summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Include/internal
diff options
context:
space:
mode:
authorshadchin <[email protected]>2026-02-03 21:59:07 +0300
committershadchin <[email protected]>2026-02-03 22:28:51 +0300
commitbce46f28de392862d5c6c3b185d844ee7c623be3 (patch)
tree424878b5b90144f98970ce4a2745990c77330ad2 /contrib/tools/python3/Include/internal
parent0e0ee9fa48ce9411b4038aa769493d22ff6c10a2 (diff)
Import Python 3.13.11
commit_hash:bbb53cefb159aa3e7afaa475fd19d5a03b66945f
Diffstat (limited to 'contrib/tools/python3/Include/internal')
-rw-r--r--contrib/tools/python3/Include/internal/mimalloc/mimalloc.h565
-rw-r--r--contrib/tools/python3/Include/internal/mimalloc/mimalloc/atomic.h392
-rw-r--r--contrib/tools/python3/Include/internal/mimalloc/mimalloc/internal.h969
-rw-r--r--contrib/tools/python3/Include/internal/mimalloc/mimalloc/prim.h329
-rw-r--r--contrib/tools/python3/Include/internal/mimalloc/mimalloc/track.h147
-rw-r--r--contrib/tools/python3/Include/internal/mimalloc/mimalloc/types.h721
-rw-r--r--contrib/tools/python3/Include/internal/pycore_abstract.h36
-rw-r--r--contrib/tools/python3/Include/internal/pycore_ast.h22
-rw-r--r--contrib/tools/python3/Include/internal/pycore_ast_state.h9
-rw-r--r--contrib/tools/python3/Include/internal/pycore_atexit.h14
-rw-r--r--contrib/tools/python3/Include/internal/pycore_atomic.h557
-rw-r--r--contrib/tools/python3/Include/internal/pycore_atomic_funcs.h94
-rw-r--r--contrib/tools/python3/Include/internal/pycore_backoff.h145
-rw-r--r--contrib/tools/python3/Include/internal/pycore_bitutils.h4
-rw-r--r--contrib/tools/python3/Include/internal/pycore_blocks_output_buffer.h6
-rw-r--r--contrib/tools/python3/Include/internal/pycore_brc.h74
-rw-r--r--contrib/tools/python3/Include/internal/pycore_bytes_methods.h23
-rw-r--r--contrib/tools/python3/Include/internal/pycore_bytesobject.h135
-rw-r--r--contrib/tools/python3/Include/internal/pycore_call.h102
-rw-r--r--contrib/tools/python3/Include/internal/pycore_capsule.h17
-rw-r--r--contrib/tools/python3/Include/internal/pycore_cell.h48
-rw-r--r--contrib/tools/python3/Include/internal/pycore_ceval.h175
-rw-r--r--contrib/tools/python3/Include/internal/pycore_ceval_state.h87
-rw-r--r--contrib/tools/python3/Include/internal/pycore_code.h245
-rw-r--r--contrib/tools/python3/Include/internal/pycore_codecs.h86
-rw-r--r--contrib/tools/python3/Include/internal/pycore_compile.h66
-rw-r--r--contrib/tools/python3/Include/internal/pycore_complexobject.h25
-rw-r--r--contrib/tools/python3/Include/internal/pycore_condvar.h22
-rw-r--r--contrib/tools/python3/Include/internal/pycore_context.h28
-rw-r--r--contrib/tools/python3/Include/internal/pycore_critical_section.h233
-rw-r--r--contrib/tools/python3/Include/internal/pycore_crossinterp.h340
-rw-r--r--contrib/tools/python3/Include/internal/pycore_descrobject.h2
-rw-r--r--contrib/tools/python3/Include/internal/pycore_dict.h187
-rw-r--r--contrib/tools/python3/Include/internal/pycore_dict_state.h20
-rw-r--r--contrib/tools/python3/Include/internal/pycore_dtoa.h22
-rw-r--r--contrib/tools/python3/Include/internal/pycore_emscripten_signal.h5
-rw-r--r--contrib/tools/python3/Include/internal/pycore_emscripten_trampoline.h81
-rw-r--r--contrib/tools/python3/Include/internal/pycore_exceptions.h3
-rw-r--r--contrib/tools/python3/Include/internal/pycore_faulthandler.h2
-rw-r--r--contrib/tools/python3/Include/internal/pycore_fileutils.h97
-rw-r--r--contrib/tools/python3/Include/internal/pycore_fileutils_windows.h2
-rw-r--r--contrib/tools/python3/Include/internal/pycore_floatobject.h33
-rw-r--r--contrib/tools/python3/Include/internal/pycore_flowgraph.h110
-rw-r--r--contrib/tools/python3/Include/internal/pycore_frame.h157
-rw-r--r--contrib/tools/python3/Include/internal/pycore_freelist.h153
-rw-r--r--contrib/tools/python3/Include/internal/pycore_function.h29
-rw-r--r--contrib/tools/python3/Include/internal/pycore_gc.h200
-rw-r--r--contrib/tools/python3/Include/internal/pycore_genobject.h41
-rw-r--r--contrib/tools/python3/Include/internal/pycore_gil.h24
-rw-r--r--contrib/tools/python3/Include/internal/pycore_global_objects.h8
-rw-r--r--contrib/tools/python3/Include/internal/pycore_global_objects_fini_generated.h49
-rw-r--r--contrib/tools/python3/Include/internal/pycore_global_strings.h49
-rw-r--r--contrib/tools/python3/Include/internal/pycore_hashtable.h9
-rw-r--r--contrib/tools/python3/Include/internal/pycore_identifier.h20
-rw-r--r--contrib/tools/python3/Include/internal/pycore_import.h80
-rw-r--r--contrib/tools/python3/Include/internal/pycore_importdl.h139
-rw-r--r--contrib/tools/python3/Include/internal/pycore_initconfig.h55
-rw-r--r--contrib/tools/python3/Include/internal/pycore_instruction_sequence.h73
-rw-r--r--contrib/tools/python3/Include/internal/pycore_instruments.h43
-rw-r--r--contrib/tools/python3/Include/internal/pycore_interp.h280
-rw-r--r--contrib/tools/python3/Include/internal/pycore_intrinsics.h31
-rw-r--r--contrib/tools/python3/Include/internal/pycore_jit.h25
-rw-r--r--contrib/tools/python3/Include/internal/pycore_list.h39
-rw-r--r--contrib/tools/python3/Include/internal/pycore_llist.h106
-rw-r--r--contrib/tools/python3/Include/internal/pycore_lock.h241
-rw-r--r--contrib/tools/python3/Include/internal/pycore_long.h84
-rw-r--r--contrib/tools/python3/Include/internal/pycore_memoryobject.h2
-rw-r--r--contrib/tools/python3/Include/internal/pycore_mimalloc.h69
-rw-r--r--contrib/tools/python3/Include/internal/pycore_modsupport.h107
-rw-r--r--contrib/tools/python3/Include/internal/pycore_moduleobject.h13
-rw-r--r--contrib/tools/python3/Include/internal/pycore_namespace.h5
-rw-r--r--contrib/tools/python3/Include/internal/pycore_object.h576
-rw-r--r--contrib/tools/python3/Include/internal/pycore_object_alloc.h71
-rw-r--r--contrib/tools/python3/Include/internal/pycore_object_stack.h97
-rw-r--r--contrib/tools/python3/Include/internal/pycore_object_state.h21
-rw-r--r--contrib/tools/python3/Include/internal/pycore_obmalloc.h4
-rw-r--r--contrib/tools/python3/Include/internal/pycore_obmalloc_init.h7
-rw-r--r--contrib/tools/python3/Include/internal/pycore_opcode.h587
-rw-r--r--contrib/tools/python3/Include/internal/pycore_opcode_metadata.h1922
-rw-r--r--contrib/tools/python3/Include/internal/pycore_opcode_utils.h51
-rw-r--r--contrib/tools/python3/Include/internal/pycore_optimizer.h272
-rw-r--r--contrib/tools/python3/Include/internal/pycore_parking_lot.h97
-rw-r--r--contrib/tools/python3/Include/internal/pycore_parser.h31
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pathconfig.h2
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pyarena.h84
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pyatomic_ft_wrappers.h165
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pybuffer.h21
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pyerrors.h101
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pyhash.h77
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pylifecycle.h71
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pymem.h85
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pymem_init.h26
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pystate.h159
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pystats.h21
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pythonrun.h39
-rw-r--r--contrib/tools/python3/Include/internal/pycore_pythread.h139
-rw-r--r--contrib/tools/python3/Include/internal/pycore_qsbr.h173
-rw-r--r--contrib/tools/python3/Include/internal/pycore_runtime.h245
-rw-r--r--contrib/tools/python3/Include/internal/pycore_runtime_init.h183
-rw-r--r--contrib/tools/python3/Include/internal/pycore_runtime_init_generated.h52
-rw-r--r--contrib/tools/python3/Include/internal/pycore_semaphore.h67
-rw-r--r--contrib/tools/python3/Include/internal/pycore_setobject.h39
-rw-r--r--contrib/tools/python3/Include/internal/pycore_signal.h30
-rw-r--r--contrib/tools/python3/Include/internal/pycore_sliceobject.h4
-rw-r--r--contrib/tools/python3/Include/internal/pycore_stackref.h195
-rw-r--r--contrib/tools/python3/Include/internal/pycore_strhex.h7
-rw-r--r--contrib/tools/python3/Include/internal/pycore_structseq.h3
-rw-r--r--contrib/tools/python3/Include/internal/pycore_symtable.h64
-rw-r--r--contrib/tools/python3/Include/internal/pycore_sysmodule.h12
-rw-r--r--contrib/tools/python3/Include/internal/pycore_time.h328
-rw-r--r--contrib/tools/python3/Include/internal/pycore_token.h26
-rw-r--r--contrib/tools/python3/Include/internal/pycore_traceback.h27
-rw-r--r--contrib/tools/python3/Include/internal/pycore_tracemalloc.h47
-rw-r--r--contrib/tools/python3/Include/internal/pycore_tstate.h46
-rw-r--r--contrib/tools/python3/Include/internal/pycore_tuple.h50
-rw-r--r--contrib/tools/python3/Include/internal/pycore_typeobject.h144
-rw-r--r--contrib/tools/python3/Include/internal/pycore_typevarobject.h3
-rw-r--r--contrib/tools/python3/Include/internal/pycore_ucnhash.h2
-rw-r--r--contrib/tools/python3/Include/internal/pycore_unicodeobject.h285
-rw-r--r--contrib/tools/python3/Include/internal/pycore_unicodeobject_generated.h188
-rw-r--r--contrib/tools/python3/Include/internal/pycore_unionobject.h6
-rw-r--r--contrib/tools/python3/Include/internal/pycore_uop_ids.h295
-rw-r--r--contrib/tools/python3/Include/internal/pycore_uop_metadata.h1010
-rw-r--r--contrib/tools/python3/Include/internal/pycore_warnings.h4
-rw-r--r--contrib/tools/python3/Include/internal/pycore_weakref.h133
125 files changed, 14321 insertions, 2484 deletions
diff --git a/contrib/tools/python3/Include/internal/mimalloc/mimalloc.h b/contrib/tools/python3/Include/internal/mimalloc/mimalloc.h
new file mode 100644
index 00000000000..821129e7690
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/mimalloc/mimalloc.h
@@ -0,0 +1,565 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2023, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#pragma once
+#ifndef MIMALLOC_H
+#define MIMALLOC_H
+
+#define MI_MALLOC_VERSION 212 // major + 2 digits minor
+
+// ------------------------------------------------------
+// Compiler specific attributes
+// ------------------------------------------------------
+
+#ifdef __cplusplus
+ #if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11
+ #define mi_attr_noexcept noexcept
+ #else
+ #define mi_attr_noexcept throw()
+ #endif
+#else
+ #define mi_attr_noexcept
+#endif
+
+#if defined(__cplusplus) && (__cplusplus >= 201703)
+ #define mi_decl_nodiscard [[nodiscard]]
+#elif (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) // includes clang, icc, and clang-cl
+ #define mi_decl_nodiscard __attribute__((warn_unused_result))
+#elif defined(_HAS_NODISCARD)
+ #define mi_decl_nodiscard _NODISCARD
+#elif (_MSC_VER >= 1700)
+ #define mi_decl_nodiscard _Check_return_
+#else
+ #define mi_decl_nodiscard
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+ #if !defined(MI_SHARED_LIB)
+ #define mi_decl_export
+ #elif defined(MI_SHARED_LIB_EXPORT)
+ #define mi_decl_export __declspec(dllexport)
+ #else
+ #define mi_decl_export __declspec(dllimport)
+ #endif
+ #if defined(__MINGW32__)
+ #define mi_decl_restrict
+ #define mi_attr_malloc __attribute__((malloc))
+ #else
+ #if (_MSC_VER >= 1900) && !defined(__EDG__)
+ #define mi_decl_restrict __declspec(allocator) __declspec(restrict)
+ #else
+ #define mi_decl_restrict __declspec(restrict)
+ #endif
+ #define mi_attr_malloc
+ #endif
+ #define mi_cdecl __cdecl
+ #define mi_attr_alloc_size(s)
+ #define mi_attr_alloc_size2(s1,s2)
+ #define mi_attr_alloc_align(p)
+#elif defined(__GNUC__) // includes clang and icc
+ #if defined(MI_SHARED_LIB) && defined(MI_SHARED_LIB_EXPORT)
+ #define mi_decl_export __attribute__((visibility("default")))
+ #else
+ #define mi_decl_export
+ #endif
+ #define mi_cdecl // leads to warnings... __attribute__((cdecl))
+ #define mi_decl_restrict
+ #define mi_attr_malloc __attribute__((malloc))
+ #if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5)
+ #define mi_attr_alloc_size(s)
+ #define mi_attr_alloc_size2(s1,s2)
+ #define mi_attr_alloc_align(p)
+ #elif defined(__INTEL_COMPILER)
+ #define mi_attr_alloc_size(s) __attribute__((alloc_size(s)))
+ #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2)))
+ #define mi_attr_alloc_align(p)
+ #else
+ #define mi_attr_alloc_size(s) __attribute__((alloc_size(s)))
+ #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2)))
+ #define mi_attr_alloc_align(p) __attribute__((alloc_align(p)))
+ #endif
+#else
+ #define mi_cdecl
+ #define mi_decl_export
+ #define mi_decl_restrict
+ #define mi_attr_malloc
+ #define mi_attr_alloc_size(s)
+ #define mi_attr_alloc_size2(s1,s2)
+ #define mi_attr_alloc_align(p)
+#endif
+
+// ------------------------------------------------------
+// Includes
+// ------------------------------------------------------
+
+#include <stddef.h> // size_t
+#include <stdbool.h> // bool
+#include <stdint.h> // INTPTR_MAX
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ------------------------------------------------------
+// Standard malloc interface
+// ------------------------------------------------------
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);
+mi_decl_nodiscard mi_decl_export void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2);
+mi_decl_export void* mi_expand(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2);
+
+mi_decl_export void mi_free(void* p) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept mi_attr_malloc;
+mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept mi_attr_malloc;
+mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc;
+
+// ------------------------------------------------------
+// Extended functionality
+// ------------------------------------------------------
+#define MI_SMALL_WSIZE_MAX (128)
+#define MI_SMALL_SIZE_MAX (MI_SMALL_WSIZE_MAX*sizeof(void*))
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);
+mi_decl_nodiscard mi_decl_export void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3);
+mi_decl_nodiscard mi_decl_export void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2);
+
+mi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept;
+
+
+// ------------------------------------------------------
+// Internals
+// ------------------------------------------------------
+
+typedef void (mi_cdecl mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg);
+mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg) mi_attr_noexcept;
+
+typedef void (mi_cdecl mi_output_fun)(const char* msg, void* arg);
+mi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept;
+
+typedef void (mi_cdecl mi_error_fun)(int err, void* arg);
+mi_decl_export void mi_register_error(mi_error_fun* fun, void* arg);
+
+mi_decl_export void mi_collect(bool force) mi_attr_noexcept;
+mi_decl_export int mi_version(void) mi_attr_noexcept;
+mi_decl_export void mi_stats_reset(void) mi_attr_noexcept;
+mi_decl_export void mi_stats_merge(void) mi_attr_noexcept;
+mi_decl_export void mi_stats_print(void* out) mi_attr_noexcept; // backward compatibility: `out` is ignored and should be NULL
+mi_decl_export void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;
+
+mi_decl_export void mi_process_init(void) mi_attr_noexcept;
+mi_decl_export void mi_thread_init(void) mi_attr_noexcept;
+mi_decl_export void mi_thread_done(void) mi_attr_noexcept;
+mi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept;
+
+mi_decl_export void mi_process_info(size_t* elapsed_msecs, size_t* user_msecs, size_t* system_msecs,
+ size_t* current_rss, size_t* peak_rss,
+ size_t* current_commit, size_t* peak_commit, size_t* page_faults) mi_attr_noexcept;
+
+// -------------------------------------------------------------------------------------
+// Aligned allocation
+// Note that `alignment` always follows `size` for consistency with unaligned
+// allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`.
+// -------------------------------------------------------------------------------------
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2) mi_attr_alloc_align(3);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2);
+mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3);
+mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2);
+
+
+// -------------------------------------------------------------------------------------
+// Heaps: first-class, but can only allocate from the same thread that created it.
+// -------------------------------------------------------------------------------------
+
+struct mi_heap_s;
+typedef struct mi_heap_s mi_heap_t;
+
+mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void);
+mi_decl_export void mi_heap_delete(mi_heap_t* heap);
+mi_decl_export void mi_heap_destroy(mi_heap_t* heap);
+mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap);
+mi_decl_export mi_heap_t* mi_heap_get_default(void);
+mi_decl_export mi_heap_t* mi_heap_get_backing(void);
+mi_decl_export void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept;
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
+
+mi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3);
+mi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4);
+mi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3);
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept mi_attr_malloc;
+mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept mi_attr_malloc;
+mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc;
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3);
+mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4);
+mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3);
+
+
+// --------------------------------------------------------------------------------
+// Zero initialized re-allocation.
+// Only valid on memory that was originally allocated with zero initialization too.
+// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc.
+// see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992>
+// --------------------------------------------------------------------------------
+
+mi_decl_nodiscard mi_decl_export void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export void* mi_recalloc(void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3);
+
+mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3);
+mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(2,3) mi_attr_alloc_align(4);
+mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(2,3);
+
+mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3);
+mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4);
+
+mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4);
+mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3);
+mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(3,4) mi_attr_alloc_align(5);
+mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(3,4);
+
+
+// ------------------------------------------------------
+// Analysis
+// ------------------------------------------------------
+
+mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p);
+mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p);
+mi_decl_export bool mi_check_owned(const void* p);
+
+// An area of heap space contains blocks of a single size.
+typedef struct mi_heap_area_s {
+ void* blocks; // start of the area containing heap blocks
+ size_t reserved; // bytes reserved for this area (virtual)
+ size_t committed; // current available bytes for this area
+ size_t used; // number of allocated blocks
+ size_t block_size; // size in bytes of each block
+ size_t full_block_size; // size in bytes of a full block including padding and metadata.
+} mi_heap_area_t;
+
+typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg);
+
+mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg);
+
+// Experimental
+mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export bool mi_is_redirected(void) mi_attr_noexcept;
+
+mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept;
+mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept;
+
+mi_decl_export int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept;
+mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept;
+
+mi_decl_export void mi_debug_show_arenas(void) mi_attr_noexcept;
+
+// Experimental: heaps associated with specific memory arena's
+typedef int mi_arena_id_t;
+mi_decl_export void* mi_arena_area(mi_arena_id_t arena_id, size_t* size);
+mi_decl_export int mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_msecs, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;
+mi_decl_export int mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;
+mi_decl_export bool mi_manage_os_memory_ex(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node, bool exclusive, mi_arena_id_t* arena_id) mi_attr_noexcept;
+
+#if MI_MALLOC_VERSION >= 182
+// Create a heap that only allocates in the specified arena
+mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new_in_arena(mi_arena_id_t arena_id);
+#endif
+
+// deprecated
+mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept;
+
+
+// ------------------------------------------------------
+// Convenience
+// ------------------------------------------------------
+
+#define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp)))
+#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp)))
+#define mi_calloc_tp(tp,n) ((tp*)mi_calloc(n,sizeof(tp)))
+#define mi_mallocn_tp(tp,n) ((tp*)mi_mallocn(n,sizeof(tp)))
+#define mi_reallocn_tp(p,tp,n) ((tp*)mi_reallocn(p,n,sizeof(tp)))
+#define mi_recalloc_tp(p,tp,n) ((tp*)mi_recalloc(p,n,sizeof(tp)))
+
+#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp)))
+#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp)))
+#define mi_heap_calloc_tp(hp,tp,n) ((tp*)mi_heap_calloc(hp,n,sizeof(tp)))
+#define mi_heap_mallocn_tp(hp,tp,n) ((tp*)mi_heap_mallocn(hp,n,sizeof(tp)))
+#define mi_heap_reallocn_tp(hp,p,tp,n) ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp)))
+#define mi_heap_recalloc_tp(hp,p,tp,n) ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp)))
+
+
+// ------------------------------------------------------
+// Options
+// ------------------------------------------------------
+
+typedef enum mi_option_e {
+ // stable options
+ mi_option_show_errors, // print error messages
+ mi_option_show_stats, // print statistics on termination
+ mi_option_verbose, // print verbose messages
+ // the following options are experimental (see src/options.h)
+ mi_option_eager_commit, // eager commit segments? (after `eager_commit_delay` segments) (=1)
+ mi_option_arena_eager_commit, // eager commit arenas? Use 2 to enable just on overcommit systems (=2)
+ mi_option_purge_decommits, // should a memory purge decommit (or only reset) (=1)
+ mi_option_allow_large_os_pages, // allow large (2MiB) OS pages, implies eager commit
+ mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB/page) at startup
+ mi_option_reserve_huge_os_pages_at, // reserve huge OS pages at a specific NUMA node
+ mi_option_reserve_os_memory, // reserve specified amount of OS memory in an arena at startup
+ mi_option_deprecated_segment_cache,
+ mi_option_deprecated_page_reset,
+ mi_option_abandoned_page_purge, // immediately purge delayed purges on thread termination
+ mi_option_deprecated_segment_reset,
+ mi_option_eager_commit_delay,
+ mi_option_purge_delay, // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all.
+ mi_option_use_numa_nodes, // 0 = use all available numa nodes, otherwise use at most N nodes.
+ mi_option_limit_os_alloc, // 1 = do not use OS memory for allocation (but only programmatically reserved arenas)
+ mi_option_os_tag, // tag used for OS logging (macOS only for now)
+ mi_option_max_errors, // issue at most N error messages
+ mi_option_max_warnings, // issue at most N warning messages
+ mi_option_max_segment_reclaim,
+ mi_option_destroy_on_exit, // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe.
+ mi_option_arena_reserve, // initial memory size in KiB for arena reservation (1GiB on 64-bit)
+ mi_option_arena_purge_mult,
+ mi_option_purge_extend_delay,
+ _mi_option_last,
+ // legacy option names
+ mi_option_large_os_pages = mi_option_allow_large_os_pages,
+ mi_option_eager_region_commit = mi_option_arena_eager_commit,
+ mi_option_reset_decommits = mi_option_purge_decommits,
+ mi_option_reset_delay = mi_option_purge_delay,
+ mi_option_abandoned_page_reset = mi_option_abandoned_page_purge
+} mi_option_t;
+
+
+mi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option);
+mi_decl_export void mi_option_enable(mi_option_t option);
+mi_decl_export void mi_option_disable(mi_option_t option);
+mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable);
+mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable);
+
+mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option);
+mi_decl_nodiscard mi_decl_export long mi_option_get_clamp(mi_option_t option, long min, long max);
+mi_decl_nodiscard mi_decl_export size_t mi_option_get_size(mi_option_t option);
+mi_decl_export void mi_option_set(mi_option_t option, long value);
+mi_decl_export void mi_option_set_default(mi_option_t option, long value);
+
+
+// -------------------------------------------------------------------------------------------------------
+// "mi" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions.
+// (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.)
+// note: we use `mi_cfree` as "checked free" and it checks if the pointer is in our heap before free-ing.
+// -------------------------------------------------------------------------------------------------------
+
+mi_decl_export void mi_cfree(void* p) mi_attr_noexcept;
+mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export size_t mi_malloc_good_size(size_t size) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept;
+
+mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1);
+
+mi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3);
+mi_decl_nodiscard mi_decl_export int mi_reallocarr(void* p, size_t count, size_t size) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept;
+mi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept;
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept mi_attr_malloc;
+mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept mi_attr_malloc;
+mi_decl_export int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept;
+mi_decl_export int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept;
+
+mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept;
+mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept;
+mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept;
+
+// The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`.
+// (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception).
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new(size_t size) mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_n(size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(1, 2);
+mi_decl_nodiscard mi_decl_export void* mi_new_realloc(void* p, size_t newsize) mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export void* mi_new_reallocn(void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3);
+
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new(mi_heap_t* heap, size_t size) mi_attr_malloc mi_attr_alloc_size(2);
+mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_alloc_new_n(mi_heap_t* heap, size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(2, 3);
+
+#ifdef __cplusplus
+}
+#endif
+
+// ---------------------------------------------------------------------------------------------
+// Implement the C++ std::allocator interface for use in STL containers.
+// (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally)
+// ---------------------------------------------------------------------------------------------
+#ifdef __cplusplus
+
+#include <cstddef> // std::size_t
+#include <cstdint> // PTRDIFF_MAX
+#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11
+#include <type_traits> // std::true_type
+#include <utility> // std::forward
+#endif
+
+template<class T> struct _mi_stl_allocator_common {
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef value_type& reference;
+ typedef value_type const& const_reference;
+ typedef value_type* pointer;
+ typedef value_type const* const_pointer;
+
+ #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11
+ using propagate_on_container_copy_assignment = std::true_type;
+ using propagate_on_container_move_assignment = std::true_type;
+ using propagate_on_container_swap = std::true_type;
+ template <class U, class ...Args> void construct(U* p, Args&& ...args) { ::new(p) U(std::forward<Args>(args)...); }
+ template <class U> void destroy(U* p) mi_attr_noexcept { p->~U(); }
+ #else
+ void construct(pointer p, value_type const& val) { ::new(p) value_type(val); }
+ void destroy(pointer p) { p->~value_type(); }
+ #endif
+
+ size_type max_size() const mi_attr_noexcept { return (PTRDIFF_MAX/sizeof(value_type)); }
+ pointer address(reference x) const { return &x; }
+ const_pointer address(const_reference x) const { return &x; }
+};
+
+template<class T> struct mi_stl_allocator : public _mi_stl_allocator_common<T> {
+ using typename _mi_stl_allocator_common<T>::size_type;
+ using typename _mi_stl_allocator_common<T>::value_type;
+ using typename _mi_stl_allocator_common<T>::pointer;
+ template <class U> struct rebind { typedef mi_stl_allocator<U> other; };
+
+ mi_stl_allocator() mi_attr_noexcept = default;
+ mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept = default;
+ template<class U> mi_stl_allocator(const mi_stl_allocator<U>&) mi_attr_noexcept { }
+ mi_stl_allocator select_on_container_copy_construction() const { return *this; }
+ void deallocate(T* p, size_type) { mi_free(p); }
+
+ #if (__cplusplus >= 201703L) // C++17
+ mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_new_n(count, sizeof(T))); }
+ mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); }
+ #else
+ mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_new_n(count, sizeof(value_type))); }
+ #endif
+
+ #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11
+ using is_always_equal = std::true_type;
+ #endif
+};
+
+template<class T1,class T2> bool operator==(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return true; }
+template<class T1,class T2> bool operator!=(const mi_stl_allocator<T1>& , const mi_stl_allocator<T2>& ) mi_attr_noexcept { return false; }
+
+
+#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900) // C++11
+#define MI_HAS_HEAP_STL_ALLOCATOR 1
+
+#include <memory> // std::shared_ptr
+
+// Common base class for STL allocators in a specific heap
+template<class T, bool _mi_destroy> struct _mi_heap_stl_allocator_common : public _mi_stl_allocator_common<T> {
+ using typename _mi_stl_allocator_common<T>::size_type;
+ using typename _mi_stl_allocator_common<T>::value_type;
+ using typename _mi_stl_allocator_common<T>::pointer;
+
+ _mi_heap_stl_allocator_common(mi_heap_t* hp) : heap(hp) { } /* will not delete nor destroy the passed in heap */
+
+ #if (__cplusplus >= 201703L) // C++17
+ mi_decl_nodiscard T* allocate(size_type count) { return static_cast<T*>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(T))); }
+ mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); }
+ #else
+ mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast<pointer>(mi_heap_alloc_new_n(this->heap.get(), count, sizeof(value_type))); }
+ #endif
+
+ #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11
+ using is_always_equal = std::false_type;
+ #endif
+
+ void collect(bool force) { mi_heap_collect(this->heap.get(), force); }
+ template<class U> bool is_equal(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) const { return (this->heap == x.heap); }
+
+protected:
+ std::shared_ptr<mi_heap_t> heap;
+ template<class U, bool D> friend struct _mi_heap_stl_allocator_common;
+
+ _mi_heap_stl_allocator_common() {
+ mi_heap_t* hp = mi_heap_new();
+ this->heap.reset(hp, (_mi_destroy ? &heap_destroy : &heap_delete)); /* calls heap_delete/destroy when the refcount drops to zero */
+ }
+ _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common& x) mi_attr_noexcept : heap(x.heap) { }
+ template<class U> _mi_heap_stl_allocator_common(const _mi_heap_stl_allocator_common<U, _mi_destroy>& x) mi_attr_noexcept : heap(x.heap) { }
+
+private:
+ static void heap_delete(mi_heap_t* hp) { if (hp != NULL) { mi_heap_delete(hp); } }
+ static void heap_destroy(mi_heap_t* hp) { if (hp != NULL) { mi_heap_destroy(hp); } }
+};
+
+// STL allocator allocation in a specific heap
+template<class T> struct mi_heap_stl_allocator : public _mi_heap_stl_allocator_common<T, false> {
+ using typename _mi_heap_stl_allocator_common<T, false>::size_type;
+ mi_heap_stl_allocator() : _mi_heap_stl_allocator_common<T, false>() { } // creates fresh heap that is deleted when the destructor is called
+ mi_heap_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, false>(hp) { } // no delete nor destroy on the passed in heap
+ template<class U> mi_heap_stl_allocator(const mi_heap_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, false>(x) { }
+
+ mi_heap_stl_allocator select_on_container_copy_construction() const { return *this; }
+ void deallocate(T* p, size_type) { mi_free(p); }
+ template<class U> struct rebind { typedef mi_heap_stl_allocator<U> other; };
+};
+
+template<class T1, class T2> bool operator==(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); }
+template<class T1, class T2> bool operator!=(const mi_heap_stl_allocator<T1>& x, const mi_heap_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); }
+
+
+// STL allocator allocation in a specific heap, where `free` does nothing and
+// the heap is destroyed in one go on destruction -- use with care!
+template<class T> struct mi_heap_destroy_stl_allocator : public _mi_heap_stl_allocator_common<T, true> {
+ using typename _mi_heap_stl_allocator_common<T, true>::size_type;
+ mi_heap_destroy_stl_allocator() : _mi_heap_stl_allocator_common<T, true>() { } // creates fresh heap that is destroyed when the destructor is called
+ mi_heap_destroy_stl_allocator(mi_heap_t* hp) : _mi_heap_stl_allocator_common<T, true>(hp) { } // no delete nor destroy on the passed in heap
+ template<class U> mi_heap_destroy_stl_allocator(const mi_heap_destroy_stl_allocator<U>& x) mi_attr_noexcept : _mi_heap_stl_allocator_common<T, true>(x) { }
+
+ mi_heap_destroy_stl_allocator select_on_container_copy_construction() const { return *this; }
+ void deallocate(T*, size_type) { /* do nothing as we destroy the heap on destruct. */ }
+ template<class U> struct rebind { typedef mi_heap_destroy_stl_allocator<U> other; };
+};
+
+template<class T1, class T2> bool operator==(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (x.is_equal(y)); }
+template<class T1, class T2> bool operator!=(const mi_heap_destroy_stl_allocator<T1>& x, const mi_heap_destroy_stl_allocator<T2>& y) mi_attr_noexcept { return (!x.is_equal(y)); }
+
+#endif // C++11
+
+#endif // __cplusplus
+
+#endif
diff --git a/contrib/tools/python3/Include/internal/mimalloc/mimalloc/atomic.h b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/atomic.h
new file mode 100644
index 00000000000..77cc0a88006
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/atomic.h
@@ -0,0 +1,392 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2023 Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#pragma once
+#ifndef MIMALLOC_ATOMIC_H
+#define MIMALLOC_ATOMIC_H
+
+// --------------------------------------------------------------------------------------------
+// Atomics
+// We need to be portable between C, C++, and MSVC.
+// We base the primitives on the C/C++ atomics and create a mimimal wrapper for MSVC in C compilation mode.
+// This is why we try to use only `uintptr_t` and `<type>*` as atomic types.
+// To gain better insight in the range of used atomics, we use explicitly named memory order operations
+// instead of passing the memory order as a parameter.
+// -----------------------------------------------------------------------------------------------
+
+#if defined(__cplusplus)
+// Use C++ atomics
+#include <atomic>
+#define _Atomic(tp) std::atomic<tp>
+#define mi_atomic(name) std::atomic_##name
+#define mi_memory_order(name) std::memory_order_##name
+#if (__cplusplus >= 202002L) // c++20, see issue #571
+ #define MI_ATOMIC_VAR_INIT(x) x
+#elif !defined(ATOMIC_VAR_INIT)
+ #define MI_ATOMIC_VAR_INIT(x) x
+#else
+ #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
+#endif
+#elif defined(_MSC_VER)
+// Use MSVC C wrapper for C11 atomics
+#define _Atomic(tp) tp
+#define MI_ATOMIC_VAR_INIT(x) x
+#define mi_atomic(name) mi_atomic_##name
+#define mi_memory_order(name) mi_memory_order_##name
+#else
+// Use C11 atomics
+#include <stdatomic.h>
+#define mi_atomic(name) atomic_##name
+#define mi_memory_order(name) memory_order_##name
+#if (__STDC_VERSION__ >= 201710L) // c17, see issue #735
+ #define MI_ATOMIC_VAR_INIT(x) x
+#elif !defined(ATOMIC_VAR_INIT)
+ #define MI_ATOMIC_VAR_INIT(x) x
+#else
+ #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x)
+#endif
+#endif
+
+// Various defines for all used memory orders in mimalloc
+#define mi_atomic_cas_weak(p,expected,desired,mem_success,mem_fail) \
+ mi_atomic(compare_exchange_weak_explicit)(p,expected,desired,mem_success,mem_fail)
+
+#define mi_atomic_cas_strong(p,expected,desired,mem_success,mem_fail) \
+ mi_atomic(compare_exchange_strong_explicit)(p,expected,desired,mem_success,mem_fail)
+
+#define mi_atomic_load_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire))
+#define mi_atomic_load_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed))
+#define mi_atomic_store_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_store_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))
+#define mi_atomic_exchange_release(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_exchange_acq_rel(p,x) mi_atomic(exchange_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_cas_weak_release(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))
+#define mi_atomic_cas_weak_acq_rel(p,exp,des) mi_atomic_cas_weak(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))
+#define mi_atomic_cas_strong_release(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(release),mi_memory_order(relaxed))
+#define mi_atomic_cas_strong_acq_rel(p,exp,des) mi_atomic_cas_strong(p,exp,des,mi_memory_order(acq_rel),mi_memory_order(acquire))
+
+#define mi_atomic_add_relaxed(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(relaxed))
+#define mi_atomic_sub_relaxed(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(relaxed))
+#define mi_atomic_add_acq_rel(p,x) mi_atomic(fetch_add_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_sub_acq_rel(p,x) mi_atomic(fetch_sub_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_and_acq_rel(p,x) mi_atomic(fetch_and_explicit)(p,x,mi_memory_order(acq_rel))
+#define mi_atomic_or_acq_rel(p,x) mi_atomic(fetch_or_explicit)(p,x,mi_memory_order(acq_rel))
+
+#define mi_atomic_increment_relaxed(p) mi_atomic_add_relaxed(p,(uintptr_t)1)
+#define mi_atomic_decrement_relaxed(p) mi_atomic_sub_relaxed(p,(uintptr_t)1)
+#define mi_atomic_increment_acq_rel(p) mi_atomic_add_acq_rel(p,(uintptr_t)1)
+#define mi_atomic_decrement_acq_rel(p) mi_atomic_sub_acq_rel(p,(uintptr_t)1)
+
+static inline void mi_atomic_yield(void);
+static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add);
+static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub);
+
+
+#if defined(__cplusplus) || !defined(_MSC_VER)
+
+// In C++/C11 atomics we have polymorphic atomics so can use the typed `ptr` variants (where `tp` is the type of atomic value)
+// We use these macros so we can provide a typed wrapper in MSVC in C compilation mode as well
+#define mi_atomic_load_ptr_acquire(tp,p) mi_atomic_load_acquire(p)
+#define mi_atomic_load_ptr_relaxed(tp,p) mi_atomic_load_relaxed(p)
+
+// In C++ we need to add casts to help resolve templates if NULL is passed
+#if defined(__cplusplus)
+#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,(tp*)x)
+#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,(tp*)x)
+#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,(tp*)des)
+#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,(tp*)des)
+#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,(tp*)des)
+#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,(tp*)x)
+#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,(tp*)x)
+#else
+#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release(p,x)
+#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed(p,x)
+#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release(p,exp,des)
+#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel(p,exp,des)
+#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release(p,exp,des)
+#define mi_atomic_exchange_ptr_release(tp,p,x) mi_atomic_exchange_release(p,x)
+#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) mi_atomic_exchange_acq_rel(p,x)
+#endif
+
+// These are used by the statistics
+static inline int64_t mi_atomic_addi64_relaxed(volatile int64_t* p, int64_t add) {
+ return mi_atomic(fetch_add_explicit)((_Atomic(int64_t)*)p, add, mi_memory_order(relaxed));
+}
+static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) {
+ int64_t current = mi_atomic_load_relaxed((_Atomic(int64_t)*)p);
+ while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, &current, x)) { /* nothing */ };
+}
+
+// Used by timers
+#define mi_atomic_loadi64_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire))
+#define mi_atomic_loadi64_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed))
+#define mi_atomic_storei64_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_storei64_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed))
+
+#define mi_atomic_casi64_strong_acq_rel(p,e,d) mi_atomic_cas_strong_acq_rel(p,e,d)
+#define mi_atomic_addi64_acq_rel(p,i) mi_atomic_add_acq_rel(p,i)
+
+
+#elif defined(_MSC_VER)
+
+// MSVC C compilation wrapper that uses Interlocked operations to model C11 atomics.
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <intrin.h>
+#ifdef _WIN64
+typedef LONG64 msc_intptr_t;
+#define MI_64(f) f##64
+#else
+typedef LONG msc_intptr_t;
+#define MI_64(f) f
+#endif
+
+typedef enum mi_memory_order_e {
+ mi_memory_order_relaxed,
+ mi_memory_order_consume,
+ mi_memory_order_acquire,
+ mi_memory_order_release,
+ mi_memory_order_acq_rel,
+ mi_memory_order_seq_cst
+} mi_memory_order;
+
+static inline uintptr_t mi_atomic_fetch_add_explicit(_Atomic(uintptr_t)*p, uintptr_t add, mi_memory_order mo) {
+ (void)(mo);
+ return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add);
+}
+static inline uintptr_t mi_atomic_fetch_sub_explicit(_Atomic(uintptr_t)*p, uintptr_t sub, mi_memory_order mo) {
+ (void)(mo);
+ return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, -((msc_intptr_t)sub));
+}
+static inline uintptr_t mi_atomic_fetch_and_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {
+ (void)(mo);
+ return (uintptr_t)MI_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x);
+}
+static inline uintptr_t mi_atomic_fetch_or_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {
+ (void)(mo);
+ return (uintptr_t)MI_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x);
+}
+static inline bool mi_atomic_compare_exchange_strong_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {
+ (void)(mo1); (void)(mo2);
+ uintptr_t read = (uintptr_t)MI_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)(*expected));
+ if (read == *expected) {
+ return true;
+ }
+ else {
+ *expected = read;
+ return false;
+ }
+}
+static inline bool mi_atomic_compare_exchange_weak_explicit(_Atomic(uintptr_t)*p, uintptr_t* expected, uintptr_t desired, mi_memory_order mo1, mi_memory_order mo2) {
+ return mi_atomic_compare_exchange_strong_explicit(p, expected, desired, mo1, mo2);
+}
+static inline uintptr_t mi_atomic_exchange_explicit(_Atomic(uintptr_t)*p, uintptr_t exchange, mi_memory_order mo) {
+ (void)(mo);
+ return (uintptr_t)MI_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange);
+}
+static inline void mi_atomic_thread_fence(mi_memory_order mo) {
+ (void)(mo);
+ _Atomic(uintptr_t) x = 0;
+ mi_atomic_exchange_explicit(&x, 1, mo);
+}
+static inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_memory_order mo) {
+ (void)(mo);
+#if defined(_M_IX86) || defined(_M_X64)
+ return *p;
+#else
+ uintptr_t x = *p;
+ if (mo > mi_memory_order_relaxed) {
+ while (!mi_atomic_compare_exchange_weak_explicit((_Atomic(uintptr_t)*)p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ };
+ }
+ return x;
+#endif
+}
+static inline void mi_atomic_store_explicit(_Atomic(uintptr_t)*p, uintptr_t x, mi_memory_order mo) {
+ (void)(mo);
+#if defined(_M_IX86) || defined(_M_X64)
+ *p = x;
+#else
+ mi_atomic_exchange_explicit(p, x, mo);
+#endif
+}
+static inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)*p, mi_memory_order mo) {
+ (void)(mo);
+#if defined(_M_X64)
+ return *p;
+#else
+ int64_t old = *p;
+ int64_t x = old;
+ while ((old = InterlockedCompareExchange64(p, x, old)) != x) {
+ x = old;
+ }
+ return x;
+#endif
+}
+static inline void mi_atomic_storei64_explicit(_Atomic(int64_t)*p, int64_t x, mi_memory_order mo) {
+ (void)(mo);
+#if defined(x_M_IX86) || defined(_M_X64)
+ *p = x;
+#else
+ InterlockedExchange64(p, x);
+#endif
+}
+
+// These are used by the statistics
+static inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)*p, int64_t add) {
+#ifdef _WIN64
+ return (int64_t)mi_atomic_addi((int64_t*)p, add);
+#else
+ int64_t current;
+ int64_t sum;
+ do {
+ current = *p;
+ sum = current + add;
+ } while (_InterlockedCompareExchange64(p, sum, current) != current);
+ return current;
+#endif
+}
+static inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t x) {
+ int64_t current;
+ do {
+ current = *p;
+ } while (current < x && _InterlockedCompareExchange64(p, x, current) != current);
+}
+
+static inline void mi_atomic_addi64_acq_rel(volatile _Atomic(int64_t*)p, int64_t i) {
+ mi_atomic_addi64_relaxed(p, i);
+}
+
+static inline bool mi_atomic_casi64_strong_acq_rel(volatile _Atomic(int64_t*)p, int64_t* exp, int64_t des) {
+ int64_t read = _InterlockedCompareExchange64(p, des, *exp);
+ if (read == *exp) {
+ return true;
+ }
+ else {
+ *exp = read;
+ return false;
+ }
+}
+
+// The pointer macros cast to `uintptr_t`.
+#define mi_atomic_load_ptr_acquire(tp,p) (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p))
+#define mi_atomic_load_ptr_relaxed(tp,p) (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p))
+#define mi_atomic_store_ptr_release(tp,p,x) mi_atomic_store_release((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))
+#define mi_atomic_store_ptr_relaxed(tp,p,x) mi_atomic_store_relaxed((_Atomic(uintptr_t)*)(p),(uintptr_t)(x))
+#define mi_atomic_cas_ptr_weak_release(tp,p,exp,des) mi_atomic_cas_weak_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
+#define mi_atomic_cas_ptr_weak_acq_rel(tp,p,exp,des) mi_atomic_cas_weak_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
+#define mi_atomic_cas_ptr_strong_release(tp,p,exp,des) mi_atomic_cas_strong_release((_Atomic(uintptr_t)*)(p),(uintptr_t*)exp,(uintptr_t)des)
+#define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x)
+#define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x)
+
+#define mi_atomic_loadi64_acquire(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire))
+#define mi_atomic_loadi64_relaxed(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed))
+#define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release))
+#define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed))
+
+
+#endif
+
+
+// Atomically add a signed value; returns the previous value.
+static inline intptr_t mi_atomic_addi(_Atomic(intptr_t)*p, intptr_t add) {
+ return (intptr_t)mi_atomic_add_acq_rel((_Atomic(uintptr_t)*)p, (uintptr_t)add);
+}
+
+// Atomically subtract a signed value; returns the previous value.
+static inline intptr_t mi_atomic_subi(_Atomic(intptr_t)*p, intptr_t sub) {
+ return (intptr_t)mi_atomic_addi(p, -sub);
+}
+
+typedef _Atomic(uintptr_t) mi_atomic_once_t;
+
+// Returns true only on the first invocation
+static inline bool mi_atomic_once( mi_atomic_once_t* once ) {
+ if (mi_atomic_load_relaxed(once) != 0) return false; // quick test
+ uintptr_t expected = 0;
+ return mi_atomic_cas_strong_acq_rel(once, &expected, (uintptr_t)1); // try to set to 1
+}
+
+typedef _Atomic(uintptr_t) mi_atomic_guard_t;
+
+// Allows only one thread to execute at a time
+#define mi_atomic_guard(guard) \
+ uintptr_t _mi_guard_expected = 0; \
+ for(bool _mi_guard_once = true; \
+ _mi_guard_once && mi_atomic_cas_strong_acq_rel(guard,&_mi_guard_expected,(uintptr_t)1); \
+ (mi_atomic_store_release(guard,(uintptr_t)0), _mi_guard_once = false) )
+
+
+
+// Yield
+#if defined(__cplusplus)
+#include <thread>
+static inline void mi_atomic_yield(void) {
+ std::this_thread::yield();
+}
+#elif defined(_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+static inline void mi_atomic_yield(void) {
+ YieldProcessor();
+}
+#elif defined(__SSE2__)
+#include <emmintrin.h>
+static inline void mi_atomic_yield(void) {
+ _mm_pause();
+}
+#elif (defined(__GNUC__) || defined(__clang__)) && \
+ (defined(__x86_64__) || defined(__i386__) || \
+ defined(__aarch64__) || defined(__arm__) || \
+ defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__))
+#if defined(__x86_64__) || defined(__i386__)
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile ("pause" ::: "memory");
+}
+#elif defined(__aarch64__)
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile("wfe");
+}
+#elif defined(__arm__)
+#if __ARM_ARCH >= 7
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile("yield" ::: "memory");
+}
+#else
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile ("nop" ::: "memory");
+}
+#endif
+#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(__POWERPC__)
+#ifdef __APPLE__
+static inline void mi_atomic_yield(void) {
+ __asm__ volatile ("or r27,r27,r27" ::: "memory");
+}
+#else
+static inline void mi_atomic_yield(void) {
+ __asm__ __volatile__ ("or 27,27,27" ::: "memory");
+}
+#endif
+#endif
+#elif defined(__sun)
+// Fallback for other archs
+#error #include <synch.h>
+static inline void mi_atomic_yield(void) {
+ smt_pause();
+}
+#elif defined(__wasi__)
+#include <sched.h>
+static inline void mi_atomic_yield(void) {
+ sched_yield();
+}
+#else
+#include <unistd.h>
+static inline void mi_atomic_yield(void) {
+ sleep(0);
+}
+#endif
+
+
+#endif // __MIMALLOC_ATOMIC_H
diff --git a/contrib/tools/python3/Include/internal/mimalloc/mimalloc/internal.h b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/internal.h
new file mode 100644
index 00000000000..1c16152d914
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/internal.h
@@ -0,0 +1,969 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2023, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#pragma once
+#ifndef MIMALLOC_INTERNAL_H
+#define MIMALLOC_INTERNAL_H
+
+
+// --------------------------------------------------------------------------
+// This file contains the interal API's of mimalloc and various utility
+// functions and macros.
+// --------------------------------------------------------------------------
+
+#include "types.h"
+#include "track.h"
+
+#if (MI_DEBUG>0)
+#define mi_trace_message(...) _mi_trace_message(__VA_ARGS__)
+#else
+#define mi_trace_message(...)
+#endif
+
+#if defined(__EMSCRIPTEN__) && !defined(__wasi__)
+#define __wasi__
+#endif
+
+#if defined(__cplusplus)
+#define mi_decl_externc extern "C"
+#else
+#define mi_decl_externc
+#endif
+
+// pthreads
+#if !defined(_WIN32) && !defined(__wasi__)
+#define MI_USE_PTHREADS
+#include <pthread.h>
+#endif
+
+// "options.c"
+void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);
+void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...);
+void _mi_warning_message(const char* fmt, ...);
+void _mi_verbose_message(const char* fmt, ...);
+void _mi_trace_message(const char* fmt, ...);
+void _mi_options_init(void);
+void _mi_error_message(int err, const char* fmt, ...);
+
+// random.c
+void _mi_random_init(mi_random_ctx_t* ctx);
+void _mi_random_init_weak(mi_random_ctx_t* ctx);
+void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx);
+void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx);
+uintptr_t _mi_random_next(mi_random_ctx_t* ctx);
+uintptr_t _mi_heap_random_next(mi_heap_t* heap);
+uintptr_t _mi_os_random_weak(uintptr_t extra_seed);
+static inline uintptr_t _mi_random_shuffle(uintptr_t x);
+
+// init.c
+extern mi_decl_cache_align mi_stats_t _mi_stats_main;
+extern mi_decl_cache_align const mi_page_t _mi_page_empty;
+bool _mi_is_main_thread(void);
+size_t _mi_current_thread_count(void);
+bool _mi_preloading(void); // true while the C runtime is not initialized yet
+mi_threadid_t _mi_thread_id(void) mi_attr_noexcept;
+mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap
+void _mi_thread_done(mi_heap_t* heap);
+void _mi_thread_data_collect(void);
+void _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap);
+
+// os.c
+void _mi_os_init(void); // called from process init
+void* _mi_os_alloc(size_t size, mi_memid_t* memid, mi_stats_t* stats);
+void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* stats);
+void _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid, mi_stats_t* stats);
+
+size_t _mi_os_page_size(void);
+size_t _mi_os_good_alloc_size(size_t size);
+bool _mi_os_has_overcommit(void);
+bool _mi_os_has_virtual_reserve(void);
+
+bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats);
+bool _mi_os_reset(void* addr, size_t size, mi_stats_t* tld_stats);
+bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats);
+bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats);
+bool _mi_os_protect(void* addr, size_t size);
+bool _mi_os_unprotect(void* addr, size_t size);
+bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats);
+bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats);
+
+void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* stats);
+void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats);
+
+void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size);
+bool _mi_os_use_large_page(size_t size, size_t alignment);
+size_t _mi_os_large_page_size(void);
+
+void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid);
+
+// arena.c
+mi_arena_id_t _mi_arena_id_none(void);
+void _mi_arena_free(void* p, size_t size, size_t still_committed_size, mi_memid_t memid, mi_stats_t* stats);
+void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld);
+void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld);
+bool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id);
+bool _mi_arena_contains(const void* p);
+void _mi_arena_collect(bool force_purge, mi_stats_t* stats);
+void _mi_arena_unsafe_destroy_all(mi_stats_t* stats);
+
+// "segment-map.c"
+void _mi_segment_map_allocated_at(const mi_segment_t* segment);
+void _mi_segment_map_freed_at(const mi_segment_t* segment);
+
+// "segment.c"
+extern mi_abandoned_pool_t _mi_abandoned_default; // global abandoned pool
+mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld, mi_os_tld_t* os_tld);
+void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld);
+void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld);
+bool _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segments_tld_t* tld);
+void _mi_segment_thread_collect(mi_segments_tld_t* tld);
+bool _mi_abandoned_pool_visit_blocks(mi_abandoned_pool_t* pool, uint8_t page_tag, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);
+
+
+#if MI_HUGE_PAGE_ABANDON
+void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);
+#else
+void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);
+#endif
+
+uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); // page start for any page
+void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld);
+void _mi_abandoned_await_readers(mi_abandoned_pool_t *pool);
+void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld);
+
+// "page.c"
+void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept mi_attr_malloc;
+
+void _mi_page_retire(mi_page_t* page) mi_attr_noexcept; // free the page if there are no other pages with many free blocks
+void _mi_page_unfull(mi_page_t* page);
+void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page
+void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread...
+void _mi_heap_delayed_free_all(mi_heap_t* heap);
+bool _mi_heap_delayed_free_partial(mi_heap_t* heap);
+void _mi_heap_collect_retired(mi_heap_t* heap, bool force);
+
+void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);
+bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);
+size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append);
+void _mi_deferred_free(mi_heap_t* heap, bool force);
+
+void _mi_page_free_collect(mi_page_t* page,bool force);
+void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page); // callback from segments
+
+size_t _mi_bin_size(uint8_t bin); // for stats
+uint8_t _mi_bin(size_t size); // for stats
+
+// "heap.c"
+void _mi_heap_init_ex(mi_heap_t* heap, mi_tld_t* tld, mi_arena_id_t arena_id, bool no_reclaim, uint8_t tag);
+void _mi_heap_destroy_pages(mi_heap_t* heap);
+void _mi_heap_collect_abandon(mi_heap_t* heap);
+void _mi_heap_set_default_direct(mi_heap_t* heap);
+bool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid);
+void _mi_heap_unsafe_destroy_all(void);
+void _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page);
+bool _mi_heap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t *page, mi_block_visit_fun* visitor, void* arg);
+
+// "stats.c"
+void _mi_stats_done(mi_stats_t* stats);
+mi_msecs_t _mi_clock_now(void);
+mi_msecs_t _mi_clock_end(mi_msecs_t start);
+mi_msecs_t _mi_clock_start(void);
+
+// "alloc.c"
+void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size, bool zero) mi_attr_noexcept; // called from `_mi_malloc_generic`
+void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) mi_attr_noexcept;
+void* _mi_heap_malloc_zero_ex(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept; // called from `_mi_heap_malloc_aligned`
+void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) mi_attr_noexcept;
+mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p);
+bool _mi_free_delayed_block(mi_block_t* block);
+void _mi_free_generic(const mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept; // for runtime integration
+void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size);
+
+// option.c, c primitives
+char _mi_toupper(char c);
+int _mi_strnicmp(const char* s, const char* t, size_t n);
+void _mi_strlcpy(char* dest, const char* src, size_t dest_size);
+void _mi_strlcat(char* dest, const char* src, size_t dest_size);
+size_t _mi_strlen(const char* s);
+size_t _mi_strnlen(const char* s, size_t max_len);
+
+
+#if MI_DEBUG>1
+bool _mi_page_is_valid(mi_page_t* page);
+#endif
+
+
+// ------------------------------------------------------
+// Branches
+// ------------------------------------------------------
+
+#if defined(__GNUC__) || defined(__clang__)
+#define mi_unlikely(x) (__builtin_expect(!!(x),false))
+#define mi_likely(x) (__builtin_expect(!!(x),true))
+#elif (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
+#define mi_unlikely(x) (x) [[unlikely]]
+#define mi_likely(x) (x) [[likely]]
+#else
+#define mi_unlikely(x) (x)
+#define mi_likely(x) (x)
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+
+/* -----------------------------------------------------------
+ Error codes passed to `_mi_fatal_error`
+ All are recoverable but EFAULT is a serious error and aborts by default in secure mode.
+ For portability define undefined error codes using common Unix codes:
+ <https://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html>
+----------------------------------------------------------- */
+#include <errno.h>
+#ifndef EAGAIN // double free
+#define EAGAIN (11)
+#endif
+#ifndef ENOMEM // out of memory
+#define ENOMEM (12)
+#endif
+#ifndef EFAULT // corrupted free-list or meta-data
+#define EFAULT (14)
+#endif
+#ifndef EINVAL // trying to free an invalid pointer
+#define EINVAL (22)
+#endif
+#ifndef EOVERFLOW // count*size overflow
+#define EOVERFLOW (75)
+#endif
+
+
+/* -----------------------------------------------------------
+ Inlined definitions
+----------------------------------------------------------- */
+#define MI_UNUSED(x) (void)(x)
+#if (MI_DEBUG>0)
+#define MI_UNUSED_RELEASE(x)
+#else
+#define MI_UNUSED_RELEASE(x) MI_UNUSED(x)
+#endif
+
+#define MI_INIT4(x) x(),x(),x(),x()
+#define MI_INIT8(x) MI_INIT4(x),MI_INIT4(x)
+#define MI_INIT16(x) MI_INIT8(x),MI_INIT8(x)
+#define MI_INIT32(x) MI_INIT16(x),MI_INIT16(x)
+#define MI_INIT64(x) MI_INIT32(x),MI_INIT32(x)
+#define MI_INIT128(x) MI_INIT64(x),MI_INIT64(x)
+#define MI_INIT256(x) MI_INIT128(x),MI_INIT128(x)
+
+
+#include <string.h>
+// initialize a local variable to zero; use memset as compilers optimize constant sized memset's
+#define _mi_memzero_var(x) memset(&x,0,sizeof(x))
+
+// Is `x` a power of two? (0 is considered a power of two)
+static inline bool _mi_is_power_of_two(uintptr_t x) {
+ return ((x & (x - 1)) == 0);
+}
+
+// Is a pointer aligned?
+static inline bool _mi_is_aligned(void* p, size_t alignment) {
+ mi_assert_internal(alignment != 0);
+ return (((uintptr_t)p % alignment) == 0);
+}
+
+// Align upwards
+static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) {
+ mi_assert_internal(alignment != 0);
+ uintptr_t mask = alignment - 1;
+ if ((alignment & mask) == 0) { // power of two?
+ return ((sz + mask) & ~mask);
+ }
+ else {
+ return (((sz + mask)/alignment)*alignment);
+ }
+}
+
+// Align downwards
+static inline uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) {
+ mi_assert_internal(alignment != 0);
+ uintptr_t mask = alignment - 1;
+ if ((alignment & mask) == 0) { // power of two?
+ return (sz & ~mask);
+ }
+ else {
+ return ((sz / alignment) * alignment);
+ }
+}
+
+// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`.
+static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) {
+ mi_assert_internal(divider != 0);
+ return (divider == 0 ? size : ((size + divider - 1) / divider));
+}
+
+// Is memory zero initialized?
+static inline bool mi_mem_is_zero(const void* p, size_t size) {
+ for (size_t i = 0; i < size; i++) {
+ if (((uint8_t*)p)[i] != 0) return false;
+ }
+ return true;
+}
+
+
+// Align a byte size to a size in _machine words_,
+// i.e. byte size == `wsize*sizeof(void*)`.
+static inline size_t _mi_wsize_from_size(size_t size) {
+ mi_assert_internal(size <= SIZE_MAX - sizeof(uintptr_t));
+ return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);
+}
+
+// Overflow detecting multiply
+#if __has_builtin(__builtin_umul_overflow) || (defined(__GNUC__) && (__GNUC__ >= 5))
+#include <limits.h> // UINT_MAX, ULONG_MAX
+#if defined(_CLOCK_T) // for Illumos
+#undef _CLOCK_T
+#endif
+static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {
+ #if (SIZE_MAX == ULONG_MAX)
+ return __builtin_umull_overflow(count, size, (unsigned long *)total);
+ #elif (SIZE_MAX == UINT_MAX)
+ return __builtin_umul_overflow(count, size, (unsigned int *)total);
+ #else
+ return __builtin_umulll_overflow(count, size, (unsigned long long *)total);
+ #endif
+}
+#else /* __builtin_umul_overflow is unavailable */
+static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) {
+ #define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX)
+ *total = count * size;
+ // note: gcc/clang optimize this to directly check the overflow flag
+ return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW) && size > 0 && (SIZE_MAX / size) < count);
+}
+#endif
+
+// Safe multiply `count*size` into `total`; return `true` on overflow.
+static inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) {
+ if (count==1) { // quick check for the case where count is one (common for C++ allocators)
+ *total = size;
+ return false;
+ }
+ else if mi_unlikely(mi_mul_overflow(count, size, total)) {
+ #if MI_DEBUG > 0
+ _mi_error_message(EOVERFLOW, "allocation request is too large (%zu * %zu bytes)\n", count, size);
+ #endif
+ *total = SIZE_MAX;
+ return true;
+ }
+ else return false;
+}
+
+
+/*----------------------------------------------------------------------------------------
+ Heap functions
+------------------------------------------------------------------------------------------- */
+
+extern const mi_heap_t _mi_heap_empty; // read-only empty heap, initial value of the thread local default heap
+
+static inline bool mi_heap_is_backing(const mi_heap_t* heap) {
+ return (heap->tld->heap_backing == heap);
+}
+
+static inline bool mi_heap_is_initialized(mi_heap_t* heap) {
+ mi_assert_internal(heap != NULL);
+ return (heap != &_mi_heap_empty);
+}
+
+static inline uintptr_t _mi_ptr_cookie(const void* p) {
+ extern mi_heap_t _mi_heap_main;
+ mi_assert_internal(_mi_heap_main.cookie != 0);
+ return ((uintptr_t)p ^ _mi_heap_main.cookie);
+}
+
+/* -----------------------------------------------------------
+ Pages
+----------------------------------------------------------- */
+
+static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t size) {
+ mi_assert_internal(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE));
+ const size_t idx = _mi_wsize_from_size(size);
+ mi_assert_internal(idx < MI_PAGES_DIRECT);
+ return heap->pages_free_direct[idx];
+}
+
+// Segment that contains the pointer
+// Large aligned blocks may be aligned at N*MI_SEGMENT_SIZE (inside a huge segment > MI_SEGMENT_SIZE),
+// and we need align "down" to the segment info which is `MI_SEGMENT_SIZE` bytes before it;
+// therefore we align one byte before `p`.
+static inline mi_segment_t* _mi_ptr_segment(const void* p) {
+ mi_assert_internal(p != NULL);
+ return (mi_segment_t*)(((uintptr_t)p - 1) & ~MI_SEGMENT_MASK);
+}
+
+static inline mi_page_t* mi_slice_to_page(mi_slice_t* s) {
+ mi_assert_internal(s->slice_offset== 0 && s->slice_count > 0);
+ return (mi_page_t*)(s);
+}
+
+static inline mi_slice_t* mi_page_to_slice(mi_page_t* p) {
+ mi_assert_internal(p->slice_offset== 0 && p->slice_count > 0);
+ return (mi_slice_t*)(p);
+}
+
+// Segment belonging to a page
+static inline mi_segment_t* _mi_page_segment(const mi_page_t* page) {
+ mi_segment_t* segment = _mi_ptr_segment(page);
+ mi_assert_internal(segment == NULL || ((mi_slice_t*)page >= segment->slices && (mi_slice_t*)page < segment->slices + segment->slice_entries));
+ return segment;
+}
+
+static inline mi_slice_t* mi_slice_first(const mi_slice_t* slice) {
+ mi_slice_t* start = (mi_slice_t*)((uint8_t*)slice - slice->slice_offset);
+ mi_assert_internal(start >= _mi_ptr_segment(slice)->slices);
+ mi_assert_internal(start->slice_offset == 0);
+ mi_assert_internal(start + start->slice_count > slice);
+ return start;
+}
+
+// Get the page containing the pointer (performance critical as it is called in mi_free)
+static inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) {
+ mi_assert_internal(p > (void*)segment);
+ ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment;
+ mi_assert_internal(diff > 0 && diff <= (ptrdiff_t)MI_SEGMENT_SIZE);
+ size_t idx = (size_t)diff >> MI_SEGMENT_SLICE_SHIFT;
+ mi_assert_internal(idx <= segment->slice_entries);
+ mi_slice_t* slice0 = (mi_slice_t*)&segment->slices[idx];
+ mi_slice_t* slice = mi_slice_first(slice0); // adjust to the block that holds the page data
+ mi_assert_internal(slice->slice_offset == 0);
+ mi_assert_internal(slice >= segment->slices && slice < segment->slices + segment->slice_entries);
+ return mi_slice_to_page(slice);
+}
+
+// Quick page start for initialized pages
+static inline uint8_t* _mi_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) {
+ return _mi_segment_page_start(segment, page, page_size);
+}
+
+// Get the page containing the pointer
+static inline mi_page_t* _mi_ptr_page(void* p) {
+ return _mi_segment_page_of(_mi_ptr_segment(p), p);
+}
+
+// Get the block size of a page (special case for huge objects)
+static inline size_t mi_page_block_size(const mi_page_t* page) {
+ const size_t bsize = page->xblock_size;
+ mi_assert_internal(bsize > 0);
+ if mi_likely(bsize < MI_HUGE_BLOCK_SIZE) {
+ return bsize;
+ }
+ else {
+ size_t psize;
+ _mi_segment_page_start(_mi_page_segment(page), page, &psize);
+ return psize;
+ }
+}
+
+static inline bool mi_page_is_huge(const mi_page_t* page) {
+ return (_mi_page_segment(page)->kind == MI_SEGMENT_HUGE);
+}
+
+// Get the usable block size of a page without fixed padding.
+// This may still include internal padding due to alignment and rounding up size classes.
+static inline size_t mi_page_usable_block_size(const mi_page_t* page) {
+ return mi_page_block_size(page) - MI_PADDING_SIZE;
+}
+
+// size of a segment
+static inline size_t mi_segment_size(mi_segment_t* segment) {
+ return segment->segment_slices * MI_SEGMENT_SLICE_SIZE;
+}
+
+static inline uint8_t* mi_segment_end(mi_segment_t* segment) {
+ return (uint8_t*)segment + mi_segment_size(segment);
+}
+
+// Thread free access
+static inline mi_block_t* mi_page_thread_free(const mi_page_t* page) {
+ return (mi_block_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & ~3);
+}
+
+static inline mi_delayed_t mi_page_thread_free_flag(const mi_page_t* page) {
+ return (mi_delayed_t)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xthread_free) & 3);
+}
+
+// Heap access
+static inline mi_heap_t* mi_page_heap(const mi_page_t* page) {
+ return (mi_heap_t*)(mi_atomic_load_relaxed(&((mi_page_t*)page)->xheap));
+}
+
+static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) {
+ mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING);
+ mi_atomic_store_release(&page->xheap,(uintptr_t)heap);
+}
+
+// Thread free flag helpers
+static inline mi_block_t* mi_tf_block(mi_thread_free_t tf) {
+ return (mi_block_t*)(tf & ~0x03);
+}
+static inline mi_delayed_t mi_tf_delayed(mi_thread_free_t tf) {
+ return (mi_delayed_t)(tf & 0x03);
+}
+static inline mi_thread_free_t mi_tf_make(mi_block_t* block, mi_delayed_t delayed) {
+ return (mi_thread_free_t)((uintptr_t)block | (uintptr_t)delayed);
+}
+static inline mi_thread_free_t mi_tf_set_delayed(mi_thread_free_t tf, mi_delayed_t delayed) {
+ return mi_tf_make(mi_tf_block(tf),delayed);
+}
+static inline mi_thread_free_t mi_tf_set_block(mi_thread_free_t tf, mi_block_t* block) {
+ return mi_tf_make(block, mi_tf_delayed(tf));
+}
+
+// are all blocks in a page freed?
+// note: needs up-to-date used count, (as the `xthread_free` list may not be empty). see `_mi_page_collect_free`.
+static inline bool mi_page_all_free(const mi_page_t* page) {
+ mi_assert_internal(page != NULL);
+ return (page->used == 0);
+}
+
+// are there any available blocks?
+static inline bool mi_page_has_any_available(const mi_page_t* page) {
+ mi_assert_internal(page != NULL && page->reserved > 0);
+ return (page->used < page->reserved || (mi_page_thread_free(page) != NULL));
+}
+
+// are there immediately available blocks, i.e. blocks available on the free list.
+static inline bool mi_page_immediate_available(const mi_page_t* page) {
+ mi_assert_internal(page != NULL);
+ return (page->free != NULL);
+}
+
+// is more than 7/8th of a page in use?
+static inline bool mi_page_mostly_used(const mi_page_t* page) {
+ if (page==NULL) return true;
+ uint16_t frac = page->reserved / 8U;
+ return (page->reserved - page->used <= frac);
+}
+
+static inline mi_page_queue_t* mi_page_queue(const mi_heap_t* heap, size_t size) {
+ return &((mi_heap_t*)heap)->pages[_mi_bin(size)];
+}
+
+
+
+//-----------------------------------------------------------
+// Page flags
+//-----------------------------------------------------------
+static inline bool mi_page_is_in_full(const mi_page_t* page) {
+ return page->flags.x.in_full;
+}
+
+static inline void mi_page_set_in_full(mi_page_t* page, bool in_full) {
+ page->flags.x.in_full = in_full;
+}
+
+static inline bool mi_page_has_aligned(const mi_page_t* page) {
+ return page->flags.x.has_aligned;
+}
+
+static inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) {
+ page->flags.x.has_aligned = has_aligned;
+}
+
+
+/* -------------------------------------------------------------------
+Encoding/Decoding the free list next pointers
+
+This is to protect against buffer overflow exploits where the
+free list is mutated. Many hardened allocators xor the next pointer `p`
+with a secret key `k1`, as `p^k1`. This prevents overwriting with known
+values but might be still too weak: if the attacker can guess
+the pointer `p` this can reveal `k1` (since `p^k1^p == k1`).
+Moreover, if multiple blocks can be read as well, the attacker can
+xor both as `(p1^k1) ^ (p2^k1) == p1^p2` which may reveal a lot
+about the pointers (and subsequently `k1`).
+
+Instead mimalloc uses an extra key `k2` and encodes as `((p^k2)<<<k1)+k1`.
+Since these operations are not associative, the above approaches do not
+work so well any more even if the `p` can be guesstimated. For example,
+for the read case we can subtract two entries to discard the `+k1` term,
+but that leads to `((p1^k2)<<<k1) - ((p2^k2)<<<k1)` at best.
+We include the left-rotation since xor and addition are otherwise linear
+in the lowest bit. Finally, both keys are unique per page which reduces
+the re-use of keys by a large factor.
+
+We also pass a separate `null` value to be used as `NULL` or otherwise
+`(k2<<<k1)+k1` would appear (too) often as a sentinel value.
+------------------------------------------------------------------- */
+
+static inline bool mi_is_in_same_segment(const void* p, const void* q) {
+ return (_mi_ptr_segment(p) == _mi_ptr_segment(q));
+}
+
+static inline bool mi_is_in_same_page(const void* p, const void* q) {
+ mi_segment_t* segment = _mi_ptr_segment(p);
+ if (_mi_ptr_segment(q) != segment) return false;
+ // assume q may be invalid // return (_mi_segment_page_of(segment, p) == _mi_segment_page_of(segment, q));
+ mi_page_t* page = _mi_segment_page_of(segment, p);
+ size_t psize;
+ uint8_t* start = _mi_segment_page_start(segment, page, &psize);
+ return (start <= (uint8_t*)q && (uint8_t*)q < start + psize);
+}
+
+static inline uintptr_t mi_rotl(uintptr_t x, uintptr_t shift) {
+ shift %= MI_INTPTR_BITS;
+ return (shift==0 ? x : ((x << shift) | (x >> (MI_INTPTR_BITS - shift))));
+}
+static inline uintptr_t mi_rotr(uintptr_t x, uintptr_t shift) {
+ shift %= MI_INTPTR_BITS;
+ return (shift==0 ? x : ((x >> shift) | (x << (MI_INTPTR_BITS - shift))));
+}
+
+static inline void* mi_ptr_decode(const void* null, const mi_encoded_t x, const uintptr_t* keys) {
+ void* p = (void*)(mi_rotr(x - keys[0], keys[0]) ^ keys[1]);
+ return (p==null ? NULL : p);
+}
+
+static inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const uintptr_t* keys) {
+ uintptr_t x = (uintptr_t)(p==NULL ? null : p);
+ return mi_rotl(x ^ keys[1], keys[0]) + keys[0];
+}
+
+static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) {
+ mi_track_mem_defined(block,sizeof(mi_block_t));
+ mi_block_t* next;
+ #ifdef MI_ENCODE_FREELIST
+ next = (mi_block_t*)mi_ptr_decode(null, mi_atomic_load_relaxed((_Atomic(mi_encoded_t)*)&block->next), keys);
+ #else
+ MI_UNUSED(keys); MI_UNUSED(null);
+ next = (mi_block_t*)mi_atomic_load_relaxed((_Atomic(mi_encoded_t)*)&block->next);
+ #endif
+ mi_track_mem_noaccess(block,sizeof(mi_block_t));
+ return next;
+}
+
+static inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) {
+ mi_track_mem_undefined(block,sizeof(mi_block_t));
+ #ifdef MI_ENCODE_FREELIST
+ mi_atomic_store_relaxed(&block->next, mi_ptr_encode(null, next, keys));
+ #else
+ MI_UNUSED(keys); MI_UNUSED(null);
+ mi_atomic_store_relaxed(&block->next, (mi_encoded_t)next);
+ #endif
+ mi_track_mem_noaccess(block,sizeof(mi_block_t));
+}
+
+static inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) {
+ #ifdef MI_ENCODE_FREELIST
+ mi_block_t* next = mi_block_nextx(page,block,page->keys);
+ // check for free list corruption: is `next` at least in the same page?
+ // TODO: check if `next` is `page->block_size` aligned?
+ if mi_unlikely(next!=NULL && !mi_is_in_same_page(block, next)) {
+ _mi_error_message(EFAULT, "corrupted free list entry of size %zub at %p: value 0x%zx\n", mi_page_block_size(page), block, (uintptr_t)next);
+ next = NULL;
+ }
+ return next;
+ #else
+ MI_UNUSED(page);
+ return mi_block_nextx(page,block,NULL);
+ #endif
+}
+
+static inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) {
+ #ifdef MI_ENCODE_FREELIST
+ mi_block_set_nextx(page,block,next, page->keys);
+ #else
+ MI_UNUSED(page);
+ mi_block_set_nextx(page,block,next,NULL);
+ #endif
+}
+
+
+// -------------------------------------------------------------------
+// commit mask
+// -------------------------------------------------------------------
+
+static inline void mi_commit_mask_create_empty(mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ cm->mask[i] = 0;
+ }
+}
+
+static inline void mi_commit_mask_create_full(mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ cm->mask[i] = ~((size_t)0);
+ }
+}
+
+static inline bool mi_commit_mask_is_empty(const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ if (cm->mask[i] != 0) return false;
+ }
+ return true;
+}
+
+static inline bool mi_commit_mask_is_full(const mi_commit_mask_t* cm) {
+ for (size_t i = 0; i < MI_COMMIT_MASK_FIELD_COUNT; i++) {
+ if (cm->mask[i] != ~((size_t)0)) return false;
+ }
+ return true;
+}
+
+// defined in `segment.c`:
+size_t _mi_commit_mask_committed_size(const mi_commit_mask_t* cm, size_t total);
+size_t _mi_commit_mask_next_run(const mi_commit_mask_t* cm, size_t* idx);
+
+#define mi_commit_mask_foreach(cm,idx,count) \
+ idx = 0; \
+ while ((count = _mi_commit_mask_next_run(cm,&idx)) > 0) {
+
+#define mi_commit_mask_foreach_end() \
+ idx += count; \
+ }
+
+
+
+/* -----------------------------------------------------------
+ memory id's
+----------------------------------------------------------- */
+
+static inline mi_memid_t _mi_memid_create(mi_memkind_t memkind) {
+ mi_memid_t memid;
+ _mi_memzero_var(memid);
+ memid.memkind = memkind;
+ return memid;
+}
+
+static inline mi_memid_t _mi_memid_none(void) {
+ return _mi_memid_create(MI_MEM_NONE);
+}
+
+static inline mi_memid_t _mi_memid_create_os(bool committed, bool is_zero, bool is_large) {
+ mi_memid_t memid = _mi_memid_create(MI_MEM_OS);
+ memid.initially_committed = committed;
+ memid.initially_zero = is_zero;
+ memid.is_pinned = is_large;
+ return memid;
+}
+
+
+// -------------------------------------------------------------------
+// Fast "random" shuffle
+// -------------------------------------------------------------------
+
+static inline uintptr_t _mi_random_shuffle(uintptr_t x) {
+ if (x==0) { x = 17; } // ensure we don't get stuck in generating zeros
+#if (MI_INTPTR_SIZE==8)
+ // by Sebastiano Vigna, see: <http://xoshiro.di.unimi.it/splitmix64.c>
+ x ^= x >> 30;
+ x *= 0xbf58476d1ce4e5b9UL;
+ x ^= x >> 27;
+ x *= 0x94d049bb133111ebUL;
+ x ^= x >> 31;
+#elif (MI_INTPTR_SIZE==4)
+ // by Chris Wellons, see: <https://nullprogram.com/blog/2018/07/31/>
+ x ^= x >> 16;
+ x *= 0x7feb352dUL;
+ x ^= x >> 15;
+ x *= 0x846ca68bUL;
+ x ^= x >> 16;
+#endif
+ return x;
+}
+
+// -------------------------------------------------------------------
+// Optimize numa node access for the common case (= one node)
+// -------------------------------------------------------------------
+
+int _mi_os_numa_node_get(mi_os_tld_t* tld);
+size_t _mi_os_numa_node_count_get(void);
+
+extern _Atomic(size_t) _mi_numa_node_count;
+static inline int _mi_os_numa_node(mi_os_tld_t* tld) {
+ if mi_likely(mi_atomic_load_relaxed(&_mi_numa_node_count) == 1) { return 0; }
+ else return _mi_os_numa_node_get(tld);
+}
+static inline size_t _mi_os_numa_node_count(void) {
+ const size_t count = mi_atomic_load_relaxed(&_mi_numa_node_count);
+ if mi_likely(count > 0) { return count; }
+ else return _mi_os_numa_node_count_get();
+}
+
+
+
+// -----------------------------------------------------------------------
+// Count bits: trailing or leading zeros (with MI_INTPTR_BITS on all zero)
+// -----------------------------------------------------------------------
+
+#if defined(__GNUC__)
+
+#include <limits.h> // LONG_MAX
+#define MI_HAVE_FAST_BITSCAN
+static inline size_t mi_clz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (INTPTR_MAX == LONG_MAX)
+ return __builtin_clzl(x);
+#else
+ return __builtin_clzll(x);
+#endif
+}
+static inline size_t mi_ctz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (INTPTR_MAX == LONG_MAX)
+ return __builtin_ctzl(x);
+#else
+ return __builtin_ctzll(x);
+#endif
+}
+
+#elif defined(_MSC_VER)
+
+#include <limits.h> // LONG_MAX
+#include <intrin.h> // BitScanReverse64
+#define MI_HAVE_FAST_BITSCAN
+static inline size_t mi_clz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+ unsigned long idx;
+#if (INTPTR_MAX == LONG_MAX)
+ _BitScanReverse(&idx, x);
+#else
+ _BitScanReverse64(&idx, x);
+#endif
+ return ((MI_INTPTR_BITS - 1) - idx);
+}
+static inline size_t mi_ctz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+ unsigned long idx;
+#if (INTPTR_MAX == LONG_MAX)
+ _BitScanForward(&idx, x);
+#else
+ _BitScanForward64(&idx, x);
+#endif
+ return idx;
+}
+
+#else
+static inline size_t mi_ctz32(uint32_t x) {
+ // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
+ static const unsigned char debruijn[32] = {
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
+ };
+ if (x==0) return 32;
+ return debruijn[((x & -(int32_t)x) * 0x077CB531UL) >> 27];
+}
+static inline size_t mi_clz32(uint32_t x) {
+ // de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
+ static const uint8_t debruijn[32] = {
+ 31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
+ 23, 19, 11, 3, 16, 14, 7, 24, 12, 4, 8, 25, 5, 26, 27, 0
+ };
+ if (x==0) return 32;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return debruijn[(uint32_t)(x * 0x07C4ACDDUL) >> 27];
+}
+
+static inline size_t mi_clz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (MI_INTPTR_BITS <= 32)
+ return mi_clz32((uint32_t)x);
+#else
+ size_t count = mi_clz32((uint32_t)(x >> 32));
+ if (count < 32) return count;
+ return (32 + mi_clz32((uint32_t)x));
+#endif
+}
+static inline size_t mi_ctz(uintptr_t x) {
+ if (x==0) return MI_INTPTR_BITS;
+#if (MI_INTPTR_BITS <= 32)
+ return mi_ctz32((uint32_t)x);
+#else
+ size_t count = mi_ctz32((uint32_t)x);
+ if (count < 32) return count;
+ return (32 + mi_ctz32((uint32_t)(x>>32)));
+#endif
+}
+
+#endif
+
+// "bit scan reverse": Return index of the highest bit (or MI_INTPTR_BITS if `x` is zero)
+static inline size_t mi_bsr(uintptr_t x) {
+ return (x==0 ? MI_INTPTR_BITS : MI_INTPTR_BITS - 1 - mi_clz(x));
+}
+
+
+// ---------------------------------------------------------------------------------
+// Provide our own `_mi_memcpy` for potential performance optimizations.
+//
+// For now, only on Windows with msvc/clang-cl we optimize to `rep movsb` if
+// we happen to run on x86/x64 cpu's that have "fast short rep movsb" (FSRM) support
+// (AMD Zen3+ (~2020) or Intel Ice Lake+ (~2017). See also issue #201 and pr #253.
+// ---------------------------------------------------------------------------------
+
+#if !MI_TRACK_ENABLED && defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
+#include <intrin.h>
+extern bool _mi_cpu_has_fsrm;
+static inline void _mi_memcpy(void* dst, const void* src, size_t n) {
+ if (_mi_cpu_has_fsrm) {
+ __movsb((unsigned char*)dst, (const unsigned char*)src, n);
+ }
+ else {
+ memcpy(dst, src, n);
+ }
+}
+static inline void _mi_memzero(void* dst, size_t n) {
+ if (_mi_cpu_has_fsrm) {
+ __stosb((unsigned char*)dst, 0, n);
+ }
+ else {
+ memset(dst, 0, n);
+ }
+}
+#else
+static inline void _mi_memcpy(void* dst, const void* src, size_t n) {
+ memcpy(dst, src, n);
+}
+static inline void _mi_memzero(void* dst, size_t n) {
+ memset(dst, 0, n);
+}
+#endif
+
+// -------------------------------------------------------------------------------
+// The `_mi_memcpy_aligned` can be used if the pointers are machine-word aligned
+// This is used for example in `mi_realloc`.
+// -------------------------------------------------------------------------------
+
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+// On GCC/CLang we provide a hint that the pointers are word aligned.
+static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {
+ mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));
+ void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);
+ const void* asrc = __builtin_assume_aligned(src, MI_INTPTR_SIZE);
+ _mi_memcpy(adst, asrc, n);
+}
+
+static inline void _mi_memzero_aligned(void* dst, size_t n) {
+ mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0);
+ void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);
+ _mi_memzero(adst, n);
+}
+#else
+// Default fallback on `_mi_memcpy`
+static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {
+ mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0));
+ _mi_memcpy(dst, src, n);
+}
+
+static inline void _mi_memzero_aligned(void* dst, size_t n) {
+ mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0);
+ _mi_memzero(dst, n);
+}
+#endif
+
+
+#endif
diff --git a/contrib/tools/python3/Include/internal/mimalloc/mimalloc/prim.h b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/prim.h
new file mode 100644
index 00000000000..322ab29e6b4
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/prim.h
@@ -0,0 +1,329 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2023, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#pragma once
+#ifndef MIMALLOC_PRIM_H
+#define MIMALLOC_PRIM_H
+
+
+// --------------------------------------------------------------------------
+// This file specifies the primitive portability API.
+// Each OS/host needs to implement these primitives, see `src/prim`
+// for implementations on Window, macOS, WASI, and Linux/Unix.
+//
+// note: on all primitive functions, we always have result parameters != NUL, and:
+// addr != NULL and page aligned
+// size > 0 and page aligned
+// return value is an error code an int where 0 is success.
+// --------------------------------------------------------------------------
+
+// OS memory configuration
+typedef struct mi_os_mem_config_s {
+ size_t page_size; // 4KiB
+ size_t large_page_size; // 2MiB
+ size_t alloc_granularity; // smallest allocation size (on Windows 64KiB)
+ bool has_overcommit; // can we reserve more memory than can be actually committed?
+ bool must_free_whole; // must allocated blocks be freed as a whole (false for mmap, true for VirtualAlloc)
+ bool has_virtual_reserve; // supports virtual address space reservation? (if true we can reserve virtual address space without using commit or physical memory)
+} mi_os_mem_config_t;
+
+// Initialize
+void _mi_prim_mem_init( mi_os_mem_config_t* config );
+
+// Free OS memory
+int _mi_prim_free(void* addr, size_t size );
+
+// Allocate OS memory. Return NULL on error.
+// The `try_alignment` is just a hint and the returned pointer does not have to be aligned.
+// If `commit` is false, the virtual memory range only needs to be reserved (with no access)
+// which will later be committed explicitly using `_mi_prim_commit`.
+// `is_zero` is set to true if the memory was zero initialized (as on most OS's)
+// pre: !commit => !allow_large
+// try_alignment >= _mi_os_page_size() and a power of 2
+int _mi_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr);
+
+// Commit memory. Returns error code or 0 on success.
+// For example, on Linux this would make the memory PROT_READ|PROT_WRITE.
+// `is_zero` is set to true if the memory was zero initialized (e.g. on Windows)
+int _mi_prim_commit(void* addr, size_t size, bool* is_zero);
+
+// Decommit memory. Returns error code or 0 on success. The `needs_recommit` result is true
+// if the memory would need to be re-committed. For example, on Windows this is always true,
+// but on Linux we could use MADV_DONTNEED to decommit which does not need a recommit.
+// pre: needs_recommit != NULL
+int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit);
+
+// Reset memory. The range keeps being accessible but the content might be reset.
+// Returns error code or 0 on success.
+int _mi_prim_reset(void* addr, size_t size);
+
+// Protect memory. Returns error code or 0 on success.
+int _mi_prim_protect(void* addr, size_t size, bool protect);
+
+// Allocate huge (1GiB) pages possibly associated with a NUMA node.
+// `is_zero` is set to true if the memory was zero initialized (as on most OS's)
+// pre: size > 0 and a multiple of 1GiB.
+// numa_node is either negative (don't care), or a numa node number.
+int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr);
+
+// Return the current NUMA node
+size_t _mi_prim_numa_node(void);
+
+// Return the number of logical NUMA nodes
+size_t _mi_prim_numa_node_count(void);
+
+// Clock ticks
+mi_msecs_t _mi_prim_clock_now(void);
+
+// Return process information (only for statistics)
+typedef struct mi_process_info_s {
+ mi_msecs_t elapsed;
+ mi_msecs_t utime;
+ mi_msecs_t stime;
+ size_t current_rss;
+ size_t peak_rss;
+ size_t current_commit;
+ size_t peak_commit;
+ size_t page_faults;
+} mi_process_info_t;
+
+void _mi_prim_process_info(mi_process_info_t* pinfo);
+
+// Default stderr output. (only for warnings etc. with verbose enabled)
+// msg != NULL && _mi_strlen(msg) > 0
+void _mi_prim_out_stderr( const char* msg );
+
+// Get an environment variable. (only for options)
+// name != NULL, result != NULL, result_size >= 64
+bool _mi_prim_getenv(const char* name, char* result, size_t result_size);
+
+
+// Fill a buffer with strong randomness; return `false` on error or if
+// there is no strong randomization available.
+bool _mi_prim_random_buf(void* buf, size_t buf_len);
+
+// Called on the first thread start, and should ensure `_mi_thread_done` is called on thread termination.
+void _mi_prim_thread_init_auto_done(void);
+
+// Called on process exit and may take action to clean up resources associated with the thread auto done.
+void _mi_prim_thread_done_auto_done(void);
+
+// Called when the default heap for a thread changes
+void _mi_prim_thread_associate_default_heap(mi_heap_t* heap);
+
+
+//-------------------------------------------------------------------
+// Thread id: `_mi_prim_thread_id()`
+//
+// Getting the thread id should be performant as it is called in the
+// fast path of `_mi_free` and we specialize for various platforms as
+// inlined definitions. Regular code should call `init.c:_mi_thread_id()`.
+// We only require _mi_prim_thread_id() to return a unique id
+// for each thread (unequal to zero).
+//-------------------------------------------------------------------
+
+// defined in `init.c`; do not use these directly
+extern mi_decl_thread mi_heap_t* _mi_heap_default; // default heap to allocate from
+extern bool _mi_process_is_initialized; // has mi_process_init been called?
+
+static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept;
+
+#ifdef MI_PRIM_THREAD_ID
+
+static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {
+ return MI_PRIM_THREAD_ID();
+}
+
+#elif defined(_WIN32)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {
+ // Windows: works on Intel and ARM in both 32- and 64-bit
+ return (uintptr_t)NtCurrentTeb();
+}
+
+// We use assembly for a fast thread id on the main platforms. The TLS layout depends on
+// both the OS and libc implementation so we use specific tests for each main platform.
+// If you test on another platform and it works please send a PR :-)
+// see also https://akkadia.org/drepper/tls.pdf for more info on the TLS register.
+#elif defined(__GNUC__) && ( \
+ (defined(__GLIBC__) && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \
+ || (defined(__APPLE__) && (defined(__x86_64__) || defined(__aarch64__))) \
+ || (defined(__BIONIC__) && (defined(__x86_64__) || defined(__i386__) || (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__))) \
+ || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \
+ || (defined(__OpenBSD__) && (defined(__x86_64__) || defined(__i386__) || defined(__aarch64__))) \
+ )
+
+static inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept {
+ void* res;
+ const size_t ofs = (slot*sizeof(void*));
+ #if defined(__i386__)
+ __asm__("movl %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86 32-bit always uses GS
+ #elif defined(__APPLE__) && defined(__x86_64__)
+ __asm__("movq %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 macOSX uses GS
+ #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)
+ __asm__("movl %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x32 ABI
+ #elif defined(__x86_64__)
+ __asm__("movq %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 Linux, BSD uses FS
+ #elif defined(__arm__)
+ void** tcb; MI_UNUSED(ofs);
+ __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
+ res = tcb[slot];
+ #elif defined(__aarch64__)
+ void** tcb; MI_UNUSED(ofs);
+ #if defined(__APPLE__) // M1, issue #343
+ __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb));
+ #else
+ __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
+ #endif
+ res = tcb[slot];
+ #endif
+ return res;
+}
+
+// setting a tls slot is only used on macOS for now
+static inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexcept {
+ const size_t ofs = (slot*sizeof(void*));
+ #if defined(__i386__)
+ __asm__("movl %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // 32-bit always uses GS
+ #elif defined(__APPLE__) && defined(__x86_64__)
+ __asm__("movq %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 macOS uses GS
+ #elif defined(__x86_64__) && (MI_INTPTR_SIZE==4)
+ __asm__("movl %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x32 ABI
+ #elif defined(__x86_64__)
+ __asm__("movq %1,%%fs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 Linux, BSD uses FS
+ #elif defined(__arm__)
+ void** tcb; MI_UNUSED(ofs);
+ __asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
+ tcb[slot] = value;
+ #elif defined(__aarch64__)
+ void** tcb; MI_UNUSED(ofs);
+ #if defined(__APPLE__) // M1, issue #343
+ __asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb));
+ #else
+ __asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
+ #endif
+ tcb[slot] = value;
+ #endif
+}
+
+static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {
+ #if defined(__BIONIC__)
+ // issue #384, #495: on the Bionic libc (Android), slot 1 is the thread id
+ // see: https://github.com/aosp-mirror/platform_bionic/blob/c44b1d0676ded732df4b3b21c5f798eacae93228/libc/platform/bionic/tls_defines.h#L86
+ return (uintptr_t)mi_prim_tls_slot(1);
+ #else
+ // in all our other targets, slot 0 is the thread id
+ // glibc: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=sysdeps/x86_64/nptl/tls.h
+ // apple: https://github.com/apple/darwin-xnu/blob/main/libsyscall/os/tsd.h#L36
+ return (uintptr_t)mi_prim_tls_slot(0);
+ #endif
+}
+
+#else
+
+// otherwise use portable C, taking the address of a thread local variable (this is still very fast on most platforms).
+static inline mi_threadid_t _mi_prim_thread_id(void) mi_attr_noexcept {
+ return (uintptr_t)&_mi_heap_default;
+}
+
+#endif
+
+
+
+/* ----------------------------------------------------------------------------------------
+The thread local default heap: `_mi_prim_get_default_heap()`
+This is inlined here as it is on the fast path for allocation functions.
+
+On most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a
+__thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures
+that the storage will always be available (allocated on the thread stacks).
+
+On some platforms though we cannot use that when overriding `malloc` since the underlying
+TLS implementation (or the loader) will call itself `malloc` on a first access and recurse.
+We try to circumvent this in an efficient way:
+- macOSX : we use an unused TLS slot from the OS allocated slots (MI_TLS_SLOT). On OSX, the
+ loader itself calls `malloc` even before the modules are initialized.
+- OpenBSD: we use an unused slot from the pthread block (MI_TLS_PTHREAD_SLOT_OFS).
+- DragonFly: defaults are working but seem slow compared to freeBSD (see PR #323)
+------------------------------------------------------------------------------------------- */
+
+static inline mi_heap_t* mi_prim_get_default_heap(void);
+
+#if defined(MI_MALLOC_OVERRIDE)
+#if defined(__APPLE__) // macOS
+ #define MI_TLS_SLOT 89 // seems unused?
+ // #define MI_TLS_RECURSE_GUARD 1
+ // other possible unused ones are 9, 29, __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 (94), __PTK_FRAMEWORK_GC_KEY9 (112) and __PTK_FRAMEWORK_OLDGC_KEY9 (89)
+ // see <https://github.com/rweichler/substrate/blob/master/include/pthread_machdep.h>
+#elif defined(__OpenBSD__)
+ // use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16)
+ // see <https://github.com/openbsd/src/blob/master/lib/libc/include/thread_private.h#L371>
+ #define MI_TLS_PTHREAD_SLOT_OFS (6*sizeof(int) + 4*sizeof(void*) + 24)
+ // #elif defined(__DragonFly__)
+ // #warning "mimalloc is not working correctly on DragonFly yet."
+ // #define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) <https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/lib/libthread_xu/thread/thr_private.h#L458>
+#elif defined(__ANDROID__)
+ // See issue #381
+ #define MI_TLS_PTHREAD
+#endif
+#endif
+
+
+#if defined(MI_TLS_SLOT)
+
+static inline mi_heap_t* mi_prim_get_default_heap(void) {
+ mi_heap_t* heap = (mi_heap_t*)mi_prim_tls_slot(MI_TLS_SLOT);
+ if mi_unlikely(heap == NULL) {
+ #ifdef __GNUC__
+ __asm(""); // prevent conditional load of the address of _mi_heap_empty
+ #endif
+ heap = (mi_heap_t*)&_mi_heap_empty;
+ }
+ return heap;
+}
+
+#elif defined(MI_TLS_PTHREAD_SLOT_OFS)
+
+static inline mi_heap_t** mi_prim_tls_pthread_heap_slot(void) {
+ pthread_t self = pthread_self();
+ #if defined(__DragonFly__)
+ if (self==NULL) return NULL;
+ #endif
+ return (mi_heap_t**)((uint8_t*)self + MI_TLS_PTHREAD_SLOT_OFS);
+}
+
+static inline mi_heap_t* mi_prim_get_default_heap(void) {
+ mi_heap_t** pheap = mi_prim_tls_pthread_heap_slot();
+ if mi_unlikely(pheap == NULL) return _mi_heap_main_get();
+ mi_heap_t* heap = *pheap;
+ if mi_unlikely(heap == NULL) return (mi_heap_t*)&_mi_heap_empty;
+ return heap;
+}
+
+#elif defined(MI_TLS_PTHREAD)
+
+extern pthread_key_t _mi_heap_default_key;
+static inline mi_heap_t* mi_prim_get_default_heap(void) {
+ mi_heap_t* heap = (mi_unlikely(_mi_heap_default_key == (pthread_key_t)(-1)) ? _mi_heap_main_get() : (mi_heap_t*)pthread_getspecific(_mi_heap_default_key));
+ return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap);
+}
+
+#else // default using a thread local variable; used on most platforms.
+
+static inline mi_heap_t* mi_prim_get_default_heap(void) {
+ #if defined(MI_TLS_RECURSE_GUARD)
+ if (mi_unlikely(!_mi_process_is_initialized)) return _mi_heap_main_get();
+ #endif
+ return _mi_heap_default;
+}
+
+#endif // mi_prim_get_default_heap()
+
+
+
+#endif // MIMALLOC_PRIM_H
diff --git a/contrib/tools/python3/Include/internal/mimalloc/mimalloc/track.h b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/track.h
new file mode 100644
index 00000000000..6a3b5a280e5
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/track.h
@@ -0,0 +1,147 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2023, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#pragma once
+#ifndef MIMALLOC_TRACK_H
+#define MIMALLOC_TRACK_H
+
+/* ------------------------------------------------------------------------------------------------------
+Track memory ranges with macros for tools like Valgrind address sanitizer, or other memory checkers.
+These can be defined for tracking allocation:
+
+ #define mi_track_malloc_size(p,reqsize,size,zero)
+ #define mi_track_free_size(p,_size)
+
+The macros are set up such that the size passed to `mi_track_free_size`
+always matches the size of `mi_track_malloc_size`. (currently, `size == mi_usable_size(p)`).
+The `reqsize` is what the user requested, and `size >= reqsize`.
+The `size` is either byte precise (and `size==reqsize`) if `MI_PADDING` is enabled,
+or otherwise it is the usable block size which may be larger than the original request.
+Use `_mi_block_size_of(void* p)` to get the full block size that was allocated (including padding etc).
+The `zero` parameter is `true` if the allocated block is zero initialized.
+
+Optional:
+
+ #define mi_track_align(p,alignedp,offset,size)
+ #define mi_track_resize(p,oldsize,newsize)
+ #define mi_track_init()
+
+The `mi_track_align` is called right after a `mi_track_malloc` for aligned pointers in a block.
+The corresponding `mi_track_free` still uses the block start pointer and original size (corresponding to the `mi_track_malloc`).
+The `mi_track_resize` is currently unused but could be called on reallocations within a block.
+`mi_track_init` is called at program start.
+
+The following macros are for tools like asan and valgrind to track whether memory is
+defined, undefined, or not accessible at all:
+
+ #define mi_track_mem_defined(p,size)
+ #define mi_track_mem_undefined(p,size)
+ #define mi_track_mem_noaccess(p,size)
+
+-------------------------------------------------------------------------------------------------------*/
+
+#if MI_TRACK_VALGRIND
+// valgrind tool
+
+#define MI_TRACK_ENABLED 1
+#define MI_TRACK_HEAP_DESTROY 1 // track free of individual blocks on heap_destroy
+#define MI_TRACK_TOOL "valgrind"
+
+#include <valgrind/valgrind.h>
+#include <valgrind/memcheck.h>
+
+#define mi_track_malloc_size(p,reqsize,size,zero) VALGRIND_MALLOCLIKE_BLOCK(p,size,MI_PADDING_SIZE /*red zone*/,zero)
+#define mi_track_free_size(p,_size) VALGRIND_FREELIKE_BLOCK(p,MI_PADDING_SIZE /*red zone*/)
+#define mi_track_resize(p,oldsize,newsize) VALGRIND_RESIZEINPLACE_BLOCK(p,oldsize,newsize,MI_PADDING_SIZE /*red zone*/)
+#define mi_track_mem_defined(p,size) VALGRIND_MAKE_MEM_DEFINED(p,size)
+#define mi_track_mem_undefined(p,size) VALGRIND_MAKE_MEM_UNDEFINED(p,size)
+#define mi_track_mem_noaccess(p,size) VALGRIND_MAKE_MEM_NOACCESS(p,size)
+
+#elif MI_TRACK_ASAN
+// address sanitizer
+
+#define MI_TRACK_ENABLED 1
+#define MI_TRACK_HEAP_DESTROY 0
+#define MI_TRACK_TOOL "asan"
+
+#error #include <sanitizer/asan_interface.h>
+
+#define mi_track_malloc_size(p,reqsize,size,zero) ASAN_UNPOISON_MEMORY_REGION(p,size)
+#define mi_track_free_size(p,size) ASAN_POISON_MEMORY_REGION(p,size)
+#define mi_track_mem_defined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size)
+#define mi_track_mem_undefined(p,size) ASAN_UNPOISON_MEMORY_REGION(p,size)
+#define mi_track_mem_noaccess(p,size) ASAN_POISON_MEMORY_REGION(p,size)
+
+#elif MI_TRACK_ETW
+// windows event tracing
+
+#define MI_TRACK_ENABLED 1
+#define MI_TRACK_HEAP_DESTROY 1
+#define MI_TRACK_TOOL "ETW"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#error #include "../src/prim/windows/etw.h"
+
+#define mi_track_init() EventRegistermicrosoft_windows_mimalloc();
+#define mi_track_malloc_size(p,reqsize,size,zero) EventWriteETW_MI_ALLOC((UINT64)(p), size)
+#define mi_track_free_size(p,size) EventWriteETW_MI_FREE((UINT64)(p), size)
+
+#else
+// no tracking
+
+#define MI_TRACK_ENABLED 0
+#define MI_TRACK_HEAP_DESTROY 0
+#define MI_TRACK_TOOL "none"
+
+#define mi_track_malloc_size(p,reqsize,size,zero)
+#define mi_track_free_size(p,_size)
+
+#endif
+
+// -------------------
+// Utility definitions
+
+#ifndef mi_track_resize
+#define mi_track_resize(p,oldsize,newsize) mi_track_free_size(p,oldsize); mi_track_malloc(p,newsize,false)
+#endif
+
+#ifndef mi_track_align
+#define mi_track_align(p,alignedp,offset,size) mi_track_mem_noaccess(p,offset)
+#endif
+
+#ifndef mi_track_init
+#define mi_track_init()
+#endif
+
+#ifndef mi_track_mem_defined
+#define mi_track_mem_defined(p,size)
+#endif
+
+#ifndef mi_track_mem_undefined
+#define mi_track_mem_undefined(p,size)
+#endif
+
+#ifndef mi_track_mem_noaccess
+#define mi_track_mem_noaccess(p,size)
+#endif
+
+
+#if MI_PADDING
+#define mi_track_malloc(p,reqsize,zero) \
+ if ((p)!=NULL) { \
+ mi_assert_internal(mi_usable_size(p)==(reqsize)); \
+ mi_track_malloc_size(p,reqsize,reqsize,zero); \
+ }
+#else
+#define mi_track_malloc(p,reqsize,zero) \
+ if ((p)!=NULL) { \
+ mi_assert_internal(mi_usable_size(p)>=(reqsize)); \
+ mi_track_malloc_size(p,reqsize,mi_usable_size(p),zero); \
+ }
+#endif
+
+#endif
diff --git a/contrib/tools/python3/Include/internal/mimalloc/mimalloc/types.h b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/types.h
new file mode 100644
index 00000000000..70c600e920b
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/mimalloc/mimalloc/types.h
@@ -0,0 +1,721 @@
+/* ----------------------------------------------------------------------------
+Copyright (c) 2018-2023, Microsoft Research, Daan Leijen
+This is free software; you can redistribute it and/or modify it under the
+terms of the MIT license. A copy of the license can be found in the file
+"LICENSE" at the root of this distribution.
+-----------------------------------------------------------------------------*/
+#pragma once
+#ifndef MIMALLOC_TYPES_H
+#define MIMALLOC_TYPES_H
+
+// --------------------------------------------------------------------------
+// This file contains the main type definitions for mimalloc:
+// mi_heap_t : all data for a thread-local heap, contains
+// lists of all managed heap pages.
+// mi_segment_t : a larger chunk of memory (32GiB) from where pages
+// are allocated.
+// mi_page_t : a mimalloc page (usually 64KiB or 512KiB) from
+// where objects are allocated.
+// --------------------------------------------------------------------------
+
+
+#include <stddef.h> // ptrdiff_t
+#include <stdint.h> // uintptr_t, uint16_t, etc
+#include "atomic.h" // _Atomic
+
+#ifdef _MSC_VER
+#pragma warning(disable:4214) // bitfield is not int
+#endif
+
+// Minimal alignment necessary. On most platforms 16 bytes are needed
+// due to SSE registers for example. This must be at least `sizeof(void*)`
+#ifndef MI_MAX_ALIGN_SIZE
+#define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t)
+#endif
+
+#define MI_CACHE_LINE 64
+#if defined(_MSC_VER)
+#pragma warning(disable:4127) // suppress constant conditional warning (due to MI_SECURE paths)
+#pragma warning(disable:26812) // unscoped enum warning
+#define mi_decl_noinline __declspec(noinline)
+#define mi_decl_thread __declspec(thread)
+#define mi_decl_cache_align __declspec(align(MI_CACHE_LINE))
+#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) // includes clang and icc
+#define mi_decl_noinline __attribute__((noinline))
+#define mi_decl_thread __thread
+#define mi_decl_cache_align __attribute__((aligned(MI_CACHE_LINE)))
+#else
+#define mi_decl_noinline
+#define mi_decl_thread __thread // hope for the best :-)
+#define mi_decl_cache_align
+#endif
+
+// ------------------------------------------------------
+// Variants
+// ------------------------------------------------------
+
+// Define NDEBUG in the release version to disable assertions.
+// #define NDEBUG
+
+// Define MI_TRACK_<tool> to enable tracking support
+// #define MI_TRACK_VALGRIND 1
+// #define MI_TRACK_ASAN 1
+// #define MI_TRACK_ETW 1
+
+// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance).
+// #define MI_STAT 1
+
+// Define MI_SECURE to enable security mitigations
+// #define MI_SECURE 1 // guard page around metadata
+// #define MI_SECURE 2 // guard page around each mimalloc page
+// #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free)
+// #define MI_SECURE 4 // checks for double free. (may be more expensive)
+
+#if !defined(MI_SECURE)
+#define MI_SECURE 0
+#endif
+
+// Define MI_DEBUG for debug mode
+// #define MI_DEBUG 1 // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free.
+// #define MI_DEBUG 2 // + internal assertion checks
+// #define MI_DEBUG 3 // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON)
+#if !defined(MI_DEBUG)
+#if !defined(NDEBUG) || defined(_DEBUG)
+#define MI_DEBUG 2
+#else
+#define MI_DEBUG 0
+#endif
+#endif
+
+// Reserve extra padding at the end of each block to be more resilient against heap block overflows.
+// The padding can detect buffer overflow on free.
+#if !defined(MI_PADDING) && (MI_SECURE>=3 || MI_DEBUG>=1 || (MI_TRACK_VALGRIND || MI_TRACK_ASAN || MI_TRACK_ETW))
+#define MI_PADDING 1
+#endif
+
+// Check padding bytes; allows byte-precise buffer overflow detection
+#if !defined(MI_PADDING_CHECK) && MI_PADDING && (MI_SECURE>=3 || MI_DEBUG>=1)
+#define MI_PADDING_CHECK 1
+#endif
+
+
+// Encoded free lists allow detection of corrupted free lists
+// and can detect buffer overflows, modify after free, and double `free`s.
+#if (MI_SECURE>=3 || MI_DEBUG>=1)
+#define MI_ENCODE_FREELIST 1
+#endif
+
+
+// We used to abandon huge pages but to eagerly deallocate if freed from another thread,
+// but that makes it not possible to visit them during a heap walk or include them in a
+// `mi_heap_destroy`. We therefore instead reset/decommit the huge blocks if freed from
+// another thread so most memory is available until it gets properly freed by the owning thread.
+// #define MI_HUGE_PAGE_ABANDON 1
+
+
+// ------------------------------------------------------
+// Platform specific values
+// ------------------------------------------------------
+
+// ------------------------------------------------------
+// Size of a pointer.
+// We assume that `sizeof(void*)==sizeof(intptr_t)`
+// and it holds for all platforms we know of.
+//
+// However, the C standard only requires that:
+// p == (void*)((intptr_t)p))
+// but we also need:
+// i == (intptr_t)((void*)i)
+// or otherwise one might define an intptr_t type that is larger than a pointer...
+// ------------------------------------------------------
+
+#if INTPTR_MAX > INT64_MAX
+# define MI_INTPTR_SHIFT (4) // assume 128-bit (as on arm CHERI for example)
+#elif INTPTR_MAX == INT64_MAX
+# define MI_INTPTR_SHIFT (3)
+#elif INTPTR_MAX == INT32_MAX
+# define MI_INTPTR_SHIFT (2)
+#else
+#error platform pointers must be 32, 64, or 128 bits
+#endif
+
+#if SIZE_MAX == UINT64_MAX
+# define MI_SIZE_SHIFT (3)
+typedef int64_t mi_ssize_t;
+#elif SIZE_MAX == UINT32_MAX
+# define MI_SIZE_SHIFT (2)
+typedef int32_t mi_ssize_t;
+#else
+#error platform objects must be 32 or 64 bits
+#endif
+
+#if (SIZE_MAX/2) > LONG_MAX
+# define MI_ZU(x) x##ULL
+# define MI_ZI(x) x##LL
+#else
+# define MI_ZU(x) x##UL
+# define MI_ZI(x) x##L
+#endif
+
+#define MI_INTPTR_SIZE (1<<MI_INTPTR_SHIFT)
+#define MI_INTPTR_BITS (MI_INTPTR_SIZE*8)
+
+#define MI_SIZE_SIZE (1<<MI_SIZE_SHIFT)
+#define MI_SIZE_BITS (MI_SIZE_SIZE*8)
+
+#define MI_KiB (MI_ZU(1024))
+#define MI_MiB (MI_KiB*MI_KiB)
+#define MI_GiB (MI_MiB*MI_KiB)
+
+
+// ------------------------------------------------------
+// Main internal data-structures
+// ------------------------------------------------------
+
+// Main tuning parameters for segment and page sizes
+// Sizes for 64-bit (usually divide by two for 32-bit)
+#define MI_SEGMENT_SLICE_SHIFT (13 + MI_INTPTR_SHIFT) // 64KiB (32KiB on 32-bit)
+
+#if MI_INTPTR_SIZE > 4
+#define MI_SEGMENT_SHIFT ( 9 + MI_SEGMENT_SLICE_SHIFT) // 32MiB
+#else
+#define MI_SEGMENT_SHIFT ( 7 + MI_SEGMENT_SLICE_SHIFT) // 4MiB on 32-bit
+#endif
+
+#define MI_SMALL_PAGE_SHIFT (MI_SEGMENT_SLICE_SHIFT) // 64KiB
+#define MI_MEDIUM_PAGE_SHIFT ( 3 + MI_SMALL_PAGE_SHIFT) // 512KiB
+
+
+// Derived constants
+#define MI_SEGMENT_SIZE (MI_ZU(1)<<MI_SEGMENT_SHIFT)
+#define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE
+#define MI_SEGMENT_MASK ((uintptr_t)(MI_SEGMENT_ALIGN - 1))
+#define MI_SEGMENT_SLICE_SIZE (MI_ZU(1)<< MI_SEGMENT_SLICE_SHIFT)
+#define MI_SLICES_PER_SEGMENT (MI_SEGMENT_SIZE / MI_SEGMENT_SLICE_SIZE) // 1024
+
+#define MI_SMALL_PAGE_SIZE (MI_ZU(1)<<MI_SMALL_PAGE_SHIFT)
+#define MI_MEDIUM_PAGE_SIZE (MI_ZU(1)<<MI_MEDIUM_PAGE_SHIFT)
+
+#define MI_SMALL_OBJ_SIZE_MAX (MI_SMALL_PAGE_SIZE/4) // 8KiB on 64-bit
+#define MI_MEDIUM_OBJ_SIZE_MAX (MI_MEDIUM_PAGE_SIZE/4) // 128KiB on 64-bit
+#define MI_MEDIUM_OBJ_WSIZE_MAX (MI_MEDIUM_OBJ_SIZE_MAX/MI_INTPTR_SIZE)
+#define MI_LARGE_OBJ_SIZE_MAX (MI_SEGMENT_SIZE/2) // 32MiB on 64-bit
+#define MI_LARGE_OBJ_WSIZE_MAX (MI_LARGE_OBJ_SIZE_MAX/MI_INTPTR_SIZE)
+
+// Maximum number of size classes. (spaced exponentially in 12.5% increments)
+#define MI_BIN_HUGE (73U)
+
+#if (MI_MEDIUM_OBJ_WSIZE_MAX >= 655360)
+#error "mimalloc internal: define more bins"
+#endif
+
+// Maximum slice offset (15)
+#define MI_MAX_SLICE_OFFSET ((MI_ALIGNMENT_MAX / MI_SEGMENT_SLICE_SIZE) - 1)
+
+// Used as a special value to encode block sizes in 32 bits.
+#define MI_HUGE_BLOCK_SIZE ((uint32_t)(2*MI_GiB))
+
+// blocks up to this size are always allocated aligned
+#define MI_MAX_ALIGN_GUARANTEE (8*MI_MAX_ALIGN_SIZE)
+
+// Alignments over MI_ALIGNMENT_MAX are allocated in dedicated huge page segments
+#define MI_ALIGNMENT_MAX (MI_SEGMENT_SIZE >> 1)
+
+
+// ------------------------------------------------------
+// Mimalloc pages contain allocated blocks
+// ------------------------------------------------------
+
+// The free lists use encoded next fields
+// (Only actually encodes when MI_ENCODED_FREELIST is defined.)
+typedef uintptr_t mi_encoded_t;
+
+// thread id's
+typedef size_t mi_threadid_t;
+
+// free lists contain blocks
+typedef struct mi_block_s {
+ _Atomic(mi_encoded_t) next;
+} mi_block_t;
+
+
+// The delayed flags are used for efficient multi-threaded free-ing
+typedef enum mi_delayed_e {
+ MI_USE_DELAYED_FREE = 0, // push on the owning heap thread delayed list
+ MI_DELAYED_FREEING = 1, // temporary: another thread is accessing the owning heap
+ MI_NO_DELAYED_FREE = 2, // optimize: push on page local thread free queue if another block is already in the heap thread delayed free list
+ MI_NEVER_DELAYED_FREE = 3 // sticky, only resets on page reclaim
+} mi_delayed_t;
+
+
+// The `in_full` and `has_aligned` page flags are put in a union to efficiently
+// test if both are false (`full_aligned == 0`) in the `mi_free` routine.
+#if !MI_TSAN
+typedef union mi_page_flags_s {
+ uint8_t full_aligned;
+ struct {
+ uint8_t in_full : 1;
+ uint8_t has_aligned : 1;
+ } x;
+} mi_page_flags_t;
+#else
+// under thread sanitizer, use a byte for each flag to suppress warning, issue #130
+typedef union mi_page_flags_s {
+ uint16_t full_aligned;
+ struct {
+ uint8_t in_full;
+ uint8_t has_aligned;
+ } x;
+} mi_page_flags_t;
+#endif
+
+// Thread free list.
+// We use the bottom 2 bits of the pointer for mi_delayed_t flags
+typedef uintptr_t mi_thread_free_t;
+
+// A page contains blocks of one specific size (`block_size`).
+// Each page has three list of free blocks:
+// `free` for blocks that can be allocated,
+// `local_free` for freed blocks that are not yet available to `mi_malloc`
+// `thread_free` for freed blocks by other threads
+// The `local_free` and `thread_free` lists are migrated to the `free` list
+// when it is exhausted. The separate `local_free` list is necessary to
+// implement a monotonic heartbeat. The `thread_free` list is needed for
+// avoiding atomic operations in the common case.
+//
+//
+// `used - |thread_free|` == actual blocks that are in use (alive)
+// `used - |thread_free| + |free| + |local_free| == capacity`
+//
+// We don't count `freed` (as |free|) but use `used` to reduce
+// the number of memory accesses in the `mi_page_all_free` function(s).
+//
+// Notes:
+// - Access is optimized for `mi_free` and `mi_page_alloc` (in `alloc.c`)
+// - Using `uint16_t` does not seem to slow things down
+// - The size is 8 words on 64-bit which helps the page index calculations
+// (and 10 words on 32-bit, and encoded free lists add 2 words. Sizes 10
+// and 12 are still good for address calculation)
+// - To limit the structure size, the `xblock_size` is 32-bits only; for
+// blocks > MI_HUGE_BLOCK_SIZE the size is determined from the segment page size
+// - `thread_free` uses the bottom bits as a delayed-free flags to optimize
+// concurrent frees where only the first concurrent free adds to the owning
+// heap `thread_delayed_free` list (see `alloc.c:mi_free_block_mt`).
+// The invariant is that no-delayed-free is only set if there is
+// at least one block that will be added, or as already been added, to
+// the owning heap `thread_delayed_free` list. This guarantees that pages
+// will be freed correctly even if only other threads free blocks.
+typedef struct mi_page_s {
+ // "owned" by the segment
+ uint32_t slice_count; // slices in this page (0 if not a page)
+ uint32_t slice_offset; // distance from the actual page data slice (0 if a page)
+ uint8_t is_committed : 1; // `true` if the page virtual memory is committed
+ uint8_t is_zero_init : 1; // `true` if the page was initially zero initialized
+ uint8_t use_qsbr : 1; // delay page freeing using qsbr
+ uint8_t tag : 4; // tag from the owning heap
+ uint8_t debug_offset; // number of bytes to preserve when filling freed or uninitialized memory
+
+ // layout like this to optimize access in `mi_malloc` and `mi_free`
+ uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear`
+ uint16_t reserved; // number of blocks reserved in memory
+ mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits)
+ uint8_t free_is_zero : 1; // `true` if the blocks in the free list are zero initialized
+ uint8_t retire_expire : 7; // expiration count for retired blocks
+
+ mi_block_t* free; // list of available free blocks (`malloc` allocates from this list)
+ uint32_t used; // number of blocks in use (including blocks in `local_free` and `thread_free`)
+ uint32_t xblock_size; // size available in each block (always `>0`)
+ mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`)
+
+ #if (MI_ENCODE_FREELIST || MI_PADDING)
+ uintptr_t keys[2]; // two random keys to encode the free lists (see `_mi_block_next`) or padding canary
+ #endif
+
+ _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads
+ _Atomic(uintptr_t) xheap;
+
+ struct mi_page_s* next; // next page owned by this thread with the same `block_size`
+ struct mi_page_s* prev; // previous page owned by this thread with the same `block_size`
+
+#ifdef Py_GIL_DISABLED
+ struct llist_node qsbr_node;
+ uint64_t qsbr_goal;
+#endif
+
+ // 64-bit 9 words, 32-bit 12 words, (+2 for secure)
+ #if MI_INTPTR_SIZE==8 && !defined(Py_GIL_DISABLED)
+ uintptr_t padding[1];
+ #endif
+} mi_page_t;
+
+
+
+// ------------------------------------------------------
+// Mimalloc segments contain mimalloc pages
+// ------------------------------------------------------
+
+typedef enum mi_page_kind_e {
+ MI_PAGE_SMALL, // small blocks go into 64KiB pages inside a segment
+ MI_PAGE_MEDIUM, // medium blocks go into medium pages inside a segment
+ MI_PAGE_LARGE, // larger blocks go into a page of just one block
+ MI_PAGE_HUGE, // huge blocks (> 16 MiB) are put into a single page in a single segment.
+} mi_page_kind_t;
+
+typedef enum mi_segment_kind_e {
+ MI_SEGMENT_NORMAL, // MI_SEGMENT_SIZE size with pages inside.
+ MI_SEGMENT_HUGE, // > MI_LARGE_SIZE_MAX segment with just one huge page inside.
+} mi_segment_kind_t;
+
+// ------------------------------------------------------
+// A segment holds a commit mask where a bit is set if
+// the corresponding MI_COMMIT_SIZE area is committed.
+// The MI_COMMIT_SIZE must be a multiple of the slice
+// size. If it is equal we have the most fine grained
+// decommit (but setting it higher can be more efficient).
+// The MI_MINIMAL_COMMIT_SIZE is the minimal amount that will
+// be committed in one go which can be set higher than
+// MI_COMMIT_SIZE for efficiency (while the decommit mask
+// is still tracked in fine-grained MI_COMMIT_SIZE chunks)
+// ------------------------------------------------------
+
+#define MI_MINIMAL_COMMIT_SIZE (1*MI_SEGMENT_SLICE_SIZE)
+#define MI_COMMIT_SIZE (MI_SEGMENT_SLICE_SIZE) // 64KiB
+#define MI_COMMIT_MASK_BITS (MI_SEGMENT_SIZE / MI_COMMIT_SIZE)
+#define MI_COMMIT_MASK_FIELD_BITS MI_SIZE_BITS
+#define MI_COMMIT_MASK_FIELD_COUNT (MI_COMMIT_MASK_BITS / MI_COMMIT_MASK_FIELD_BITS)
+
+#if (MI_COMMIT_MASK_BITS != (MI_COMMIT_MASK_FIELD_COUNT * MI_COMMIT_MASK_FIELD_BITS))
+#error "the segment size must be exactly divisible by the (commit size * size_t bits)"
+#endif
+
+typedef struct mi_commit_mask_s {
+ size_t mask[MI_COMMIT_MASK_FIELD_COUNT];
+} mi_commit_mask_t;
+
+typedef mi_page_t mi_slice_t;
+typedef int64_t mi_msecs_t;
+
+
+// Memory can reside in arena's, direct OS allocated, or statically allocated. The memid keeps track of this.
+typedef enum mi_memkind_e {
+ MI_MEM_NONE, // not allocated
+ MI_MEM_EXTERNAL, // not owned by mimalloc but provided externally (via `mi_manage_os_memory` for example)
+ MI_MEM_STATIC, // allocated in a static area and should not be freed (for arena meta data for example)
+ MI_MEM_OS, // allocated from the OS
+ MI_MEM_OS_HUGE, // allocated as huge os pages
+ MI_MEM_OS_REMAP, // allocated in a remapable area (i.e. using `mremap`)
+ MI_MEM_ARENA // allocated from an arena (the usual case)
+} mi_memkind_t;
+
+static inline bool mi_memkind_is_os(mi_memkind_t memkind) {
+ return (memkind >= MI_MEM_OS && memkind <= MI_MEM_OS_REMAP);
+}
+
+typedef struct mi_memid_os_info {
+ void* base; // actual base address of the block (used for offset aligned allocations)
+ size_t alignment; // alignment at allocation
+} mi_memid_os_info_t;
+
+typedef struct mi_memid_arena_info {
+ size_t block_index; // index in the arena
+ mi_arena_id_t id; // arena id (>= 1)
+ bool is_exclusive; // the arena can only be used for specific arena allocations
+} mi_memid_arena_info_t;
+
+typedef struct mi_memid_s {
+ union {
+ mi_memid_os_info_t os; // only used for MI_MEM_OS
+ mi_memid_arena_info_t arena; // only used for MI_MEM_ARENA
+ } mem;
+ bool is_pinned; // `true` if we cannot decommit/reset/protect in this memory (e.g. when allocated using large OS pages)
+ bool initially_committed;// `true` if the memory was originally allocated as committed
+ bool initially_zero; // `true` if the memory was originally zero initialized
+ mi_memkind_t memkind;
+} mi_memid_t;
+
+
+// Segments are large allocated memory blocks (8mb on 64 bit) from
+// the OS. Inside segments we allocated fixed size _pages_ that
+// contain blocks.
+typedef struct mi_segment_s {
+ // constant fields
+ mi_memid_t memid; // memory id for arena allocation
+ bool allow_decommit;
+ bool allow_purge;
+ size_t segment_size;
+
+ // segment fields
+ mi_msecs_t purge_expire;
+ mi_commit_mask_t purge_mask;
+ mi_commit_mask_t commit_mask;
+
+ _Atomic(struct mi_segment_s*) abandoned_next;
+
+ // from here is zero initialized
+ struct mi_segment_s* next; // the list of freed segments in the cache (must be first field, see `segment.c:mi_segment_init`)
+
+ size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`)
+ size_t abandoned_visits; // count how often this segment is visited in the abandoned list (to force reclaim it it is too long)
+ size_t used; // count of pages in use
+ uintptr_t cookie; // verify addresses in debug mode: `mi_ptr_cookie(segment) == segment->cookie`
+
+ size_t segment_slices; // for huge segments this may be different from `MI_SLICES_PER_SEGMENT`
+ size_t segment_info_slices; // initial slices we are using segment info and possible guard pages.
+
+ // layout like this to optimize access in `mi_free`
+ mi_segment_kind_t kind;
+ size_t slice_entries; // entries in the `slices` array, at most `MI_SLICES_PER_SEGMENT`
+ _Atomic(mi_threadid_t) thread_id; // unique id of the thread owning this segment
+
+ mi_slice_t slices[MI_SLICES_PER_SEGMENT+1]; // one more for huge blocks with large alignment
+} mi_segment_t;
+
+typedef uintptr_t mi_tagged_segment_t;
+
+// Segments unowned by any thread are put in a shared pool
+typedef struct mi_abandoned_pool_s {
+ // This is a list of visited abandoned pages that were full at the time.
+ // this list migrates to `abandoned` when that becomes NULL. The use of
+ // this list reduces contention and the rate at which segments are visited.
+ mi_decl_cache_align _Atomic(mi_segment_t*) abandoned_visited; // = NULL
+
+ // The abandoned page list (tagged as it supports pop)
+ mi_decl_cache_align _Atomic(mi_tagged_segment_t) abandoned; // = NULL
+
+ // Maintain these for debug purposes (these counts may be a bit off)
+ mi_decl_cache_align _Atomic(size_t) abandoned_count;
+ mi_decl_cache_align _Atomic(size_t) abandoned_visited_count;
+
+ // We also maintain a count of current readers of the abandoned list
+ // in order to prevent resetting/decommitting segment memory if it might
+ // still be read.
+ mi_decl_cache_align _Atomic(size_t) abandoned_readers; // = 0
+} mi_abandoned_pool_t;
+
+
+// ------------------------------------------------------
+// Heaps
+// Provide first-class heaps to allocate from.
+// A heap just owns a set of pages for allocation and
+// can only be allocate/reallocate from the thread that created it.
+// Freeing blocks can be done from any thread though.
+// Per thread, the segments are shared among its heaps.
+// Per thread, there is always a default heap that is
+// used for allocation; it is initialized to statically
+// point to an empty heap to avoid initialization checks
+// in the fast path.
+// ------------------------------------------------------
+
+// Thread local data
+typedef struct mi_tld_s mi_tld_t;
+
+// Pages of a certain block size are held in a queue.
+typedef struct mi_page_queue_s {
+ mi_page_t* first;
+ mi_page_t* last;
+ size_t block_size;
+} mi_page_queue_t;
+
+#define MI_BIN_FULL (MI_BIN_HUGE+1)
+
+// Random context
+typedef struct mi_random_cxt_s {
+ uint32_t input[16];
+ uint32_t output[16];
+ int output_available;
+ bool weak;
+} mi_random_ctx_t;
+
+
+// In debug mode there is a padding structure at the end of the blocks to check for buffer overflows
+#if (MI_PADDING)
+typedef struct mi_padding_s {
+ uint32_t canary; // encoded block value to check validity of the padding (in case of overflow)
+ uint32_t delta; // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes)
+} mi_padding_t;
+#define MI_PADDING_SIZE (sizeof(mi_padding_t))
+#define MI_PADDING_WSIZE ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE)
+#else
+#define MI_PADDING_SIZE 0
+#define MI_PADDING_WSIZE 0
+#endif
+
+#define MI_PAGES_DIRECT (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1)
+
+
+// A heap owns a set of pages.
+struct mi_heap_s {
+ mi_tld_t* tld;
+ mi_page_t* pages_free_direct[MI_PAGES_DIRECT]; // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size.
+ mi_page_queue_t pages[MI_BIN_FULL + 1]; // queue of pages for each size class (or "bin")
+ _Atomic(mi_block_t*) thread_delayed_free;
+ mi_threadid_t thread_id; // thread this heap belongs too
+ mi_arena_id_t arena_id; // arena id if the heap belongs to a specific arena (or 0)
+ uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`)
+ uintptr_t keys[2]; // two random keys used to encode the `thread_delayed_free` list
+ mi_random_ctx_t random; // random number context used for secure allocation
+ size_t page_count; // total number of pages in the `pages` queues.
+ size_t page_retired_min; // smallest retired index (retired pages are fully free, but still in the page queues)
+ size_t page_retired_max; // largest retired index into the `pages` array.
+ mi_heap_t* next; // list of heaps per thread
+ bool no_reclaim; // `true` if this heap should not reclaim abandoned pages
+ uint8_t tag; // custom identifier for this heap
+ uint8_t debug_offset; // number of bytes to preserve when filling freed or uninitialized memory
+ bool page_use_qsbr; // should freeing pages be delayed using QSBR
+};
+
+
+
+// ------------------------------------------------------
+// Debug
+// ------------------------------------------------------
+
+#if !defined(MI_DEBUG_UNINIT)
+#define MI_DEBUG_UNINIT (0xD0)
+#endif
+#if !defined(MI_DEBUG_FREED)
+#define MI_DEBUG_FREED (0xDF)
+#endif
+#if !defined(MI_DEBUG_PADDING)
+#define MI_DEBUG_PADDING (0xDE)
+#endif
+
+#if (MI_DEBUG)
+// use our own assertion to print without memory allocation
+void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func );
+#define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__))
+#else
+#define mi_assert(x)
+#endif
+
+#if (MI_DEBUG>1)
+#define mi_assert_internal mi_assert
+#else
+#define mi_assert_internal(x)
+#endif
+
+#if (MI_DEBUG>2)
+#define mi_assert_expensive mi_assert
+#else
+#define mi_assert_expensive(x)
+#endif
+
+// ------------------------------------------------------
+// Statistics
+// ------------------------------------------------------
+
+#ifndef MI_STAT
+#if (MI_DEBUG>0)
+#define MI_STAT 2
+#else
+#define MI_STAT 0
+#endif
+#endif
+
+typedef struct mi_stat_count_s {
+ int64_t allocated;
+ int64_t freed;
+ int64_t peak;
+ int64_t current;
+} mi_stat_count_t;
+
+typedef struct mi_stat_counter_s {
+ int64_t total;
+ int64_t count;
+} mi_stat_counter_t;
+
+typedef struct mi_stats_s {
+ mi_stat_count_t segments;
+ mi_stat_count_t pages;
+ mi_stat_count_t reserved;
+ mi_stat_count_t committed;
+ mi_stat_count_t reset;
+ mi_stat_count_t purged;
+ mi_stat_count_t page_committed;
+ mi_stat_count_t segments_abandoned;
+ mi_stat_count_t pages_abandoned;
+ mi_stat_count_t threads;
+ mi_stat_count_t normal;
+ mi_stat_count_t huge;
+ mi_stat_count_t large;
+ mi_stat_count_t malloc;
+ mi_stat_count_t segments_cache;
+ mi_stat_counter_t pages_extended;
+ mi_stat_counter_t mmap_calls;
+ mi_stat_counter_t commit_calls;
+ mi_stat_counter_t reset_calls;
+ mi_stat_counter_t purge_calls;
+ mi_stat_counter_t page_no_retire;
+ mi_stat_counter_t searches;
+ mi_stat_counter_t normal_count;
+ mi_stat_counter_t huge_count;
+ mi_stat_counter_t large_count;
+#if MI_STAT>1
+ mi_stat_count_t normal_bins[MI_BIN_HUGE+1];
+#endif
+} mi_stats_t;
+
+
+void _mi_stat_increase(mi_stat_count_t* stat, size_t amount);
+void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount);
+void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount);
+
+#if (MI_STAT)
+#define mi_stat_increase(stat,amount) _mi_stat_increase( &(stat), amount)
+#define mi_stat_decrease(stat,amount) _mi_stat_decrease( &(stat), amount)
+#define mi_stat_counter_increase(stat,amount) _mi_stat_counter_increase( &(stat), amount)
+#else
+#define mi_stat_increase(stat,amount) (void)0
+#define mi_stat_decrease(stat,amount) (void)0
+#define mi_stat_counter_increase(stat,amount) (void)0
+#endif
+
+#define mi_heap_stat_counter_increase(heap,stat,amount) mi_stat_counter_increase( (heap)->tld->stats.stat, amount)
+#define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount)
+#define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount)
+
+// ------------------------------------------------------
+// Thread Local data
+// ------------------------------------------------------
+
+// A "span" is an available range of slices. The span queues keep
+// track of slice spans of at most the given `slice_count` (but more than the previous size class).
+typedef struct mi_span_queue_s {
+ mi_slice_t* first;
+ mi_slice_t* last;
+ size_t slice_count;
+} mi_span_queue_t;
+
+#define MI_SEGMENT_BIN_MAX (35) // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT)
+
+// OS thread local data
+typedef struct mi_os_tld_s {
+ size_t region_idx; // start point for next allocation
+ mi_stats_t* stats; // points to tld stats
+} mi_os_tld_t;
+
+
+// Segments thread local data
+typedef struct mi_segments_tld_s {
+ mi_span_queue_t spans[MI_SEGMENT_BIN_MAX+1]; // free slice spans inside segments
+ size_t count; // current number of segments;
+ size_t peak_count; // peak number of segments
+ size_t current_size; // current size of all segments
+ size_t peak_size; // peak size of all segments
+ mi_stats_t* stats; // points to tld stats
+ mi_os_tld_t* os; // points to os stats
+ mi_abandoned_pool_t* abandoned; // pool of abandoned segments
+} mi_segments_tld_t;
+
+// Thread local data
+struct mi_tld_s {
+ unsigned long long heartbeat; // monotonic heartbeat count
+ bool recurse; // true if deferred was called; used to prevent infinite recursion.
+ mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted)
+ mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates)
+ mi_segments_tld_t segments; // segment tld
+ mi_os_tld_t os; // os tld
+ mi_stats_t stats; // statistics
+};
+
+#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_abstract.h b/contrib/tools/python3/Include/internal/pycore_abstract.h
index b1afb2dc7be..3cc0afac4bd 100644
--- a/contrib/tools/python3/Include/internal/pycore_abstract.h
+++ b/contrib/tools/python3/Include/internal/pycore_abstract.h
@@ -19,6 +19,42 @@ _PyIndex_Check(PyObject *obj)
PyObject *_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs);
PyObject *_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs);
+extern int _PyObject_HasLen(PyObject *o);
+
+/* === Sequence protocol ================================================ */
+
+#define PY_ITERSEARCH_COUNT 1
+#define PY_ITERSEARCH_INDEX 2
+#define PY_ITERSEARCH_CONTAINS 3
+
+/* Iterate over seq.
+
+ Result depends on the operation:
+
+ PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if
+ error.
+ PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of
+ obj in seq; set ValueError and return -1 if none found;
+ also return -1 on error.
+ PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on
+ error. */
+extern Py_ssize_t _PySequence_IterSearch(PyObject *seq,
+ PyObject *obj, int operation);
+
+/* === Mapping protocol ================================================= */
+
+extern int _PyObject_RealIsInstance(PyObject *inst, PyObject *cls);
+
+extern int _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
+
+// Convert Python int to Py_ssize_t. Do nothing if the argument is None.
+// Export for '_bisect' shared extension.
+PyAPI_FUNC(int) _Py_convert_optional_to_ssize_t(PyObject *, void *);
+
+// Same as PyNumber_Index() but can return an instance of a subclass of int.
+// Export for 'math' shared extension.
+PyAPI_FUNC(PyObject*) _PyNumber_Index(PyObject *o);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_ast.h b/contrib/tools/python3/Include/internal/pycore_ast.h
index b568902bb1e..f5bf1205a82 100644
--- a/contrib/tools/python3/Include/internal/pycore_ast.h
+++ b/contrib/tools/python3/Include/internal/pycore_ast.h
@@ -10,7 +10,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_asdl.h"
+#include "pycore_asdl.h" // _ASDL_SEQ_HEAD
typedef struct _mod *mod_ty;
@@ -657,14 +657,17 @@ struct _type_param {
struct {
identifier name;
expr_ty bound;
+ expr_ty default_value;
} TypeVar;
struct {
identifier name;
+ expr_ty default_value;
} ParamSpec;
struct {
identifier name;
+ expr_ty default_value;
} TypeVarTuple;
} v;
@@ -892,14 +895,15 @@ pattern_ty _PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int
col_offset, int end_lineno, int end_col_offset,
PyArena *arena);
type_ignore_ty _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena);
-type_param_ty _PyAST_TypeVar(identifier name, expr_ty bound, int lineno, int
- col_offset, int end_lineno, int end_col_offset,
- PyArena *arena);
-type_param_ty _PyAST_ParamSpec(identifier name, int lineno, int col_offset, int
- end_lineno, int end_col_offset, PyArena *arena);
-type_param_ty _PyAST_TypeVarTuple(identifier name, int lineno, int col_offset,
- int end_lineno, int end_col_offset, PyArena
- *arena);
+type_param_ty _PyAST_TypeVar(identifier name, expr_ty bound, expr_ty
+ default_value, int lineno, int col_offset, int
+ end_lineno, int end_col_offset, PyArena *arena);
+type_param_ty _PyAST_ParamSpec(identifier name, expr_ty default_value, int
+ lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena);
+type_param_ty _PyAST_TypeVarTuple(identifier name, expr_ty default_value, int
+ lineno, int col_offset, int end_lineno, int
+ end_col_offset, PyArena *arena);
PyObject* PyAST_mod2obj(mod_ty t);
diff --git a/contrib/tools/python3/Include/internal/pycore_ast_state.h b/contrib/tools/python3/Include/internal/pycore_ast_state.h
index 863c73b0d6e..09ae9546549 100644
--- a/contrib/tools/python3/Include/internal/pycore_ast_state.h
+++ b/contrib/tools/python3/Include/internal/pycore_ast_state.h
@@ -2,6 +2,9 @@
#ifndef Py_INTERNAL_AST_STATE_H
#define Py_INTERNAL_AST_STATE_H
+
+#include "pycore_lock.h" // _PyOnceFlag
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -11,9 +14,8 @@ extern "C" {
#endif
struct ast_state {
- int initialized;
- int unused_recursion_depth;
- int unused_recursion_limit;
+ _PyOnceFlag once;
+ int finalized;
PyObject *AST_type;
PyObject *Add_singleton;
PyObject *Add_type;
@@ -182,6 +184,7 @@ struct ast_state {
PyObject *conversion;
PyObject *ctx;
PyObject *decorator_list;
+ PyObject *default_value;
PyObject *defaults;
PyObject *elt;
PyObject *elts;
diff --git a/contrib/tools/python3/Include/internal/pycore_atexit.h b/contrib/tools/python3/Include/internal/pycore_atexit.h
index 63a2cd5d507..72c66a05939 100644
--- a/contrib/tools/python3/Include/internal/pycore_atexit.h
+++ b/contrib/tools/python3/Include/internal/pycore_atexit.h
@@ -1,5 +1,8 @@
#ifndef Py_INTERNAL_ATEXIT_H
#define Py_INTERNAL_ATEXIT_H
+
+#include "pycore_lock.h" // PyMutex
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -15,7 +18,7 @@ extern "C" {
typedef void (*atexit_callbackfunc)(void);
struct _atexit_runtime_state {
- PyThread_type_lock mutex;
+ PyMutex mutex;
#define NEXITFUNCS 32
atexit_callbackfunc callbacks[NEXITFUNCS];
int ncallbacks;
@@ -25,7 +28,8 @@ struct _atexit_runtime_state {
//###################
// interpreter atexit
-struct atexit_callback;
+typedef void (*atexit_datacallbackfunc)(void *);
+
typedef struct atexit_callback {
atexit_datacallbackfunc func;
void *data;
@@ -40,6 +44,7 @@ typedef struct {
struct atexit_state {
atexit_callback *ll_callbacks;
+ // Kept for ABI compatibility--do not use! (See GH-127791.)
atexit_callback *last_ll_callback;
// XXX The rest of the state could be moved to the atexit module state
@@ -50,6 +55,11 @@ struct atexit_state {
int callback_len;
};
+// Export for '_interpchannels' shared extension
+PyAPI_FUNC(int) _Py_AtExit(
+ PyInterpreterState *interp,
+ atexit_datacallbackfunc func,
+ void *data);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_atomic.h b/contrib/tools/python3/Include/internal/pycore_atomic.h
deleted file mode 100644
index 425d69f868b..00000000000
--- a/contrib/tools/python3/Include/internal/pycore_atomic.h
+++ /dev/null
@@ -1,557 +0,0 @@
-#ifndef Py_ATOMIC_H
-#define Py_ATOMIC_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef Py_BUILD_CORE
-# error "this header requires Py_BUILD_CORE define"
-#endif
-
-#include "dynamic_annotations.h" /* _Py_ANNOTATE_MEMORY_ORDER */
-#include "pyconfig.h"
-
-#ifdef HAVE_STD_ATOMIC
-# include <stdatomic.h>
-#endif
-
-
-#if defined(_MSC_VER)
-#include <intrin.h>
-#if defined(_M_IX86) || defined(_M_X64)
-# include <immintrin.h>
-#endif
-#endif
-
-/* This is modeled after the atomics interface from C1x, according to
- * the draft at
- * http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf.
- * Operations and types are named the same except with a _Py_ prefix
- * and have the same semantics.
- *
- * Beware, the implementations here are deep magic.
- */
-
-#if defined(HAVE_STD_ATOMIC)
-
-typedef enum _Py_memory_order {
- _Py_memory_order_relaxed = memory_order_relaxed,
- _Py_memory_order_acquire = memory_order_acquire,
- _Py_memory_order_release = memory_order_release,
- _Py_memory_order_acq_rel = memory_order_acq_rel,
- _Py_memory_order_seq_cst = memory_order_seq_cst
-} _Py_memory_order;
-
-typedef struct _Py_atomic_address {
- atomic_uintptr_t _value;
-} _Py_atomic_address;
-
-typedef struct _Py_atomic_int {
- atomic_int _value;
-} _Py_atomic_int;
-
-#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \
- atomic_signal_fence(ORDER)
-
-#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \
- atomic_thread_fence(ORDER)
-
-#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
- atomic_store_explicit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER)
-
-#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
- atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER)
-
-// Use builtin atomic operations in GCC >= 4.7 and clang
-#elif defined(HAVE_BUILTIN_ATOMIC)
-
-typedef enum _Py_memory_order {
- _Py_memory_order_relaxed = __ATOMIC_RELAXED,
- _Py_memory_order_acquire = __ATOMIC_ACQUIRE,
- _Py_memory_order_release = __ATOMIC_RELEASE,
- _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL,
- _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST
-} _Py_memory_order;
-
-typedef struct _Py_atomic_address {
- uintptr_t _value;
-} _Py_atomic_address;
-
-typedef struct _Py_atomic_int {
- int _value;
-} _Py_atomic_int;
-
-#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \
- __atomic_signal_fence(ORDER)
-
-#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \
- __atomic_thread_fence(ORDER)
-
-#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
- (assert((ORDER) == __ATOMIC_RELAXED \
- || (ORDER) == __ATOMIC_SEQ_CST \
- || (ORDER) == __ATOMIC_RELEASE), \
- __atomic_store_n(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER))
-
-#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
- (assert((ORDER) == __ATOMIC_RELAXED \
- || (ORDER) == __ATOMIC_SEQ_CST \
- || (ORDER) == __ATOMIC_ACQUIRE \
- || (ORDER) == __ATOMIC_CONSUME), \
- __atomic_load_n(&((ATOMIC_VAL)->_value), ORDER))
-
-/* Only support GCC (for expression statements) and x86 (for simple
- * atomic semantics) and MSVC x86/x64/ARM */
-#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64))
-typedef enum _Py_memory_order {
- _Py_memory_order_relaxed,
- _Py_memory_order_acquire,
- _Py_memory_order_release,
- _Py_memory_order_acq_rel,
- _Py_memory_order_seq_cst
-} _Py_memory_order;
-
-typedef struct _Py_atomic_address {
- uintptr_t _value;
-} _Py_atomic_address;
-
-typedef struct _Py_atomic_int {
- int _value;
-} _Py_atomic_int;
-
-
-static __inline__ void
-_Py_atomic_signal_fence(_Py_memory_order order)
-{
- if (order != _Py_memory_order_relaxed)
- __asm__ volatile("":::"memory");
-}
-
-static __inline__ void
-_Py_atomic_thread_fence(_Py_memory_order order)
-{
- if (order != _Py_memory_order_relaxed)
- __asm__ volatile("mfence":::"memory");
-}
-
-/* Tell the race checker about this operation's effects. */
-static __inline__ void
-_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order)
-{
- (void)address; /* shut up -Wunused-parameter */
- switch(order) {
- case _Py_memory_order_release:
- case _Py_memory_order_acq_rel:
- case _Py_memory_order_seq_cst:
- _Py_ANNOTATE_HAPPENS_BEFORE(address);
- break;
- case _Py_memory_order_relaxed:
- case _Py_memory_order_acquire:
- break;
- }
- switch(order) {
- case _Py_memory_order_acquire:
- case _Py_memory_order_acq_rel:
- case _Py_memory_order_seq_cst:
- _Py_ANNOTATE_HAPPENS_AFTER(address);
- break;
- case _Py_memory_order_relaxed:
- case _Py_memory_order_release:
- break;
- }
-}
-
-#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
- __extension__ ({ \
- __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \
- __typeof__(atomic_val->_value) new_val = NEW_VAL;\
- volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \
- _Py_memory_order order = ORDER; \
- _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \
- \
- /* Perform the operation. */ \
- _Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \
- switch(order) { \
- case _Py_memory_order_release: \
- _Py_atomic_signal_fence(_Py_memory_order_release); \
- /* fallthrough */ \
- case _Py_memory_order_relaxed: \
- *volatile_data = new_val; \
- break; \
- \
- case _Py_memory_order_acquire: \
- case _Py_memory_order_acq_rel: \
- case _Py_memory_order_seq_cst: \
- __asm__ volatile("xchg %0, %1" \
- : "+r"(new_val) \
- : "m"(atomic_val->_value) \
- : "memory"); \
- break; \
- } \
- _Py_ANNOTATE_IGNORE_WRITES_END(); \
- })
-
-#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
- __extension__ ({ \
- __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \
- __typeof__(atomic_val->_value) result; \
- volatile __typeof__(result) *volatile_data = &atomic_val->_value; \
- _Py_memory_order order = ORDER; \
- _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \
- \
- /* Perform the operation. */ \
- _Py_ANNOTATE_IGNORE_READS_BEGIN(); \
- switch(order) { \
- case _Py_memory_order_release: \
- case _Py_memory_order_acq_rel: \
- case _Py_memory_order_seq_cst: \
- /* Loads on x86 are not releases by default, so need a */ \
- /* thread fence. */ \
- _Py_atomic_thread_fence(_Py_memory_order_release); \
- break; \
- default: \
- /* No fence */ \
- break; \
- } \
- result = *volatile_data; \
- switch(order) { \
- case _Py_memory_order_acquire: \
- case _Py_memory_order_acq_rel: \
- case _Py_memory_order_seq_cst: \
- /* Loads on x86 are automatically acquire operations so */ \
- /* can get by with just a compiler fence. */ \
- _Py_atomic_signal_fence(_Py_memory_order_acquire); \
- break; \
- default: \
- /* No fence */ \
- break; \
- } \
- _Py_ANNOTATE_IGNORE_READS_END(); \
- result; \
- })
-
-#elif defined(_MSC_VER)
-/* _Interlocked* functions provide a full memory barrier and are therefore
- enough for acq_rel and seq_cst. If the HLE variants aren't available
- in hardware they will fall back to a full memory barrier as well.
-
- This might affect performance but likely only in some very specific and
- hard to measure scenario.
-*/
-#if defined(_M_IX86) || defined(_M_X64)
-typedef enum _Py_memory_order {
- _Py_memory_order_relaxed,
- _Py_memory_order_acquire,
- _Py_memory_order_release,
- _Py_memory_order_acq_rel,
- _Py_memory_order_seq_cst
-} _Py_memory_order;
-
-typedef struct _Py_atomic_address {
- volatile uintptr_t _value;
-} _Py_atomic_address;
-
-typedef struct _Py_atomic_int {
- volatile int _value;
-} _Py_atomic_int;
-
-
-#if defined(_M_X64)
-#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \
- switch (ORDER) { \
- case _Py_memory_order_acquire: \
- _InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
- break; \
- case _Py_memory_order_release: \
- _InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
- break; \
- default: \
- _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \
- break; \
- }
-#else
-#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0);
-#endif
-
-#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \
- switch (ORDER) { \
- case _Py_memory_order_acquire: \
- _InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
- break; \
- case _Py_memory_order_release: \
- _InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
- break; \
- default: \
- _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \
- break; \
- }
-
-#if defined(_M_X64)
-/* This has to be an intptr_t for now.
- gil_created() uses -1 as a sentinel value, if this returns
- a uintptr_t it will do an unsigned compare and crash
-*/
-inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) {
- __int64 old;
- switch (order) {
- case _Py_memory_order_acquire:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old);
- break;
- }
- case _Py_memory_order_release:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old);
- break;
- }
- case _Py_memory_order_relaxed:
- old = *value;
- break;
- default:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old);
- break;
- }
- }
- return old;
-}
-
-#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \
- _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER))
-
-#else
-#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value)
-#endif
-
-inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) {
- long old;
- switch (order) {
- case _Py_memory_order_acquire:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old);
- break;
- }
- case _Py_memory_order_release:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old);
- break;
- }
- case _Py_memory_order_relaxed:
- old = *value;
- break;
- default:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange((volatile long*)value, old, old) != old);
- break;
- }
- }
- return old;
-}
-
-#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \
- _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER))
-
-#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
- if (sizeof((ATOMIC_VAL)->_value) == 8) { \
- _Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \
- _Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) }
-
-#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
- ( \
- sizeof((ATOMIC_VAL)->_value) == 8 ? \
- _Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \
- _Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \
- )
-#elif defined(_M_ARM) || defined(_M_ARM64)
-typedef enum _Py_memory_order {
- _Py_memory_order_relaxed,
- _Py_memory_order_acquire,
- _Py_memory_order_release,
- _Py_memory_order_acq_rel,
- _Py_memory_order_seq_cst
-} _Py_memory_order;
-
-typedef struct _Py_atomic_address {
- volatile uintptr_t _value;
-} _Py_atomic_address;
-
-typedef struct _Py_atomic_int {
- volatile int _value;
-} _Py_atomic_int;
-
-
-#if defined(_M_ARM64)
-#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \
- switch (ORDER) { \
- case _Py_memory_order_acquire: \
- _InterlockedExchange64_acq((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
- break; \
- case _Py_memory_order_release: \
- _InterlockedExchange64_rel((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
- break; \
- default: \
- _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \
- break; \
- }
-#else
-#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0);
-#endif
-
-#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \
- switch (ORDER) { \
- case _Py_memory_order_acquire: \
- _InterlockedExchange_acq((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
- break; \
- case _Py_memory_order_release: \
- _InterlockedExchange_rel((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
- break; \
- default: \
- _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \
- break; \
- }
-
-#if defined(_M_ARM64)
-/* This has to be an intptr_t for now.
- gil_created() uses -1 as a sentinel value, if this returns
- a uintptr_t it will do an unsigned compare and crash
-*/
-inline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) {
- uintptr_t old;
- switch (order) {
- case _Py_memory_order_acquire:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange64_acq(value, old, old) != old);
- break;
- }
- case _Py_memory_order_release:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange64_rel(value, old, old) != old);
- break;
- }
- case _Py_memory_order_relaxed:
- old = *value;
- break;
- default:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange64(value, old, old) != old);
- break;
- }
- }
- return old;
-}
-
-#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \
- _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER))
-
-#else
-#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value)
-#endif
-
-inline int _Py_atomic_load_32bit_impl(volatile int* value, int order) {
- int old;
- switch (order) {
- case _Py_memory_order_acquire:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange_acq(value, old, old) != old);
- break;
- }
- case _Py_memory_order_release:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange_rel(value, old, old) != old);
- break;
- }
- case _Py_memory_order_relaxed:
- old = *value;
- break;
- default:
- {
- do {
- old = *value;
- } while(_InterlockedCompareExchange(value, old, old) != old);
- break;
- }
- }
- return old;
-}
-
-#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \
- _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER))
-
-#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
- if (sizeof((ATOMIC_VAL)->_value) == 8) { \
- _Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \
- _Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) }
-
-#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
- ( \
- sizeof((ATOMIC_VAL)->_value) == 8 ? \
- _Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \
- _Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \
- )
-#endif
-#else /* !gcc x86 !_msc_ver */
-typedef enum _Py_memory_order {
- _Py_memory_order_relaxed,
- _Py_memory_order_acquire,
- _Py_memory_order_release,
- _Py_memory_order_acq_rel,
- _Py_memory_order_seq_cst
-} _Py_memory_order;
-
-typedef struct _Py_atomic_address {
- uintptr_t _value;
-} _Py_atomic_address;
-
-typedef struct _Py_atomic_int {
- int _value;
-} _Py_atomic_int;
-/* Fall back to other compilers and processors by assuming that simple
- volatile accesses are atomic. This is false, so people should port
- this. */
-#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0)
-#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0)
-#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \
- ((ATOMIC_VAL)->_value = NEW_VAL)
-#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \
- ((ATOMIC_VAL)->_value)
-#endif
-
-/* Standardized shortcuts. */
-#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \
- _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst)
-#define _Py_atomic_load(ATOMIC_VAL) \
- _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst)
-
-/* Python-local extensions */
-
-#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \
- _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed)
-#define _Py_atomic_load_relaxed(ATOMIC_VAL) \
- _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed)
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* Py_ATOMIC_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_atomic_funcs.h b/contrib/tools/python3/Include/internal/pycore_atomic_funcs.h
deleted file mode 100644
index a708789cea7..00000000000
--- a/contrib/tools/python3/Include/internal/pycore_atomic_funcs.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Atomic functions: similar to pycore_atomic.h, but don't need
- to declare variables as atomic.
-
- Py_ssize_t type:
-
- * value = _Py_atomic_size_get(&var)
- * _Py_atomic_size_set(&var, value)
-
- Use sequentially-consistent ordering (__ATOMIC_SEQ_CST memory order):
- enforce total ordering with all other atomic functions.
-*/
-#ifndef Py_ATOMIC_FUNC_H
-#define Py_ATOMIC_FUNC_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef Py_BUILD_CORE
-# error "this header requires Py_BUILD_CORE define"
-#endif
-
-#if defined(_MSC_VER)
-# include <intrin.h> // _InterlockedExchange()
-#endif
-
-
-// Use builtin atomic operations in GCC >= 4.7 and clang
-#ifdef HAVE_BUILTIN_ATOMIC
-
-static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
-{
- return __atomic_load_n(var, __ATOMIC_SEQ_CST);
-}
-
-static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
-{
- __atomic_store_n(var, value, __ATOMIC_SEQ_CST);
-}
-
-#elif defined(_MSC_VER)
-
-static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
-{
-#if SIZEOF_VOID_P == 8
- Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));
- volatile __int64 *volatile_var = (volatile __int64 *)var;
- __int64 old;
- do {
- old = *volatile_var;
- } while(_InterlockedCompareExchange64(volatile_var, old, old) != old);
-#else
- Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));
- volatile long *volatile_var = (volatile long *)var;
- long old;
- do {
- old = *volatile_var;
- } while(_InterlockedCompareExchange(volatile_var, old, old) != old);
-#endif
- return old;
-}
-
-static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
-{
-#if SIZEOF_VOID_P == 8
- Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));
- volatile __int64 *volatile_var = (volatile __int64 *)var;
- _InterlockedExchange64(volatile_var, value);
-#else
- Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));
- volatile long *volatile_var = (volatile long *)var;
- _InterlockedExchange(volatile_var, value);
-#endif
-}
-
-#else
-// Fallback implementation using volatile
-
-static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)
-{
- volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;
- return *volatile_var;
-}
-
-static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)
-{
- volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;
- *volatile_var = value;
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* Py_ATOMIC_FUNC_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_backoff.h b/contrib/tools/python3/Include/internal/pycore_backoff.h
new file mode 100644
index 00000000000..0bcca1e769b
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_backoff.h
@@ -0,0 +1,145 @@
+
+#ifndef Py_INTERNAL_BACKOFF_H
+#define Py_INTERNAL_BACKOFF_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+
+typedef struct {
+ union {
+ struct {
+ uint16_t backoff : 4;
+ uint16_t value : 12;
+ };
+ uint16_t as_counter; // For printf("%#x", ...)
+ };
+} _Py_BackoffCounter;
+
+
+/* 16-bit countdown counters using exponential backoff.
+
+ These are used by the adaptive specializer to count down until
+ it is time to specialize an instruction. If specialization fails
+ the counter is reset using exponential backoff.
+
+ Another use is for the Tier 2 optimizer to decide when to create
+ a new Tier 2 trace (executor). Again, exponential backoff is used.
+
+ The 16-bit counter is structured as a 12-bit unsigned 'value'
+ and a 4-bit 'backoff' field. When resetting the counter, the
+ backoff field is incremented (until it reaches a limit) and the
+ value is set to a bit mask representing the value 2**backoff - 1.
+ The maximum backoff is 12 (the number of value bits).
+
+ There is an exceptional value which must not be updated, 0xFFFF.
+*/
+
+#define UNREACHABLE_BACKOFF 0xFFFF
+
+static inline bool
+is_unreachable_backoff_counter(_Py_BackoffCounter counter)
+{
+ return counter.as_counter == UNREACHABLE_BACKOFF;
+}
+
+static inline _Py_BackoffCounter
+make_backoff_counter(uint16_t value, uint16_t backoff)
+{
+ assert(backoff <= 15);
+ assert(value <= 0xFFF);
+ _Py_BackoffCounter result;
+ result.value = value;
+ result.backoff = backoff;
+ return result;
+}
+
+static inline _Py_BackoffCounter
+forge_backoff_counter(uint16_t counter)
+{
+ _Py_BackoffCounter result;
+ result.as_counter = counter;
+ return result;
+}
+
+static inline _Py_BackoffCounter
+restart_backoff_counter(_Py_BackoffCounter counter)
+{
+ assert(!is_unreachable_backoff_counter(counter));
+ if (counter.backoff < 12) {
+ return make_backoff_counter((1 << (counter.backoff + 1)) - 1, counter.backoff + 1);
+ }
+ else {
+ return make_backoff_counter((1 << 12) - 1, 12);
+ }
+}
+
+static inline _Py_BackoffCounter
+pause_backoff_counter(_Py_BackoffCounter counter)
+{
+ return make_backoff_counter(counter.value | 1, counter.backoff);
+}
+
+static inline _Py_BackoffCounter
+advance_backoff_counter(_Py_BackoffCounter counter)
+{
+ if (!is_unreachable_backoff_counter(counter)) {
+ return make_backoff_counter((counter.value - 1) & 0xFFF, counter.backoff);
+ }
+ else {
+ return counter;
+ }
+}
+
+static inline bool
+backoff_counter_triggers(_Py_BackoffCounter counter)
+{
+ return counter.value == 0;
+}
+
+/* Initial JUMP_BACKWARD counter.
+ * This determines when we create a trace for a loop.
+* Backoff sequence 16, 32, 64, 128, 256, 512, 1024, 2048, 4096. */
+#define JUMP_BACKWARD_INITIAL_VALUE 16
+#define JUMP_BACKWARD_INITIAL_BACKOFF 4
+static inline _Py_BackoffCounter
+initial_jump_backoff_counter(void)
+{
+ return make_backoff_counter(JUMP_BACKWARD_INITIAL_VALUE,
+ JUMP_BACKWARD_INITIAL_BACKOFF);
+}
+
+/* Initial exit temperature.
+ * Must be larger than ADAPTIVE_COOLDOWN_VALUE,
+ * otherwise when a side exit warms up we may construct
+ * a new trace before the Tier 1 code has properly re-specialized.
+ * Backoff sequence 64, 128, 256, 512, 1024, 2048, 4096. */
+#define COLD_EXIT_INITIAL_VALUE 64
+#define COLD_EXIT_INITIAL_BACKOFF 6
+
+static inline _Py_BackoffCounter
+initial_temperature_backoff_counter(void)
+{
+ return make_backoff_counter(COLD_EXIT_INITIAL_VALUE,
+ COLD_EXIT_INITIAL_BACKOFF);
+}
+
+/* Unreachable backoff counter. */
+static inline _Py_BackoffCounter
+initial_unreachable_backoff_counter(void)
+{
+ return forge_backoff_counter(UNREACHABLE_BACKOFF);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_BACKOFF_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_bitutils.h b/contrib/tools/python3/Include/internal/pycore_bitutils.h
index e6bf61ef425..50f69377523 100644
--- a/contrib/tools/python3/Include/internal/pycore_bitutils.h
+++ b/contrib/tools/python3/Include/internal/pycore_bitutils.h
@@ -26,10 +26,10 @@ extern "C" {
#endif
#ifdef _MSC_VER
- /* Get _byteswap_ushort(), _byteswap_ulong(), _byteswap_uint64() */
-# include <intrin.h>
+# include <intrin.h> // _byteswap_uint64()
#endif
+
static inline uint16_t
_Py_bswap16(uint16_t word)
{
diff --git a/contrib/tools/python3/Include/internal/pycore_blocks_output_buffer.h b/contrib/tools/python3/Include/internal/pycore_blocks_output_buffer.h
index 28cf6fba4ee..573e10359b7 100644
--- a/contrib/tools/python3/Include/internal/pycore_blocks_output_buffer.h
+++ b/contrib/tools/python3/Include/internal/pycore_blocks_output_buffer.h
@@ -40,6 +40,10 @@ extern "C" {
#include "Python.h"
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
typedef struct {
// List of bytes objects
PyObject *list;
@@ -314,4 +318,4 @@ _BlocksOutputBuffer_OnError(_BlocksOutputBuffer *buffer)
#ifdef __cplusplus
}
#endif
-#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */ \ No newline at end of file
+#endif /* Py_INTERNAL_BLOCKS_OUTPUT_BUFFER_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_brc.h b/contrib/tools/python3/Include/internal/pycore_brc.h
new file mode 100644
index 00000000000..3453d83b57c
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_brc.h
@@ -0,0 +1,74 @@
+#ifndef Py_INTERNAL_BRC_H
+#define Py_INTERNAL_BRC_H
+
+#include <stdint.h>
+#include "pycore_llist.h" // struct llist_node
+#include "pycore_lock.h" // PyMutex
+#include "pycore_object_stack.h" // _PyObjectStack
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#ifdef Py_GIL_DISABLED
+
+// Prime number to avoid correlations with memory addresses.
+#define _Py_BRC_NUM_BUCKETS 257
+
+// Hash table bucket
+struct _brc_bucket {
+ // Mutex protects both the bucket and thread state queues in this bucket.
+ PyMutex mutex;
+
+ // Linked list of _PyThreadStateImpl objects hashed to this bucket.
+ struct llist_node root;
+};
+
+// Per-interpreter biased reference counting state
+struct _brc_state {
+ // Hash table of thread states by thread-id. Thread states within a bucket
+ // are chained using a doubly-linked list.
+ struct _brc_bucket table[_Py_BRC_NUM_BUCKETS];
+};
+
+// Per-thread biased reference counting state
+struct _brc_thread_state {
+ // Linked-list of thread states per hash bucket
+ struct llist_node bucket_node;
+
+ // Thread-id as determined by _PyThread_Id()
+ uintptr_t tid;
+
+ // Objects with refcounts to be merged (protected by bucket mutex)
+ _PyObjectStack objects_to_merge;
+
+ // Local stack of objects to be merged (not accessed by other threads)
+ _PyObjectStack local_objects_to_merge;
+};
+
+// Initialize/finalize the per-thread biased reference counting state
+void _Py_brc_init_thread(PyThreadState *tstate);
+void _Py_brc_remove_thread(PyThreadState *tstate);
+
+// Initialize per-interpreter state
+void _Py_brc_init_state(PyInterpreterState *interp);
+
+void _Py_brc_after_fork(PyInterpreterState *interp);
+
+// Enqueues an object to be merged by it's owning thread (tid). This
+// steals a reference to the object.
+void _Py_brc_queue_object(PyObject *ob);
+
+// Merge the refcounts of queued objects for the current thread.
+void _Py_brc_merge_refcounts(PyThreadState *tstate);
+
+#endif /* Py_GIL_DISABLED */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_BRC_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_bytes_methods.h b/contrib/tools/python3/Include/internal/pycore_bytes_methods.h
index 11e8ab20e91..059dc2599bb 100644
--- a/contrib/tools/python3/Include/internal/pycore_bytes_methods.h
+++ b/contrib/tools/python3/Include/internal/pycore_bytes_methods.h
@@ -26,14 +26,23 @@ extern void _Py_bytes_title(char *result, const char *s, Py_ssize_t len);
extern void _Py_bytes_capitalize(char *result, const char *s, Py_ssize_t len);
extern void _Py_bytes_swapcase(char *result, const char *s, Py_ssize_t len);
-extern PyObject *_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *args);
-extern PyObject *_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *args);
-extern PyObject *_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *args);
-extern PyObject *_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *args);
-extern PyObject *_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *args);
+extern PyObject *_Py_bytes_find(const char *str, Py_ssize_t len, PyObject *sub,
+ Py_ssize_t start, Py_ssize_t end);
+extern PyObject *_Py_bytes_index(const char *str, Py_ssize_t len, PyObject *sub,
+ Py_ssize_t start, Py_ssize_t end);
+extern PyObject *_Py_bytes_rfind(const char *str, Py_ssize_t len, PyObject *sub,
+ Py_ssize_t start, Py_ssize_t end);
+extern PyObject *_Py_bytes_rindex(const char *str, Py_ssize_t len, PyObject *sub,
+ Py_ssize_t start, Py_ssize_t end);
+extern PyObject *_Py_bytes_count(const char *str, Py_ssize_t len, PyObject *sub,
+ Py_ssize_t start, Py_ssize_t end);
extern int _Py_bytes_contains(const char *str, Py_ssize_t len, PyObject *arg);
-extern PyObject *_Py_bytes_startswith(const char *str, Py_ssize_t len, PyObject *args);
-extern PyObject *_Py_bytes_endswith(const char *str, Py_ssize_t len, PyObject *args);
+extern PyObject *_Py_bytes_startswith(const char *str, Py_ssize_t len,
+ PyObject *subobj, Py_ssize_t start,
+ Py_ssize_t end);
+extern PyObject *_Py_bytes_endswith(const char *str, Py_ssize_t len,
+ PyObject *subobj, Py_ssize_t start,
+ Py_ssize_t end);
/* The maketrans() static method. */
extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to);
diff --git a/contrib/tools/python3/Include/internal/pycore_bytesobject.h b/contrib/tools/python3/Include/internal/pycore_bytesobject.h
index d36fa9569d6..8c922a4fb30 100644
--- a/contrib/tools/python3/Include/internal/pycore_bytesobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_bytesobject.h
@@ -8,39 +8,144 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+extern PyObject* _PyBytes_FormatEx(
+ const char *format,
+ Py_ssize_t format_len,
+ PyObject *args,
+ int use_bytearray);
-/* Substring Search.
+extern PyObject* _PyBytes_FromHex(
+ PyObject *string,
+ int use_bytearray);
- Returns the index of the first occurrence of
- a substring ("needle") in a larger text ("haystack").
- If the needle is not found, return -1.
- If the needle is found, add offset to the index.
-*/
+// Helper for PyBytes_DecodeEscape that detects invalid escape chars.
+// Export for test_peg_generator.
+PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape2(const char *, Py_ssize_t,
+ const char *,
+ int *, const char **);
+// Export for binary compatibility.
+PyAPI_FUNC(PyObject*) _PyBytes_DecodeEscape(const char *, Py_ssize_t,
+ const char *, const char **);
+
+// Substring Search.
+//
+// Returns the index of the first occurrence of
+// a substring ("needle") in a larger text ("haystack").
+// If the needle is not found, return -1.
+// If the needle is found, add offset to the index.
+//
+// Export for 'mmap' shared extension.
PyAPI_FUNC(Py_ssize_t)
_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack,
const char *needle, Py_ssize_t len_needle,
Py_ssize_t offset);
-/* Same as above, but search right-to-left */
+// Same as above, but search right-to-left.
+// Export for 'mmap' shared extension.
PyAPI_FUNC(Py_ssize_t)
_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack,
const char *needle, Py_ssize_t len_needle,
Py_ssize_t offset);
-/** Helper function to implement the repeat and inplace repeat methods on a buffer
- *
- * len_dest is assumed to be an integer multiple of len_src.
- * If src equals dest, then assume the operation is inplace.
- *
- * This method repeately doubles the number of bytes copied to reduce
- * the number of invocations of memcpy.
- */
+// Helper function to implement the repeat and inplace repeat methods on a
+// buffer.
+//
+// len_dest is assumed to be an integer multiple of len_src.
+// If src equals dest, then assume the operation is inplace.
+//
+// This method repeately doubles the number of bytes copied to reduce
+// the number of invocations of memcpy.
+//
+// Export for 'array' shared extension.
PyAPI_FUNC(void)
_PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
const char* src, Py_ssize_t len_src);
+/* --- _PyBytesWriter ----------------------------------------------------- */
+
+/* The _PyBytesWriter structure is big: it contains an embedded "stack buffer".
+ A _PyBytesWriter variable must be declared at the end of variables in a
+ function to optimize the memory allocation on the stack. */
+typedef struct {
+ /* bytes, bytearray or NULL (when the small buffer is used) */
+ PyObject *buffer;
+
+ /* Number of allocated size. */
+ Py_ssize_t allocated;
+
+ /* Minimum number of allocated bytes,
+ incremented by _PyBytesWriter_Prepare() */
+ Py_ssize_t min_size;
+
+ /* If non-zero, use a bytearray instead of a bytes object for buffer. */
+ int use_bytearray;
+
+ /* If non-zero, overallocate the buffer (default: 0).
+ This flag must be zero if use_bytearray is non-zero. */
+ int overallocate;
+
+ /* Stack buffer */
+ int use_small_buffer;
+ char small_buffer[512];
+} _PyBytesWriter;
+
+/* Initialize a bytes writer
+
+ By default, the overallocation is disabled. Set the overallocate attribute
+ to control the allocation of the buffer.
+
+ Export _PyBytesWriter API for '_pickle' shared extension. */
+PyAPI_FUNC(void) _PyBytesWriter_Init(_PyBytesWriter *writer);
+
+/* Get the buffer content and reset the writer.
+ Return a bytes object, or a bytearray object if use_bytearray is non-zero.
+ Raise an exception and return NULL on error. */
+PyAPI_FUNC(PyObject *) _PyBytesWriter_Finish(_PyBytesWriter *writer,
+ void *str);
+
+/* Deallocate memory of a writer (clear its internal buffer). */
+PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer);
+
+/* Allocate the buffer to write size bytes.
+ Return the pointer to the beginning of buffer data.
+ Raise an exception and return NULL on error. */
+PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer,
+ Py_ssize_t size);
+
+/* Ensure that the buffer is large enough to write *size* bytes.
+ Add size to the writer minimum size (min_size attribute).
+
+ str is the current pointer inside the buffer.
+ Return the updated current pointer inside the buffer.
+ Raise an exception and return NULL on error. */
+PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer,
+ void *str,
+ Py_ssize_t size);
+
+/* Resize the buffer to make it larger.
+ The new buffer may be larger than size bytes because of overallocation.
+ Return the updated current pointer inside the buffer.
+ Raise an exception and return NULL on error.
+
+ Note: size must be greater than the number of allocated bytes in the writer.
+
+ This function doesn't use the writer minimum size (min_size attribute).
+
+ See also _PyBytesWriter_Prepare().
+ */
+PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer,
+ void *str,
+ Py_ssize_t size);
+
+/* Write bytes.
+ Raise an exception and return NULL on error. */
+PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer,
+ void *str,
+ const void *bytes,
+ Py_ssize_t size);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_call.h b/contrib/tools/python3/Include/internal/pycore_call.h
index 5d9342b562b..c92028a0129 100644
--- a/contrib/tools/python3/Include/internal/pycore_call.h
+++ b/contrib/tools/python3/Include/internal/pycore_call.h
@@ -8,31 +8,107 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_identifier.h" // _Py_Identifier
#include "pycore_pystate.h" // _PyThreadState_GET()
-PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
+/* Suggested size (number of positional arguments) for arrays of PyObject*
+ allocated on a C stack to avoid allocating memory on the heap memory. Such
+ array is used to pass positional arguments to call functions of the
+ PyObject_Vectorcall() family.
+
+ The size is chosen to not abuse the C stack and so limit the risk of stack
+ overflow. The size is also chosen to allow using the small stack for most
+ function calls of the Python standard library. On 64-bit CPU, it allocates
+ 40 bytes on the stack. */
+#define _PY_FASTCALL_SMALL_STACK 5
+
+
+// Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
+// static inline function.
+PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult(
+ PyThreadState *tstate,
+ PyObject *callable,
+ PyObject *result,
+ const char *where);
+
+extern PyObject* _PyObject_Call_Prepend(
PyThreadState *tstate,
PyObject *callable,
PyObject *obj,
PyObject *args,
PyObject *kwargs);
-PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate(
+extern PyObject* _PyObject_VectorcallDictTstate(
PyThreadState *tstate,
PyObject *callable,
PyObject *const *args,
size_t nargsf,
PyObject *kwargs);
-PyAPI_FUNC(PyObject *) _PyObject_Call(
+extern PyObject* _PyObject_Call(
PyThreadState *tstate,
PyObject *callable,
PyObject *args,
PyObject *kwargs);
extern PyObject * _PyObject_CallMethodFormat(
- PyThreadState *tstate, PyObject *callable, const char *format, ...);
+ PyThreadState *tstate,
+ PyObject *callable,
+ const char *format,
+ ...);
+
+// Export for 'array' shared extension
+PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
+ PyObject *obj,
+ PyObject *name,
+ const char *format, ...);
+
+extern PyObject* _PyObject_CallMethodIdObjArgs(
+ PyObject *obj,
+ _Py_Identifier *name,
+ ...);
+
+static inline PyObject *
+_PyObject_VectorcallMethodId(
+ _Py_Identifier *name, PyObject *const *args,
+ size_t nargsf, PyObject *kwnames)
+{
+ PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
+ if (!oname) {
+ return _Py_NULL;
+ }
+ return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
+}
+
+static inline PyObject *
+_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
+{
+ size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
+ return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
+}
+
+static inline PyObject *
+_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
+{
+ PyObject *args[2] = {self, arg};
+ size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
+ assert(arg != NULL);
+ return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
+}
+
+
+/* === Vectorcall protocol (PEP 590) ============================= */
+// Call callable using tp_call. Arguments are like PyObject_Vectorcall(),
+// except that nargs is plainly the number of arguments without flags.
+//
+// Export for 'math' shared extension, used via _PyObject_VectorcallTstate()
+// static inline function.
+PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall(
+ PyThreadState *tstate,
+ PyObject *callable,
+ PyObject *const *args, Py_ssize_t nargs,
+ PyObject *keywords);
// Static inline variant of public PyVectorcall_Function().
static inline vectorcallfunc
@@ -109,23 +185,19 @@ _PyObject_CallNoArgs(PyObject *func) {
}
-static inline PyObject *
-_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
-{
- EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
- return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
-}
-
-PyObject *const *
+extern PyObject *const *
_PyStack_UnpackDict(PyThreadState *tstate,
PyObject *const *args, Py_ssize_t nargs,
PyObject *kwargs, PyObject **p_kwnames);
-void
-_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs,
+extern void _PyStack_UnpackDict_Free(
+ PyObject *const *stack,
+ Py_ssize_t nargs,
PyObject *kwnames);
-void _PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames);
+extern void _PyStack_UnpackDict_FreeNoDecRef(
+ PyObject *const *stack,
+ PyObject *kwnames);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_capsule.h b/contrib/tools/python3/Include/internal/pycore_capsule.h
new file mode 100644
index 00000000000..aa2c67f3a8f
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_capsule.h
@@ -0,0 +1,17 @@
+#ifndef Py_INTERNAL_PYCAPSULE_H
+#define Py_INTERNAL_PYCAPSULE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+// Export for '_socket' shared extension
+PyAPI_FUNC(int) _PyCapsule_SetTraverse(PyObject *op, traverseproc traverse_func, inquiry clear_func);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_PYCAPSULE_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_cell.h b/contrib/tools/python3/Include/internal/pycore_cell.h
new file mode 100644
index 00000000000..27f67d57b2f
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_cell.h
@@ -0,0 +1,48 @@
+#ifndef Py_INTERNAL_CELL_H
+#define Py_INTERNAL_CELL_H
+
+#include "pycore_critical_section.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+// Sets the cell contents to `value` and return previous contents. Steals a
+// reference to `value`.
+static inline PyObject *
+PyCell_SwapTakeRef(PyCellObject *cell, PyObject *value)
+{
+ PyObject *old_value;
+ Py_BEGIN_CRITICAL_SECTION(cell);
+ old_value = cell->ob_ref;
+ cell->ob_ref = value;
+ Py_END_CRITICAL_SECTION();
+ return old_value;
+}
+
+static inline void
+PyCell_SetTakeRef(PyCellObject *cell, PyObject *value)
+{
+ PyObject *old_value = PyCell_SwapTakeRef(cell, value);
+ Py_XDECREF(old_value);
+}
+
+// Gets the cell contents. Returns a new reference.
+static inline PyObject *
+PyCell_GetRef(PyCellObject *cell)
+{
+ PyObject *res;
+ Py_BEGIN_CRITICAL_SECTION(cell);
+ res = Py_XNewRef(cell->ob_ref);
+ Py_END_CRITICAL_SECTION();
+ return res;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_CELL_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_ceval.h b/contrib/tools/python3/Include/internal/pycore_ceval.h
index 921b1cfcd3a..f804823cc53 100644
--- a/contrib/tools/python3/Include/internal/pycore_ceval.h
+++ b/contrib/tools/python3/Include/internal/pycore_ceval.h
@@ -8,28 +8,59 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "dynamic_annotations.h" // _Py_ANNOTATE_RWLOCK_CREATE
+
+#include "pycore_interp.h" // PyInterpreterState.eval_frame
+#include "pycore_pystate.h" // _PyThreadState_GET()
+
/* Forward declarations */
struct pyruntimestate;
struct _ceval_runtime_state;
+// Export for '_lsprof' shared extension
+PyAPI_FUNC(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
+extern int _PyEval_SetProfileAllThreads(PyInterpreterState *interp, Py_tracefunc func, PyObject *arg);
+
+extern int _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg);
+extern int _PyEval_SetTraceAllThreads(PyInterpreterState *interp, Py_tracefunc func, PyObject *arg);
+
+extern int _PyEval_SetOpcodeTrace(PyFrameObject *f, bool enable);
+
+// Helper to look up a builtin object
+// Export for 'array' shared extension
+PyAPI_FUNC(PyObject*) _PyEval_GetBuiltin(PyObject *);
+
+extern PyObject* _PyEval_GetBuiltinId(_Py_Identifier *);
+
+extern void _PyEval_SetSwitchInterval(unsigned long microseconds);
+extern unsigned long _PyEval_GetSwitchInterval(void);
+
+// Export for '_queue' shared extension
+PyAPI_FUNC(int) _PyEval_MakePendingCalls(PyThreadState *);
+
#ifndef Py_DEFAULT_RECURSION_LIMIT
# define Py_DEFAULT_RECURSION_LIMIT 1000
#endif
-#include "pycore_interp.h" // PyInterpreterState.eval_frame
-#include "pycore_pystate.h" // _PyThreadState_GET()
+extern void _Py_FinishPendingCalls(PyThreadState *tstate);
+extern void _PyEval_InitState(PyInterpreterState *);
+extern void _PyEval_SignalReceived(void);
+// bitwise flags:
+#define _Py_PENDING_MAINTHREADONLY 1
+#define _Py_PENDING_RAWFREE 2
-extern void _Py_FinishPendingCalls(PyThreadState *tstate);
-extern void _PyEval_InitState(PyInterpreterState *, PyThread_type_lock);
-extern void _PyEval_FiniState(struct _ceval_state *ceval);
-PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp);
-PyAPI_FUNC(int) _PyEval_AddPendingCall(
+typedef int _Py_add_pending_call_result;
+#define _Py_ADD_PENDING_SUCCESS 0
+#define _Py_ADD_PENDING_FULL -1
+
+// Export for '_testinternalcapi' shared extension
+PyAPI_FUNC(_Py_add_pending_call_result) _PyEval_AddPendingCall(
PyInterpreterState *interp,
- int (*func)(void *),
+ _Py_pending_call_func func,
void *arg,
- int mainthreadonly);
-PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp);
+ int flags);
+
#ifdef HAVE_FORK
extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate);
#endif
@@ -79,6 +110,7 @@ extern int _PyIsPerfTrampolineActive(void);
extern PyStatus _PyPerfTrampoline_AfterFork_Child(void);
#ifdef PY_HAVE_PERF_TRAMPOLINE
extern _PyPerf_Callbacks _Py_perfmap_callbacks;
+extern _PyPerf_Callbacks _Py_perfmap_jit_callbacks;
#endif
static inline PyObject*
@@ -98,12 +130,56 @@ _PyEval_Vector(PyThreadState *tstate,
PyObject *kwnames);
extern int _PyEval_ThreadsInitialized(void);
-extern PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil);
+extern void _PyEval_InitGIL(PyThreadState *tstate, int own_gil);
extern void _PyEval_FiniGIL(PyInterpreterState *interp);
extern void _PyEval_AcquireLock(PyThreadState *tstate);
-extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *);
-extern PyThreadState * _PyThreadState_SwapNoGIL(PyThreadState *);
+
+extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *,
+ int final_release);
+
+#ifdef Py_GIL_DISABLED
+// Returns 0 or 1 if the GIL for the given thread's interpreter is disabled or
+// enabled, respectively.
+//
+// The enabled state of the GIL will not change while one or more threads are
+// attached.
+static inline int
+_PyEval_IsGILEnabled(PyThreadState *tstate)
+{
+ struct _gil_runtime_state *gil = tstate->interp->ceval.gil;
+ return _Py_atomic_load_int_relaxed(&gil->enabled) != 0;
+}
+
+// Enable or disable the GIL used by the interpreter that owns tstate, which
+// must be the current thread. This may affect other interpreters, if the GIL
+// is shared. All three functions will be no-ops (and return 0) if the
+// interpreter's `enable_gil' config is not _PyConfig_GIL_DEFAULT.
+//
+// Every call to _PyEval_EnableGILTransient() must be paired with exactly one
+// call to either _PyEval_EnableGILPermanent() or
+// _PyEval_DisableGIL(). _PyEval_EnableGILPermanent() and _PyEval_DisableGIL()
+// must only be called while the GIL is enabled from a call to
+// _PyEval_EnableGILTransient().
+//
+// _PyEval_EnableGILTransient() returns 1 if it enabled the GIL, or 0 if the
+// GIL was already enabled, whether transiently or permanently. The caller will
+// hold the GIL upon return.
+//
+// _PyEval_EnableGILPermanent() returns 1 if it permanently enabled the GIL
+// (which must already be enabled), or 0 if it was already permanently
+// enabled. Once _PyEval_EnableGILPermanent() has been called once, all
+// subsequent calls to any of the three functions will be no-ops.
+//
+// _PyEval_DisableGIL() returns 1 if it disabled the GIL, or 0 if the GIL was
+// kept enabled because of another request, whether transient or permanent.
+//
+// All three functions must be called by an attached thread (this implies that
+// if the GIL is enabled, the current thread must hold it).
+extern int _PyEval_EnableGILTransient(PyThreadState *tstate);
+extern int _PyEval_EnableGILPermanent(PyThreadState *tstate);
+extern int _PyEval_DisableGIL(PyThreadState *state);
+#endif
extern void _PyEval_DeactivateOpCache(void);
@@ -114,15 +190,17 @@ extern void _PyEval_DeactivateOpCache(void);
/* With USE_STACKCHECK macro defined, trigger stack checks in
_Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
- return (tstate->c_recursion_remaining-- <= 0
+ return (tstate->c_recursion_remaining-- < 0
|| (tstate->c_recursion_remaining & 63) == 0);
}
#else
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
- return tstate->c_recursion_remaining-- <= 0;
+ return tstate->c_recursion_remaining-- < 0;
}
#endif
+// Export for '_json' shared extension, used via _Py_EnterRecursiveCall()
+// static inline function.
PyAPI_FUNC(int) _Py_CheckRecursiveCall(
PyThreadState *tstate,
const char *where);
@@ -135,6 +213,11 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
}
+static inline void _Py_EnterRecursiveCallTstateUnchecked(PyThreadState *tstate) {
+ assert(tstate->c_recursion_remaining > 0);
+ tstate->c_recursion_remaining--;
+}
+
static inline int _Py_EnterRecursiveCall(const char *where) {
PyThreadState *tstate = _PyThreadState_GET();
return _Py_EnterRecursiveCallTstate(tstate, where);
@@ -151,12 +234,70 @@ static inline void _Py_LeaveRecursiveCall(void) {
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
-extern PyObject* _Py_MakeCoro(PyFunctionObject *func);
+PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func);
-extern int _Py_HandlePending(PyThreadState *tstate);
+/* Handle signals, pending calls, GIL drop request
+ and asynchronous exception */
+PyAPI_FUNC(int) _Py_HandlePending(PyThreadState *tstate);
extern PyObject * _PyEval_GetFrameLocals(void);
+typedef PyObject *(*conversion_func)(PyObject *);
+
+PyAPI_DATA(const binaryfunc) _PyEval_BinaryOps[];
+PyAPI_DATA(const conversion_func) _PyEval_ConversionFuncs[];
+
+PyAPI_FUNC(int) _PyEval_CheckExceptStarTypeValid(PyThreadState *tstate, PyObject* right);
+PyAPI_FUNC(int) _PyEval_CheckExceptTypeValid(PyThreadState *tstate, PyObject* right);
+PyAPI_FUNC(int) _PyEval_ExceptionGroupMatch(PyObject* exc_value, PyObject *match_type, PyObject **match, PyObject **rest);
+PyAPI_FUNC(void) _PyEval_FormatAwaitableError(PyThreadState *tstate, PyTypeObject *type, int oparg);
+PyAPI_FUNC(void) _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, const char *format_str, PyObject *obj);
+PyAPI_FUNC(void) _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg);
+PyAPI_FUNC(void) _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs);
+PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs);
+PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys);
+PyAPI_FUNC(int) _PyEval_UnpackIterable(PyThreadState *tstate, PyObject *v, int argcnt, int argcntafter, PyObject **sp);
+PyAPI_FUNC(void) _PyEval_MonitorRaise(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *instr);
+PyAPI_FUNC(void) _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame);
+
+
+/* Bits that can be set in PyThreadState.eval_breaker */
+#define _PY_GIL_DROP_REQUEST_BIT (1U << 0)
+#define _PY_SIGNALS_PENDING_BIT (1U << 1)
+#define _PY_CALLS_TO_DO_BIT (1U << 2)
+#define _PY_ASYNC_EXCEPTION_BIT (1U << 3)
+#define _PY_GC_SCHEDULED_BIT (1U << 4)
+#define _PY_EVAL_PLEASE_STOP_BIT (1U << 5)
+#define _PY_EVAL_EXPLICIT_MERGE_BIT (1U << 6)
+
+/* Reserve a few bits for future use */
+#define _PY_EVAL_EVENTS_BITS 8
+#define _PY_EVAL_EVENTS_MASK ((1 << _PY_EVAL_EVENTS_BITS)-1)
+
+static inline void
+_Py_set_eval_breaker_bit(PyThreadState *tstate, uintptr_t bit)
+{
+ _Py_atomic_or_uintptr(&tstate->eval_breaker, bit);
+}
+
+static inline void
+_Py_unset_eval_breaker_bit(PyThreadState *tstate, uintptr_t bit)
+{
+ _Py_atomic_and_uintptr(&tstate->eval_breaker, ~bit);
+}
+
+static inline int
+_Py_eval_breaker_bit_is_set(PyThreadState *tstate, uintptr_t bit)
+{
+ uintptr_t b = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker);
+ return (b & bit) != 0;
+}
+
+// Free-threaded builds use these functions to set or unset a bit on all
+// threads in the given interpreter.
+void _Py_set_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
+void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
+
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_ceval_state.h b/contrib/tools/python3/Include/internal/pycore_ceval_state.h
index e56e43c6e0c..009a1ea41eb 100644
--- a/contrib/tools/python3/Include/internal/pycore_ceval_state.h
+++ b/contrib/tools/python3/Include/internal/pycore_ceval_state.h
@@ -8,36 +8,64 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-
-#include "pycore_atomic.h" /* _Py_atomic_address */
+#include "pycore_lock.h" // PyMutex
#include "pycore_gil.h" // struct _gil_runtime_state
+typedef int (*_Py_pending_call_func)(void *);
+
+struct _pending_call {
+ _Py_pending_call_func func;
+ void *arg;
+ int flags;
+};
+
+#define PENDINGCALLSARRAYSIZE 300
+
+#define MAXPENDINGCALLS PENDINGCALLSARRAYSIZE
+/* For interpreter-level pending calls, we want to avoid spending too
+ much time on pending calls in any one thread, so we apply a limit. */
+#if MAXPENDINGCALLS > 100
+# define MAXPENDINGCALLSLOOP 100
+#else
+# define MAXPENDINGCALLSLOOP MAXPENDINGCALLS
+#endif
+
+/* We keep the number small to preserve as much compatibility
+ as possible with earlier versions. */
+#define MAXPENDINGCALLS_MAIN 32
+/* For the main thread, we want to make sure all pending calls are
+ run at once, for the sake of prompt signal handling. This is
+ unlikely to cause any problems since there should be very few
+ pending calls for the main thread. */
+#define MAXPENDINGCALLSLOOP_MAIN 0
+
struct _pending_calls {
- int busy;
- PyThread_type_lock lock;
+ PyThreadState *handling_thread;
+ PyMutex mutex;
/* Request for running pending calls. */
- _Py_atomic_int calls_to_do;
- /* Request for looking at the `async_exc` field of the current
- thread state.
- Guarded by the GIL. */
- int async_exc;
-#define NPENDINGCALLS 32
- struct _pending_call {
- int (*func)(void *);
- void *arg;
- } calls[NPENDINGCALLS];
+ int32_t npending;
+ /* The maximum allowed number of pending calls.
+ If the queue fills up to this point then _PyEval_AddPendingCall()
+ will return _Py_ADD_PENDING_FULL. */
+ int32_t max;
+ /* We don't want a flood of pending calls to interrupt any one thread
+ for too long, so we keep a limit on the number handled per pass.
+ A value of 0 means there is no limit (other than the maximum
+ size of the list of pending calls). */
+ int32_t maxloop;
+ struct _pending_call calls[PENDINGCALLSARRAYSIZE];
int first;
- int last;
+ int next;
};
+
typedef enum {
PERF_STATUS_FAILED = -1, // Perf trampoline is in an invalid state
PERF_STATUS_NO_INIT = 0, // Perf trampoline is not initialized
PERF_STATUS_OK = 1, // Perf trampoline is ready to be executed
} perf_status_t;
-
#ifdef PY_HAVE_PERF_TRAMPOLINE
struct code_arena_st;
@@ -47,35 +75,41 @@ struct trampoline_api_st {
unsigned int code_size, PyCodeObject* code);
int (*free_state)(void* state);
void *state;
+ Py_ssize_t code_padding;
};
#endif
+
struct _ceval_runtime_state {
struct {
#ifdef PY_HAVE_PERF_TRAMPOLINE
perf_status_t status;
+ int perf_trampoline_type;
Py_ssize_t extra_code_index;
struct code_arena_st *code_arena;
struct trampoline_api_st trampoline_api;
FILE *map_file;
+ Py_ssize_t persist_after_fork;
#else
int _not_used;
#endif
} perf;
- /* Request for checking signals. It is shared by all interpreters (see
- bpo-40513). Any thread of any interpreter can receive a signal, but only
- the main thread of the main interpreter can handle signals: see
- _Py_ThreadCanHandleSignals(). */
- _Py_atomic_int signals_pending;
/* Pending calls to be made only on the main thread. */
+ // The signal machinery falls back on this
+ // so it must be especially stable and efficient.
+ // For example, we use a preallocated array
+ // for the list of pending calls.
struct _pending_calls pending_mainthread;
+ PyMutex sys_trace_profile_mutex;
};
+
#ifdef PY_HAVE_PERF_TRAMPOLINE
# define _PyEval_RUNTIME_PERF_INIT \
{ \
.status = PERF_STATUS_NO_INIT, \
.extra_code_index = -1, \
+ .persist_after_fork = 0, \
}
#else
# define _PyEval_RUNTIME_PERF_INIT {0}
@@ -83,16 +117,13 @@ struct _ceval_runtime_state {
struct _ceval_state {
- /* This single variable consolidates all requests to break out of
- the fast path in the eval loop. */
- _Py_atomic_int eval_breaker;
- /* Request for dropping the GIL */
- _Py_atomic_int gil_drop_request;
+ /* This variable holds the global instrumentation version. When a thread is
+ running, this value is overlaid onto PyThreadState.eval_breaker so that
+ changes in the instrumentation version will trigger the eval breaker. */
+ uintptr_t instrumentation_version;
int recursion_limit;
struct _gil_runtime_state *gil;
int own_gil;
- /* The GC is ready to be executed */
- _Py_atomic_int gc_scheduled;
struct _pending_calls pending;
};
diff --git a/contrib/tools/python3/Include/internal/pycore_code.h b/contrib/tools/python3/Include/internal/pycore_code.h
index 92e0a8bbd39..efb97dd871f 100644
--- a/contrib/tools/python3/Include/internal/pycore_code.h
+++ b/contrib/tools/python3/Include/internal/pycore_code.h
@@ -4,6 +4,76 @@
extern "C" {
#endif
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_lock.h" // PyMutex
+#include "pycore_backoff.h" // _Py_BackoffCounter
+
+
+/* Each instruction in a code object is a fixed-width value,
+ * currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG
+ * opcode allows for larger values but the current limit is 3 uses
+ * of EXTENDED_ARG (see Python/compile.c), for a maximum
+ * 32-bit value. This aligns with the note in Python/compile.c
+ * (compiler_addop_i_line) indicating that the max oparg value is
+ * 2**32 - 1, rather than INT_MAX.
+ */
+
+typedef union {
+ uint16_t cache;
+ struct {
+ uint8_t code;
+ uint8_t arg;
+ } op;
+ _Py_BackoffCounter counter; // First cache entry of specializable op
+} _Py_CODEUNIT;
+
+#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive)
+#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
+
+
+/* These macros only remain defined for compatibility. */
+#define _Py_OPCODE(word) ((word).op.code)
+#define _Py_OPARG(word) ((word).op.arg)
+
+static inline _Py_CODEUNIT
+_py_make_codeunit(uint8_t opcode, uint8_t oparg)
+{
+ // No designated initialisers because of C++ compat
+ _Py_CODEUNIT word;
+ word.op.code = opcode;
+ word.op.arg = oparg;
+ return word;
+}
+
+static inline void
+_py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode)
+{
+ word->op.code = opcode;
+}
+
+#define _Py_MAKE_CODEUNIT(opcode, oparg) _py_make_codeunit((opcode), (oparg))
+#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), (opcode))
+
+
+// We hide some of the newer PyCodeObject fields behind macros.
+// This helps with backporting certain changes to 3.12.
+#define _PyCode_HAS_EXECUTORS(CODE) \
+ (CODE->co_executors != NULL)
+#define _PyCode_HAS_INSTRUMENTATION(CODE) \
+ (CODE->_co_instrumentation_version > 0)
+
+struct _py_code_state {
+ PyMutex mutex;
+ // Interned constants from code objects. Used by the free-threaded build.
+ struct _Py_hashtable_t *constants;
+};
+
+extern PyStatus _PyCode_Init(PyInterpreterState *interp);
+extern void _PyCode_Fini(PyInterpreterState *interp);
+
#define CODE_MAX_WATCHERS 8
/* PEP 659
@@ -18,55 +88,58 @@ extern "C" {
#define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT))
typedef struct {
- uint16_t counter;
- uint16_t index;
+ _Py_BackoffCounter counter;
uint16_t module_keys_version;
uint16_t builtin_keys_version;
+ uint16_t index;
} _PyLoadGlobalCache;
#define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PyBinaryOpCache;
#define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PyUnpackSequenceCache;
#define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \
CACHE_ENTRIES(_PyUnpackSequenceCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PyCompareOpCache;
#define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PyBinarySubscrCache;
#define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PySuperAttrCache;
#define INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR CACHE_ENTRIES(_PySuperAttrCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
uint16_t version[2];
uint16_t index;
} _PyAttrCache;
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
uint16_t type_version[2];
- uint16_t keys_version[2];
+ union {
+ uint16_t keys_version[2];
+ uint16_t dict_offset;
+ };
uint16_t descr[4];
} _PyLoadMethodCache;
@@ -77,30 +150,43 @@ typedef struct {
#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
uint16_t func_version[2];
} _PyCallCache;
#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PyStoreSubscrCache;
#define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PyForIterCache;
#define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache)
typedef struct {
- uint16_t counter;
+ _Py_BackoffCounter counter;
} _PySendCache;
#define INLINE_CACHE_ENTRIES_SEND CACHE_ENTRIES(_PySendCache)
+typedef struct {
+ _Py_BackoffCounter counter;
+ uint16_t version[2];
+} _PyToBoolCache;
+
+#define INLINE_CACHE_ENTRIES_TO_BOOL CACHE_ENTRIES(_PyToBoolCache)
+
+typedef struct {
+ _Py_BackoffCounter counter;
+} _PyContainsOpCache;
+
+#define INLINE_CACHE_ENTRIES_CONTAINS_OP CACHE_ENTRIES(_PyContainsOpCache)
+
// Borrowed references to common callables:
struct callable_cache {
PyObject *isinstance;
@@ -196,8 +282,8 @@ struct _PyCodeConstructor {
// back to a regular function signature. Regardless, this approach
// wouldn't be appropriate if this weren't a strictly internal API.
// (See the comments in https://github.com/python/cpython/pull/26258.)
-PyAPI_FUNC(int) _PyCode_Validate(struct _PyCodeConstructor *);
-PyAPI_FUNC(PyCodeObject *) _PyCode_New(struct _PyCodeConstructor *);
+extern int _PyCode_Validate(struct _PyCodeConstructor *);
+extern PyCodeObject* _PyCode_New(struct _PyCodeConstructor *);
/* Private API */
@@ -222,6 +308,23 @@ extern void _PyLineTable_InitAddressRange(
extern int _PyLineTable_NextAddressRange(PyCodeAddressRange *range);
extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range);
+// Similar to PyCode_Addr2Line(), but return -1 if the code object is invalid
+// and can be called without an attached tstate. Used by dump_frame() in
+// Python/traceback.c. The function uses heuristics to detect freed memory,
+// it's not 100% reliable.
+extern int _PyCode_SafeAddr2Line(PyCodeObject *co, int addr);
+
+
+/** API for executors */
+extern void _PyCode_Clear_Executors(PyCodeObject *code);
+
+#ifdef Py_GIL_DISABLED
+// gh-115999 tracks progress on addressing this.
+#define ENABLE_SPECIALIZATION 0
+#else
+#define ENABLE_SPECIALIZATION 1
+#endif
+
/* Specialization functions */
extern void _Py_Specialize_LoadSuperAttr(PyObject *global_super, PyObject *cls,
@@ -237,7 +340,7 @@ extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container,
extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub,
_Py_CODEUNIT *instr);
extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr,
- int nargs, PyObject *kwnames);
+ int nargs);
extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
int oparg, PyObject **locals);
extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,
@@ -246,27 +349,46 @@ extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr,
int oparg);
extern void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg);
extern void _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr);
-
-/* Finalizer function for static codeobjects used in deepfreeze.py */
-extern void _PyStaticCode_Fini(PyCodeObject *co);
-/* Function to intern strings of codeobjects and quicken the bytecode */
-extern int _PyStaticCode_Init(PyCodeObject *co);
+extern void _Py_Specialize_ToBool(PyObject *value, _Py_CODEUNIT *instr);
+extern void _Py_Specialize_ContainsOp(PyObject *value, _Py_CODEUNIT *instr);
#ifdef Py_STATS
+#include "pycore_bitutils.h" // _Py_bit_length
-#define STAT_INC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name++; } while (0)
-#define STAT_DEC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name--; } while (0)
-#define OPCODE_EXE_INC(opname) do { if (_py_stats) _py_stats->opcode_stats[opname].execution_count++; } while (0)
-#define CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.name++; } while (0)
-#define OBJECT_STAT_INC(name) do { if (_py_stats) _py_stats->object_stats.name++; } while (0)
+#define STAT_INC(opname, name) do { if (_Py_stats) _Py_stats->opcode_stats[opname].specialization.name++; } while (0)
+#define STAT_DEC(opname, name) do { if (_Py_stats) _Py_stats->opcode_stats[opname].specialization.name--; } while (0)
+#define OPCODE_EXE_INC(opname) do { if (_Py_stats) _Py_stats->opcode_stats[opname].execution_count++; } while (0)
+#define CALL_STAT_INC(name) do { if (_Py_stats) _Py_stats->call_stats.name++; } while (0)
+#define OBJECT_STAT_INC(name) do { if (_Py_stats) _Py_stats->object_stats.name++; } while (0)
#define OBJECT_STAT_INC_COND(name, cond) \
- do { if (_py_stats && cond) _py_stats->object_stats.name++; } while (0)
-#define EVAL_CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.eval_calls[name]++; } while (0)
+ do { if (_Py_stats && cond) _Py_stats->object_stats.name++; } while (0)
+#define EVAL_CALL_STAT_INC(name) do { if (_Py_stats) _Py_stats->call_stats.eval_calls[name]++; } while (0)
#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) \
- do { if (_py_stats && PyFunction_Check(callable)) _py_stats->call_stats.eval_calls[name]++; } while (0)
+ do { if (_Py_stats && PyFunction_Check(callable)) _Py_stats->call_stats.eval_calls[name]++; } while (0)
+#define GC_STAT_ADD(gen, name, n) do { if (_Py_stats) _Py_stats->gc_stats[(gen)].name += (n); } while (0)
+#define OPT_STAT_INC(name) do { if (_Py_stats) _Py_stats->optimization_stats.name++; } while (0)
+#define UOP_STAT_INC(opname, name) do { if (_Py_stats) { assert(opname < 512); _Py_stats->optimization_stats.opcode[opname].name++; } } while (0)
+#define UOP_PAIR_INC(uopcode, lastuop) \
+ do { \
+ if (lastuop && _Py_stats) { \
+ _Py_stats->optimization_stats.opcode[lastuop].pair_count[uopcode]++; \
+ } \
+ lastuop = uopcode; \
+ } while (0)
+#define OPT_UNSUPPORTED_OPCODE(opname) do { if (_Py_stats) _Py_stats->optimization_stats.unsupported_opcode[opname]++; } while (0)
+#define OPT_ERROR_IN_OPCODE(opname) do { if (_Py_stats) _Py_stats->optimization_stats.error_in_opcode[opname]++; } while (0)
+#define OPT_HIST(length, name) \
+ do { \
+ if (_Py_stats) { \
+ int bucket = _Py_bit_length(length >= 1 ? length - 1 : 0); \
+ bucket = (bucket >= _Py_UOP_HIST_SIZE) ? _Py_UOP_HIST_SIZE - 1 : bucket; \
+ _Py_stats->optimization_stats.name[bucket]++; \
+ } \
+ } while (0)
+#define RARE_EVENT_STAT_INC(name) do { if (_Py_stats) _Py_stats->rare_event_stats.name++; } while (0)
-// Used by the _opcode extension which is built as a shared library
+// Export for '_opcode' shared extension
PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
#else
@@ -278,6 +400,14 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
#define OBJECT_STAT_INC_COND(name, cond) ((void)0)
#define EVAL_CALL_STAT_INC(name) ((void)0)
#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) ((void)0)
+#define GC_STAT_ADD(gen, name, n) ((void)0)
+#define OPT_STAT_INC(name) ((void)0)
+#define UOP_STAT_INC(opname, name) ((void)0)
+#define UOP_PAIR_INC(uopcode, lastuop) ((void)0)
+#define OPT_UNSUPPORTED_OPCODE(opname) ((void)0)
+#define OPT_ERROR_IN_OPCODE(opname) ((void)0)
+#define OPT_HIST(length, name) ((void)0)
+#define RARE_EVENT_STAT_INC(name) ((void)0)
#endif // !Py_STATS
// Utility functions for reading/writing 32/64-bit values in the inline caches.
@@ -388,18 +518,14 @@ write_location_entry_start(uint8_t *ptr, int code, int length)
/** Counters
* The first 16-bit value in each inline cache is a counter.
- * When counting misses, the counter is treated as a simple unsigned value.
*
* When counting executions until the next specialization attempt,
* exponential backoff is used to reduce the number of specialization failures.
- * The high 12 bits store the counter, the low 4 bits store the backoff exponent.
- * On a specialization failure, the backoff exponent is incremented and the
- * counter set to (2**backoff - 1).
- * Backoff == 6 -> starting counter == 63, backoff == 10 -> starting counter == 1023.
+ * See pycore_backoff.h for more details.
+ * On a specialization failure, the backoff counter is restarted.
*/
-/* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */
-#define ADAPTIVE_BACKOFF_BITS 4
+#include "pycore_backoff.h"
// A value of 1 means that we attempt to specialize the *second* time each
// instruction is executed. Executing twice is a much better indicator of
@@ -417,54 +543,34 @@ write_location_entry_start(uint8_t *ptr, int code, int length)
#define ADAPTIVE_COOLDOWN_VALUE 52
#define ADAPTIVE_COOLDOWN_BACKOFF 0
-#define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS)
-
+// Can't assert this in pycore_backoff.h because of header order dependencies
+#if COLD_EXIT_INITIAL_VALUE <= ADAPTIVE_COOLDOWN_VALUE
+# error "Cold exit value should be larger than adaptive cooldown value"
+#endif
-static inline uint16_t
+static inline _Py_BackoffCounter
adaptive_counter_bits(uint16_t value, uint16_t backoff) {
- return ((value << ADAPTIVE_BACKOFF_BITS)
- | (backoff & ((1 << ADAPTIVE_BACKOFF_BITS) - 1)));
+ return make_backoff_counter(value, backoff);
}
-static inline uint16_t
+static inline _Py_BackoffCounter
adaptive_counter_warmup(void) {
return adaptive_counter_bits(ADAPTIVE_WARMUP_VALUE,
ADAPTIVE_WARMUP_BACKOFF);
}
-static inline uint16_t
+static inline _Py_BackoffCounter
adaptive_counter_cooldown(void) {
return adaptive_counter_bits(ADAPTIVE_COOLDOWN_VALUE,
ADAPTIVE_COOLDOWN_BACKOFF);
}
-static inline uint16_t
-adaptive_counter_backoff(uint16_t counter) {
- uint16_t backoff = counter & ((1 << ADAPTIVE_BACKOFF_BITS) - 1);
- backoff++;
- if (backoff > MAX_BACKOFF_VALUE) {
- backoff = MAX_BACKOFF_VALUE;
- }
- uint16_t value = (uint16_t)(1 << backoff) - 1;
- return adaptive_counter_bits(value, backoff);
+static inline _Py_BackoffCounter
+adaptive_counter_backoff(_Py_BackoffCounter counter) {
+ return restart_backoff_counter(counter);
}
-/* Line array cache for tracing */
-
-typedef struct _PyShimCodeDef {
- const uint8_t *code;
- int codelen;
- int stacksize;
- const char *cname;
-} _PyShimCodeDef;
-
-extern PyCodeObject *
-_Py_MakeShimCode(const _PyShimCodeDef *code);
-
-extern uint32_t _Py_next_func_version;
-
-
/* Comparison bit masks. */
/* Note this evaluates its arguments twice each */
@@ -489,6 +595,7 @@ extern int _Py_Instrument(PyCodeObject *co, PyInterpreterState *interp);
extern int _Py_GetBaseOpcode(PyCodeObject *code, int offset);
+extern int _PyInstruction_GetLength(PyCodeObject *code, int offset);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_codecs.h b/contrib/tools/python3/Include/internal/pycore_codecs.h
new file mode 100644
index 00000000000..5e2d5c5ce9d
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_codecs.h
@@ -0,0 +1,86 @@
+#ifndef Py_INTERNAL_CODECS_H
+#define Py_INTERNAL_CODECS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_lock.h" // PyMutex
+
+/* Initialize codecs-related state for the given interpreter, including
+ registering the first codec search function. Must be called before any other
+ PyCodec-related functions, and while only one thread is active. */
+extern PyStatus _PyCodec_InitRegistry(PyInterpreterState *interp);
+
+/* Finalize codecs-related state for the given interpreter. No PyCodec-related
+ functions other than PyCodec_Unregister() may be called after this. */
+extern void _PyCodec_Fini(PyInterpreterState *interp);
+
+extern PyObject* _PyCodec_Lookup(const char *encoding);
+
+/* Text codec specific encoding and decoding API.
+
+ Checks the encoding against a list of codecs which do not
+ implement a str<->bytes encoding before attempting the
+ operation.
+
+ Please note that these APIs are internal and should not
+ be used in Python C extensions.
+
+ XXX (ncoghlan): should we make these, or something like them, public
+ in Python 3.5+?
+
+ */
+extern PyObject* _PyCodec_LookupTextEncoding(
+ const char *encoding,
+ const char *alternate_command);
+
+extern PyObject* _PyCodec_EncodeText(
+ PyObject *object,
+ const char *encoding,
+ const char *errors);
+
+extern PyObject* _PyCodec_DecodeText(
+ PyObject *object,
+ const char *encoding,
+ const char *errors);
+
+/* These two aren't actually text encoding specific, but _io.TextIOWrapper
+ * is the only current API consumer.
+ */
+extern PyObject* _PyCodecInfo_GetIncrementalDecoder(
+ PyObject *codec_info,
+ const char *errors);
+
+extern PyObject* _PyCodecInfo_GetIncrementalEncoder(
+ PyObject *codec_info,
+ const char *errors);
+
+// Per-interpreter state used by codecs.c.
+struct codecs_state {
+ // A list of callable objects used to search for codecs.
+ PyObject *search_path;
+
+ // A dict mapping codec names to codecs returned from a callable in
+ // search_path.
+ PyObject *search_cache;
+
+ // A dict mapping error handling strategies to functions to implement them.
+ PyObject *error_registry;
+
+#ifdef Py_GIL_DISABLED
+ // Used to safely delete a specific item from search_path.
+ PyMutex search_path_mutex;
+#endif
+
+ // Whether or not the rest of the state is initialized.
+ int initialized;
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_CODECS_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_compile.h b/contrib/tools/python3/Include/internal/pycore_compile.h
index 80a637e5bf9..3c21f83a18b 100644
--- a/contrib/tools/python3/Include/internal/pycore_compile.h
+++ b/contrib/tools/python3/Include/internal/pycore_compile.h
@@ -8,10 +8,13 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_symtable.h" // _Py_SourceLocation
+#include "pycore_instruction_sequence.h"
+
struct _arena; // Type defined in pycore_pyarena.h
struct _mod; // Type defined in pycore_ast.h
-// Export the symbol for test_peg_generator (built as a library)
+// Export for 'test_peg_generator' shared extension
PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
struct _mod *mod,
PyObject *filename,
@@ -19,43 +22,22 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile(
int optimize,
struct _arena *arena);
-static const _PyCompilerSrcLocation NO_LOCATION = {-1, -1, -1, -1};
-
-typedef struct {
- int optimize;
- int ff_features;
+/* AST optimizations */
+extern int _PyCompile_AstOptimize(
+ struct _mod *mod,
+ PyObject *filename,
+ PyCompilerFlags *flags,
+ int optimize,
+ struct _arena *arena);
- int recursion_depth; /* current recursion depth */
- int recursion_limit; /* recursion limit */
-} _PyASTOptimizeState;
+struct _Py_SourceLocation;
extern int _PyAST_Optimize(
struct _mod *,
struct _arena *arena,
- _PyASTOptimizeState *state);
-
-typedef struct {
- int h_offset;
- int h_startdepth;
- int h_preserve_lasti;
-} _PyCompile_ExceptHandlerInfo;
-
-typedef struct {
- int i_opcode;
- int i_oparg;
- _PyCompilerSrcLocation i_loc;
- _PyCompile_ExceptHandlerInfo i_except_handler_info;
-} _PyCompile_Instruction;
-
-typedef struct {
- _PyCompile_Instruction *s_instrs;
- int s_allocated;
- int s_used;
+ int optimize,
+ int ff_features);
- int *s_labelmap; /* label id --> instr offset */
- int s_labelmap_size;
- int s_next_free_label; /* next free label id */
-} _PyCompile_InstructionSequence;
typedef struct {
PyObject *u_name;
@@ -92,10 +74,26 @@ int _PyCompile_EnsureArrayLargeEnough(
int _PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj);
-int _PyCompile_InstrSize(int opcode, int oparg);
+
+// Export for '_opcode' extension module
+PyAPI_FUNC(int) _PyCompile_OpcodeIsValid(int opcode);
+PyAPI_FUNC(int) _PyCompile_OpcodeHasArg(int opcode);
+PyAPI_FUNC(int) _PyCompile_OpcodeHasConst(int opcode);
+PyAPI_FUNC(int) _PyCompile_OpcodeHasName(int opcode);
+PyAPI_FUNC(int) _PyCompile_OpcodeHasJump(int opcode);
+PyAPI_FUNC(int) _PyCompile_OpcodeHasFree(int opcode);
+PyAPI_FUNC(int) _PyCompile_OpcodeHasLocal(int opcode);
+PyAPI_FUNC(int) _PyCompile_OpcodeHasExc(int opcode);
+
+PyAPI_FUNC(PyObject*) _PyCompile_GetUnaryIntrinsicName(int index);
+PyAPI_FUNC(PyObject*) _PyCompile_GetBinaryIntrinsicName(int index);
/* Access compiler internals for unit testing */
+// Export for '_testinternalcapi' shared extension
+PyAPI_FUNC(PyObject*) _PyCompile_CleanDoc(PyObject *doc);
+
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(PyObject*) _PyCompile_CodeGen(
PyObject *ast,
PyObject *filename,
@@ -103,11 +101,13 @@ PyAPI_FUNC(PyObject*) _PyCompile_CodeGen(
int optimize,
int compile_mode);
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(PyObject*) _PyCompile_OptimizeCfg(
PyObject *instructions,
PyObject *consts,
int nlocals);
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(PyCodeObject*)
_PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename,
PyObject *instructions);
diff --git a/contrib/tools/python3/Include/internal/pycore_complexobject.h b/contrib/tools/python3/Include/internal/pycore_complexobject.h
new file mode 100644
index 00000000000..54713536eed
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_complexobject.h
@@ -0,0 +1,25 @@
+#ifndef Py_INTERNAL_COMPLEXOBJECT_H
+#define Py_INTERNAL_COMPLEXOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_unicodeobject.h" // _PyUnicodeWriter
+
+/* Format the object based on the format_spec, as defined in PEP 3101
+ (Advanced String Formatting). */
+extern int _PyComplex_FormatAdvancedWriter(
+ _PyUnicodeWriter *writer,
+ PyObject *obj,
+ PyObject *format_spec,
+ Py_ssize_t start,
+ Py_ssize_t end);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_COMPLEXOBJECT_H
diff --git a/contrib/tools/python3/Include/internal/pycore_condvar.h b/contrib/tools/python3/Include/internal/pycore_condvar.h
index 2177bed31fc..55271f0a411 100644
--- a/contrib/tools/python3/Include/internal/pycore_condvar.h
+++ b/contrib/tools/python3/Include/internal/pycore_condvar.h
@@ -5,14 +5,8 @@
# error "this header requires Py_BUILD_CORE define"
#endif
-#ifndef _POSIX_THREADS
-/* This means pthreads are not implemented in libc headers, hence the macro
- not present in unistd.h. But they still can be implemented as an external
- library (e.g. gnu pth in pthread emulation) */
-# ifdef HAVE_PTHREAD_H
-# include <pthread.h> /* _POSIX_THREADS */
-# endif
-#endif
+#include "pycore_pythread.h" // _POSIX_THREADS
+
#ifdef _POSIX_THREADS
/*
@@ -21,7 +15,7 @@
#define Py_HAVE_CONDVAR
#ifdef HAVE_PTHREAD_H
-# include <pthread.h>
+# include <pthread.h> // pthread_mutex_t
#endif
#define PyMUTEX_T pthread_mutex_t
@@ -43,14 +37,14 @@
#include <windows.h> // CRITICAL_SECTION
/* options */
-/* non-emulated condition variables are provided for those that want
- * to target Windows Vista. Modify this macro to enable them.
+/* emulated condition variables are provided for those that want
+ * to target Windows XP or earlier. Modify this macro to enable them.
*/
#ifndef _PY_EMULATED_WIN_CV
-#define _PY_EMULATED_WIN_CV 1 /* use emulated condition variables */
+#define _PY_EMULATED_WIN_CV 0 /* use non-emulated condition variables */
#endif
-/* fall back to emulation if not targeting Vista */
+/* fall back to emulation if targeting earlier than Vista */
#if !defined NTDDI_VISTA || NTDDI_VERSION < NTDDI_VISTA
#undef _PY_EMULATED_WIN_CV
#define _PY_EMULATED_WIN_CV 1
@@ -85,7 +79,7 @@ typedef struct _PyCOND_T
#else /* !_PY_EMULATED_WIN_CV */
-/* Use native Win7 primitives if build target is Win7 or higher */
+/* Use native Windows primitives if build target is Vista or higher */
/* SRWLOCK is faster and better than CriticalSection */
typedef SRWLOCK PyMUTEX_T;
diff --git a/contrib/tools/python3/Include/internal/pycore_context.h b/contrib/tools/python3/Include/internal/pycore_context.h
index 52dfe3ef233..10c1f1e52be 100644
--- a/contrib/tools/python3/Include/internal/pycore_context.h
+++ b/contrib/tools/python3/Include/internal/pycore_context.h
@@ -5,7 +5,8 @@
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_hamt.h" /* PyHamtObject */
+#include "pycore_freelist.h" // _PyFreeListState
+#include "pycore_hamt.h" // PyHamtObject
extern PyTypeObject _PyContextTokenMissing_Type;
@@ -13,7 +14,6 @@ extern PyTypeObject _PyContextTokenMissing_Type;
/* runtime lifecycle */
PyStatus _PyContext_Init(PyInterpreterState *);
-void _PyContext_Fini(PyInterpreterState *);
/* other API */
@@ -22,23 +22,6 @@ typedef struct {
PyObject_HEAD
} _PyContextTokenMissing;
-#ifndef WITH_FREELISTS
-// without freelists
-# define PyContext_MAXFREELIST 0
-#endif
-
-#ifndef PyContext_MAXFREELIST
-# define PyContext_MAXFREELIST 255
-#endif
-
-struct _Py_context_state {
-#if PyContext_MAXFREELIST > 0
- // List of free PyContext objects
- PyContext *freelist;
- int numfree;
-#endif
-};
-
struct _pycontextobject {
PyObject_HEAD
PyContext *ctx_prev;
@@ -52,9 +35,11 @@ struct _pycontextvarobject {
PyObject_HEAD
PyObject *var_name;
PyObject *var_default;
+#ifndef Py_GIL_DISABLED
PyObject *var_cached;
uint64_t var_cached_tsid;
uint64_t var_cached_tsver;
+#endif
Py_hash_t var_hash;
};
@@ -68,4 +53,9 @@ struct _pycontexttokenobject {
};
+// _testinternalcapi.hamt() used by tests.
+// Export for '_testcapi' shared extension
+PyAPI_FUNC(PyObject*) _PyContext_NewHamtForTests(void);
+
+
#endif /* !Py_INTERNAL_CONTEXT_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_critical_section.h b/contrib/tools/python3/Include/internal/pycore_critical_section.h
new file mode 100644
index 00000000000..78cd0d54972
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_critical_section.h
@@ -0,0 +1,233 @@
+#ifndef Py_INTERNAL_CRITICAL_SECTION_H
+#define Py_INTERNAL_CRITICAL_SECTION_H
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_lock.h" // PyMutex
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Tagged pointers to critical sections use the two least significant bits to
+// mark if the pointed-to critical section is inactive and whether it is a
+// PyCriticalSection2 object.
+#define _Py_CRITICAL_SECTION_INACTIVE 0x1
+#define _Py_CRITICAL_SECTION_TWO_MUTEXES 0x2
+#define _Py_CRITICAL_SECTION_MASK 0x3
+
+#ifdef Py_GIL_DISABLED
+# define Py_BEGIN_CRITICAL_SECTION_MUT(mutex) \
+ { \
+ PyCriticalSection _py_cs; \
+ _PyCriticalSection_BeginMutex(&_py_cs, mutex)
+
+# define Py_BEGIN_CRITICAL_SECTION2_MUT(m1, m2) \
+ { \
+ PyCriticalSection2 _py_cs2; \
+ _PyCriticalSection2_BeginMutex(&_py_cs2, m1, m2)
+
+// Specialized version of critical section locking to safely use
+// PySequence_Fast APIs without the GIL. For performance, the argument *to*
+// PySequence_Fast() is provided to the macro, not the *result* of
+// PySequence_Fast(), which would require an extra test to determine if the
+// lock must be acquired.
+# define Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(original) \
+ { \
+ PyObject *_orig_seq = _PyObject_CAST(original); \
+ const bool _should_lock_cs = PyList_CheckExact(_orig_seq); \
+ PyCriticalSection _cs; \
+ if (_should_lock_cs) { \
+ _PyCriticalSection_Begin(&_cs, _orig_seq); \
+ }
+
+# define Py_END_CRITICAL_SECTION_SEQUENCE_FAST() \
+ if (_should_lock_cs) { \
+ PyCriticalSection_End(&_cs); \
+ } \
+ }
+
+// Asserts that the mutex is locked. The mutex must be held by the
+// top-most critical section otherwise there's the possibility
+// that the mutex would be swalled out in some code paths.
+#define _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(mutex) \
+ _PyCriticalSection_AssertHeld(mutex)
+
+// Asserts that the mutex for the given object is locked. The mutex must
+// be held by the top-most critical section otherwise there's the
+// possibility that the mutex would be swalled out in some code paths.
+#ifdef Py_DEBUG
+
+# define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op) \
+ if (Py_REFCNT(op) != 1) { \
+ _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&_PyObject_CAST(op)->ob_mutex); \
+ }
+
+#else /* Py_DEBUG */
+
+# define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op)
+
+#endif /* Py_DEBUG */
+
+#else /* !Py_GIL_DISABLED */
+// The critical section APIs are no-ops with the GIL.
+# define Py_BEGIN_CRITICAL_SECTION_MUT(mut) {
+# define Py_BEGIN_CRITICAL_SECTION2_MUT(m1, m2) {
+# define Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(original) {
+# define Py_END_CRITICAL_SECTION_SEQUENCE_FAST() }
+# define _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(mutex)
+# define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op)
+#endif /* !Py_GIL_DISABLED */
+
+// Resumes the top-most critical section.
+PyAPI_FUNC(void)
+_PyCriticalSection_Resume(PyThreadState *tstate);
+
+// (private) slow path for locking the mutex
+PyAPI_FUNC(void)
+_PyCriticalSection_BeginSlow(PyCriticalSection *c, PyMutex *m);
+
+PyAPI_FUNC(void)
+_PyCriticalSection2_BeginSlow(PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2,
+ int is_m1_locked);
+
+PyAPI_FUNC(void)
+_PyCriticalSection_SuspendAll(PyThreadState *tstate);
+
+#ifdef Py_GIL_DISABLED
+
+static inline int
+_PyCriticalSection_IsActive(uintptr_t tag)
+{
+ return tag != 0 && (tag & _Py_CRITICAL_SECTION_INACTIVE) == 0;
+}
+
+static inline void
+_PyCriticalSection_BeginMutex(PyCriticalSection *c, PyMutex *m)
+{
+ if (PyMutex_LockFast(&m->_bits)) {
+ PyThreadState *tstate = _PyThreadState_GET();
+ c->_cs_mutex = m;
+ c->_cs_prev = tstate->critical_section;
+ tstate->critical_section = (uintptr_t)c;
+ }
+ else {
+ _PyCriticalSection_BeginSlow(c, m);
+ }
+}
+
+static inline void
+_PyCriticalSection_Begin(PyCriticalSection *c, PyObject *op)
+{
+ _PyCriticalSection_BeginMutex(c, &op->ob_mutex);
+}
+#define PyCriticalSection_Begin _PyCriticalSection_Begin
+
+// Removes the top-most critical section from the thread's stack of critical
+// sections. If the new top-most critical section is inactive, then it is
+// resumed.
+static inline void
+_PyCriticalSection_Pop(PyCriticalSection *c)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+ uintptr_t prev = c->_cs_prev;
+ tstate->critical_section = prev;
+
+ if ((prev & _Py_CRITICAL_SECTION_INACTIVE) != 0) {
+ _PyCriticalSection_Resume(tstate);
+ }
+}
+
+static inline void
+_PyCriticalSection_End(PyCriticalSection *c)
+{
+ PyMutex_Unlock(c->_cs_mutex);
+ _PyCriticalSection_Pop(c);
+}
+#define PyCriticalSection_End _PyCriticalSection_End
+
+static inline void
+_PyCriticalSection2_BeginMutex(PyCriticalSection2 *c, PyMutex *m1, PyMutex *m2)
+{
+ if (m1 == m2) {
+ // If the two mutex arguments are the same, treat this as a critical
+ // section with a single mutex.
+ c->_cs_mutex2 = NULL;
+ _PyCriticalSection_BeginMutex(&c->_cs_base, m1);
+ return;
+ }
+
+ if ((uintptr_t)m2 < (uintptr_t)m1) {
+ // Sort the mutexes so that the lower address is locked first.
+ // The exact order does not matter, but we need to acquire the mutexes
+ // in a consistent order to avoid lock ordering deadlocks.
+ PyMutex *tmp = m1;
+ m1 = m2;
+ m2 = tmp;
+ }
+
+ if (PyMutex_LockFast(&m1->_bits)) {
+ if (PyMutex_LockFast(&m2->_bits)) {
+ PyThreadState *tstate = _PyThreadState_GET();
+ c->_cs_base._cs_mutex = m1;
+ c->_cs_mutex2 = m2;
+ c->_cs_base._cs_prev = tstate->critical_section;
+
+ uintptr_t p = (uintptr_t)c | _Py_CRITICAL_SECTION_TWO_MUTEXES;
+ tstate->critical_section = p;
+ }
+ else {
+ _PyCriticalSection2_BeginSlow(c, m1, m2, 1);
+ }
+ }
+ else {
+ _PyCriticalSection2_BeginSlow(c, m1, m2, 0);
+ }
+}
+
+static inline void
+_PyCriticalSection2_Begin(PyCriticalSection2 *c, PyObject *a, PyObject *b)
+{
+ _PyCriticalSection2_BeginMutex(c, &a->ob_mutex, &b->ob_mutex);
+}
+#define PyCriticalSection2_Begin _PyCriticalSection2_Begin
+
+static inline void
+_PyCriticalSection2_End(PyCriticalSection2 *c)
+{
+ if (c->_cs_mutex2) {
+ PyMutex_Unlock(c->_cs_mutex2);
+ }
+ PyMutex_Unlock(c->_cs_base._cs_mutex);
+ _PyCriticalSection_Pop(&c->_cs_base);
+}
+#define PyCriticalSection2_End _PyCriticalSection2_End
+
+static inline void
+_PyCriticalSection_AssertHeld(PyMutex *mutex)
+{
+#ifdef Py_DEBUG
+ PyThreadState *tstate = _PyThreadState_GET();
+ uintptr_t prev = tstate->critical_section;
+ if (prev & _Py_CRITICAL_SECTION_TWO_MUTEXES) {
+ PyCriticalSection2 *cs = (PyCriticalSection2 *)(prev & ~_Py_CRITICAL_SECTION_MASK);
+ assert(cs != NULL && (cs->_cs_base._cs_mutex == mutex || cs->_cs_mutex2 == mutex));
+ }
+ else {
+ PyCriticalSection *cs = (PyCriticalSection *)(tstate->critical_section & ~_Py_CRITICAL_SECTION_MASK);
+ assert(cs != NULL && cs->_cs_mutex == mutex);
+ }
+
+#endif
+}
+
+#endif /* Py_GIL_DISABLED */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_CRITICAL_SECTION_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_crossinterp.h b/contrib/tools/python3/Include/internal/pycore_crossinterp.h
new file mode 100644
index 00000000000..2dd165eae74
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_crossinterp.h
@@ -0,0 +1,340 @@
+#ifndef Py_INTERNAL_CROSSINTERP_H
+#define Py_INTERNAL_CROSSINTERP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_lock.h" // PyMutex
+#include "pycore_pyerrors.h"
+
+/**************/
+/* exceptions */
+/**************/
+
+PyAPI_DATA(PyObject *) PyExc_InterpreterError;
+PyAPI_DATA(PyObject *) PyExc_InterpreterNotFoundError;
+
+
+/***************************/
+/* cross-interpreter calls */
+/***************************/
+
+typedef int (*_Py_simple_func)(void *);
+extern int _Py_CallInInterpreter(
+ PyInterpreterState *interp,
+ _Py_simple_func func,
+ void *arg);
+extern int _Py_CallInInterpreterAndRawFree(
+ PyInterpreterState *interp,
+ _Py_simple_func func,
+ void *arg);
+
+
+/**************************/
+/* cross-interpreter data */
+/**************************/
+
+typedef struct _xid _PyCrossInterpreterData;
+typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *);
+typedef void (*xid_freefunc)(void *);
+
+// _PyCrossInterpreterData is similar to Py_buffer as an effectively
+// opaque struct that holds data outside the object machinery. This
+// is necessary to pass safely between interpreters in the same process.
+struct _xid {
+ // data is the cross-interpreter-safe derivation of a Python object
+ // (see _PyObject_GetCrossInterpreterData). It will be NULL if the
+ // new_object func (below) encodes the data.
+ void *data;
+ // obj is the Python object from which the data was derived. This
+ // is non-NULL only if the data remains bound to the object in some
+ // way, such that the object must be "released" (via a decref) when
+ // the data is released. In that case the code that sets the field,
+ // likely a registered "crossinterpdatafunc", is responsible for
+ // ensuring it owns the reference (i.e. incref).
+ PyObject *obj;
+ // interp is the ID of the owning interpreter of the original
+ // object. It corresponds to the active interpreter when
+ // _PyObject_GetCrossInterpreterData() was called. This should only
+ // be set by the cross-interpreter machinery.
+ //
+ // We use the ID rather than the PyInterpreterState to avoid issues
+ // with deleted interpreters. Note that IDs are never re-used, so
+ // each one will always correspond to a specific interpreter
+ // (whether still alive or not).
+ int64_t interpid;
+ // new_object is a function that returns a new object in the current
+ // interpreter given the data. The resulting object (a new
+ // reference) will be equivalent to the original object. This field
+ // is required.
+ xid_newobjectfunc new_object;
+ // free is called when the data is released. If it is NULL then
+ // nothing will be done to free the data. For some types this is
+ // okay (e.g. bytes) and for those types this field should be set
+ // to NULL. However, for most the data was allocated just for
+ // cross-interpreter use, so it must be freed when
+ // _PyCrossInterpreterData_Release is called or the memory will
+ // leak. In that case, at the very least this field should be set
+ // to PyMem_RawFree (the default if not explicitly set to NULL).
+ // The call will happen with the original interpreter activated.
+ xid_freefunc free;
+};
+
+PyAPI_FUNC(_PyCrossInterpreterData *) _PyCrossInterpreterData_New(void);
+PyAPI_FUNC(void) _PyCrossInterpreterData_Free(_PyCrossInterpreterData *data);
+
+#define _PyCrossInterpreterData_DATA(DATA) ((DATA)->data)
+#define _PyCrossInterpreterData_OBJ(DATA) ((DATA)->obj)
+#define _PyCrossInterpreterData_INTERPID(DATA) ((DATA)->interpid)
+// Users should not need getters for "new_object" or "free".
+
+
+/* defining cross-interpreter data */
+
+PyAPI_FUNC(void) _PyCrossInterpreterData_Init(
+ _PyCrossInterpreterData *data,
+ PyInterpreterState *interp, void *shared, PyObject *obj,
+ xid_newobjectfunc new_object);
+PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize(
+ _PyCrossInterpreterData *,
+ PyInterpreterState *interp, const size_t, PyObject *,
+ xid_newobjectfunc);
+PyAPI_FUNC(void) _PyCrossInterpreterData_Clear(
+ PyInterpreterState *, _PyCrossInterpreterData *);
+
+// Normally the Init* functions are sufficient. The only time
+// additional initialization might be needed is to set the "free" func,
+// though that should be infrequent.
+#define _PyCrossInterpreterData_SET_FREE(DATA, FUNC) \
+ do { \
+ (DATA)->free = (FUNC); \
+ } while (0)
+// Additionally, some shareable types are essentially light wrappers
+// around other shareable types. The crossinterpdatafunc of the wrapper
+// can often be implemented by calling the wrapped object's
+// crossinterpdatafunc and then changing the "new_object" function.
+// We have _PyCrossInterpreterData_SET_NEW_OBJECT() here for that,
+// but might be better to have a function like
+// _PyCrossInterpreterData_AdaptToWrapper() instead.
+#define _PyCrossInterpreterData_SET_NEW_OBJECT(DATA, FUNC) \
+ do { \
+ (DATA)->new_object = (FUNC); \
+ } while (0)
+
+
+/* using cross-interpreter data */
+
+PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *);
+PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *);
+PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *);
+PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *);
+PyAPI_FUNC(int) _PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *);
+
+
+/* cross-interpreter data registry */
+
+// For now we use a global registry of shareable classes. An
+// alternative would be to add a tp_* slot for a class's
+// crossinterpdatafunc. It would be simpler and more efficient.
+
+typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *,
+ _PyCrossInterpreterData *);
+
+struct _xidregitem;
+
+struct _xidregitem {
+ struct _xidregitem *prev;
+ struct _xidregitem *next;
+ /* This can be a dangling pointer, but only if weakref is set. */
+ PyTypeObject *cls;
+ /* This is NULL for builtin types. */
+ PyObject *weakref;
+ size_t refcount;
+ crossinterpdatafunc getdata;
+};
+
+struct _xidregistry {
+ int global; /* builtin types or heap types */
+ int initialized;
+ PyMutex mutex;
+ struct _xidregitem *head;
+};
+
+PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc);
+PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *);
+PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);
+
+
+/*****************************/
+/* runtime state & lifecycle */
+/*****************************/
+
+struct _xi_runtime_state {
+ // builtin types
+ // XXX Remove this field once we have a tp_* slot.
+ struct _xidregistry registry;
+};
+
+struct _xi_state {
+ // heap types
+ // XXX Remove this field once we have a tp_* slot.
+ struct _xidregistry registry;
+
+ // heap types
+ PyObject *PyExc_NotShareableError;
+};
+
+extern PyStatus _PyXI_Init(PyInterpreterState *interp);
+extern void _PyXI_Fini(PyInterpreterState *interp);
+
+extern PyStatus _PyXI_InitTypes(PyInterpreterState *interp);
+extern void _PyXI_FiniTypes(PyInterpreterState *interp);
+
+#define _PyInterpreterState_GetXIState(interp) (&(interp)->xi)
+
+
+/***************************/
+/* short-term data sharing */
+/***************************/
+
+// Ultimately we'd like to preserve enough information about the
+// exception and traceback that we could re-constitute (or at least
+// simulate, a la traceback.TracebackException), and even chain, a copy
+// of the exception in the calling interpreter.
+
+typedef struct _excinfo {
+ struct _excinfo_type {
+ PyTypeObject *builtin;
+ const char *name;
+ const char *qualname;
+ const char *module;
+ } type;
+ const char *msg;
+ const char *errdisplay;
+} _PyXI_excinfo;
+
+PyAPI_FUNC(int) _PyXI_InitExcInfo(_PyXI_excinfo *info, PyObject *exc);
+PyAPI_FUNC(PyObject *) _PyXI_FormatExcInfo(_PyXI_excinfo *info);
+PyAPI_FUNC(PyObject *) _PyXI_ExcInfoAsObject(_PyXI_excinfo *info);
+PyAPI_FUNC(void) _PyXI_ClearExcInfo(_PyXI_excinfo *info);
+
+
+typedef enum error_code {
+ _PyXI_ERR_NO_ERROR = 0,
+ _PyXI_ERR_UNCAUGHT_EXCEPTION = -1,
+ _PyXI_ERR_OTHER = -2,
+ _PyXI_ERR_NO_MEMORY = -3,
+ _PyXI_ERR_ALREADY_RUNNING = -4,
+ _PyXI_ERR_MAIN_NS_FAILURE = -5,
+ _PyXI_ERR_APPLY_NS_FAILURE = -6,
+ _PyXI_ERR_NOT_SHAREABLE = -7,
+} _PyXI_errcode;
+
+
+typedef struct _sharedexception {
+ // The originating interpreter.
+ PyInterpreterState *interp;
+ // The kind of error to propagate.
+ _PyXI_errcode code;
+ // The exception information to propagate, if applicable.
+ // This is populated only for some error codes,
+ // but always for _PyXI_ERR_UNCAUGHT_EXCEPTION.
+ _PyXI_excinfo uncaught;
+} _PyXI_error;
+
+PyAPI_FUNC(PyObject *) _PyXI_ApplyError(_PyXI_error *err);
+
+
+typedef struct xi_session _PyXI_session;
+typedef struct _sharedns _PyXI_namespace;
+
+PyAPI_FUNC(void) _PyXI_FreeNamespace(_PyXI_namespace *ns);
+PyAPI_FUNC(_PyXI_namespace *) _PyXI_NamespaceFromNames(PyObject *names);
+PyAPI_FUNC(int) _PyXI_FillNamespaceFromDict(
+ _PyXI_namespace *ns,
+ PyObject *nsobj,
+ _PyXI_session *session);
+PyAPI_FUNC(int) _PyXI_ApplyNamespace(
+ _PyXI_namespace *ns,
+ PyObject *nsobj,
+ PyObject *dflt);
+
+
+// A cross-interpreter session involves entering an interpreter
+// (_PyXI_Enter()), doing some work with it, and finally exiting
+// that interpreter (_PyXI_Exit()).
+//
+// At the boundaries of the session, both entering and exiting,
+// data may be exchanged between the previous interpreter and the
+// target one in a thread-safe way that does not violate the
+// isolation between interpreters. This includes setting objects
+// in the target's __main__ module on the way in, and capturing
+// uncaught exceptions on the way out.
+struct xi_session {
+ // Once a session has been entered, this is the tstate that was
+ // current before the session. If it is different from cur_tstate
+ // then we must have switched interpreters. Either way, this will
+ // be the current tstate once we exit the session.
+ PyThreadState *prev_tstate;
+ // Once a session has been entered, this is the current tstate.
+ // It must be current when the session exits.
+ PyThreadState *init_tstate;
+ // This is true if init_tstate needs cleanup during exit.
+ int own_init_tstate;
+
+ // This is true if, while entering the session, init_thread took
+ // "ownership" of the interpreter's __main__ module. This means
+ // it is the only thread that is allowed to run code there.
+ // (Caveat: for now, users may still run exec() against the
+ // __main__ module's dict, though that isn't advisable.)
+ int running;
+ // This is a cached reference to the __dict__ of the entered
+ // interpreter's __main__ module. It is looked up when at the
+ // beginning of the session as a convenience.
+ PyObject *main_ns;
+
+ // This is set if the interpreter is entered and raised an exception
+ // that needs to be handled in some special way during exit.
+ _PyXI_errcode *error_override;
+ // This is set if exit captured an exception to propagate.
+ _PyXI_error *error;
+
+ // -- pre-allocated memory --
+ _PyXI_error _error;
+ _PyXI_errcode _error_override;
+};
+
+PyAPI_FUNC(int) _PyXI_Enter(
+ _PyXI_session *session,
+ PyInterpreterState *interp,
+ PyObject *nsupdates);
+PyAPI_FUNC(void) _PyXI_Exit(_PyXI_session *session);
+
+PyAPI_FUNC(PyObject *) _PyXI_ApplyCapturedException(_PyXI_session *session);
+PyAPI_FUNC(int) _PyXI_HasCapturedException(_PyXI_session *session);
+
+
+/*************/
+/* other API */
+/*************/
+
+// Export for _testinternalcapi shared extension
+PyAPI_FUNC(PyInterpreterState *) _PyXI_NewInterpreter(
+ PyInterpreterConfig *config,
+ long *maybe_whence,
+ PyThreadState **p_tstate,
+ PyThreadState **p_save_tstate);
+PyAPI_FUNC(void) _PyXI_EndInterpreter(
+ PyInterpreterState *interp,
+ PyThreadState *tstate,
+ PyThreadState **p_save_tstate);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_CROSSINTERP_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_descrobject.h b/contrib/tools/python3/Include/internal/pycore_descrobject.h
index 76378569df9..3cec59a68a3 100644
--- a/contrib/tools/python3/Include/internal/pycore_descrobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_descrobject.h
@@ -20,6 +20,8 @@ typedef struct {
typedef propertyobject _PyPropertyObject;
+extern PyTypeObject _PyMethodWrapper_Type;
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_dict.h b/contrib/tools/python3/Include/internal/pycore_dict.h
index 6253e0841ad..36da498db2c 100644
--- a/contrib/tools/python3/Include/internal/pycore_dict.h
+++ b/contrib/tools/python3/Include/internal/pycore_dict.h
@@ -1,4 +1,3 @@
-
#ifndef Py_INTERNAL_DICT_H
#define Py_INTERNAL_DICT_H
#ifdef __cplusplus
@@ -9,14 +8,68 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_dict_state.h"
-#include "pycore_runtime.h" // _PyRuntime
+#include "pycore_freelist.h" // _PyFreeListState
+#include "pycore_identifier.h" // _Py_Identifier
+#include "pycore_object.h" // PyManagedDictPointer
+#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_SSIZE_ACQUIRE
+
+// Unsafe flavor of PyDict_GetItemWithError(): no error checking
+extern PyObject* _PyDict_GetItemWithError(PyObject *dp, PyObject *key);
+
+// Delete an item from a dict if a predicate is true
+// Returns -1 on error, 1 if the item was deleted, 0 otherwise
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
+ int (*predicate)(PyObject *value, void *arg),
+ void *arg);
+
+// "KnownHash" variants
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
+ PyObject *item, Py_hash_t hash);
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key,
+ Py_hash_t hash);
+extern int _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t);
+
+// "Id" variants
+extern PyObject* _PyDict_GetItemIdWithError(PyObject *dp,
+ _Py_Identifier *key);
+extern int _PyDict_ContainsId(PyObject *, _Py_Identifier *);
+extern int _PyDict_SetItemId(PyObject *dp, _Py_Identifier *key, PyObject *item);
+extern int _PyDict_DelItemId(PyObject *mp, _Py_Identifier *key);
+
+extern int _PyDict_Next(
+ PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
+
+extern int _PyDict_HasOnlyStringKeys(PyObject *mp);
+
+extern void _PyDict_MaybeUntrack(PyObject *mp);
+
+// Export for '_ctypes' shared extension
+PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
+
+#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
+/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0,
+ the first occurrence of a key wins, if override is 1, the last occurrence
+ of a key wins, if override is 2, a KeyError with conflicting key as
+ argument is raised.
+*/
+PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override);
-/* runtime lifecycle */
+extern void _PyDict_DebugMallocStats(FILE *out);
-extern void _PyDict_Fini(PyInterpreterState *interp);
+/* _PyDictView */
+
+typedef struct {
+ PyObject_HEAD
+ PyDictObject *dv_dict;
+} _PyDictViewObject;
+
+extern PyObject* _PyDictView_New(PyObject *, PyTypeObject *);
+extern PyObject* _PyDictView_Intersect(PyObject* self, PyObject *other);
/* other API */
@@ -42,20 +95,35 @@ extern uint32_t _PyDictKeys_GetVersionForCurrentState(
extern size_t _PyDict_KeysSize(PyDictKeysObject *keys);
+extern void _PyDictKeys_DecRef(PyDictKeysObject *keys);
+
/* _Py_dict_lookup() returns index of entry which can be used like DK_ENTRIES(dk)[index].
* -1 when no entry found, -3 when compare raises error.
*/
extern Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr);
+extern Py_ssize_t _Py_dict_lookup_threadsafe(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr);
extern Py_ssize_t _PyDict_LookupIndex(PyDictObject *, PyObject *);
extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key);
-extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
+PyAPI_FUNC(PyObject *)_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
/* Consumes references to key and value */
-extern int _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value);
-extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
+PyAPI_FUNC(int) _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value);
+extern int _PyDict_SetItem_LockHeld(PyDictObject *dict, PyObject *name, PyObject *value);
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyDict_SetItem_KnownHash_LockHeld(PyDictObject *mp, PyObject *key,
+ PyObject *value, Py_hash_t hash);
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyDict_GetItemRef_KnownHash_LockHeld(PyDictObject *op, PyObject *key, Py_hash_t hash, PyObject **result);
+extern int _PyDict_GetItemRef_KnownHash(PyDictObject *op, PyObject *key, Py_hash_t hash, PyObject **result);
+extern int _PyDict_GetItemRef_Unicode_LockHeld(PyDictObject *op, PyObject *key, PyObject **result);
+extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr, PyObject *name, PyObject *value);
-extern PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
+extern int _PyDict_Pop_KnownHash(
+ PyDictObject *dict,
+ PyObject *key,
+ Py_hash_t hash,
+ PyObject **result);
#define DKIX_EMPTY (-1)
#define DKIX_DUMMY (-2) /* Used internally */
@@ -81,6 +149,11 @@ struct _dictkeysobject {
/* Kind of keys */
uint8_t dk_kind;
+#ifdef Py_GIL_DISABLED
+ /* Lock used to protect shared keys */
+ PyMutex dk_mutex;
+#endif
+
/* Version number -- Reset to 0 by any modification to keys */
uint32_t dk_version;
@@ -90,6 +163,7 @@ struct _dictkeysobject {
/* Number of used entries in dk_entries. */
Py_ssize_t dk_nentries;
+
/* Actual hash table of dk_size entries. It holds indices in dk_entries,
or DKIX_EMPTY(-1) or DKIX_DUMMY(-2).
@@ -106,7 +180,7 @@ struct _dictkeysobject {
char dk_indices[]; /* char is required to avoid strict aliasing. */
/* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows:
- see the DK_ENTRIES() macro */
+ see the DK_ENTRIES() / DK_UNICODE_ENTRIES() functions below */
};
/* This must be no more than 250, for the prefix size to fit in one byte. */
@@ -120,6 +194,10 @@ struct _dictkeysobject {
* [-1] = prefix size. [-2] = used size. size[-2-n...] = insertion order.
*/
struct _dictvalues {
+ uint8_t capacity;
+ uint8_t size;
+ uint8_t embedded;
+ uint8_t valid;
PyObject *values[1];
};
@@ -135,6 +213,7 @@ static inline void* _DK_ENTRIES(PyDictKeysObject *dk) {
size_t index = (size_t)1 << dk->dk_log2_index_bytes;
return (&indices[index]);
}
+
static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) {
assert(dk->dk_kind == DICT_KEYS_GENERAL);
return (PyDictKeyEntry*)_DK_ENTRIES(dk);
@@ -146,11 +225,35 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) {
#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL)
-#define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS)
-#define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1)
+#define DICT_VERSION_INCREMENT (1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS))
+#define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1)
+#define DICT_WATCHER_AND_MODIFICATION_MASK ((1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) - 1)
+
+#ifdef Py_GIL_DISABLED
+
+#define THREAD_LOCAL_DICT_VERSION_COUNT 256
+#define THREAD_LOCAL_DICT_VERSION_BATCH THREAD_LOCAL_DICT_VERSION_COUNT * DICT_VERSION_INCREMENT
+static inline uint64_t
+dict_next_version(PyInterpreterState *interp)
+{
+ PyThreadState *tstate = PyThreadState_GET();
+ uint64_t cur_progress = (tstate->dict_global_version &
+ (THREAD_LOCAL_DICT_VERSION_BATCH - 1));
+ if (cur_progress == 0) {
+ uint64_t next = _Py_atomic_add_uint64(&interp->dict_state.global_version,
+ THREAD_LOCAL_DICT_VERSION_BATCH);
+ tstate->dict_global_version = next;
+ }
+ return tstate->dict_global_version += DICT_VERSION_INCREMENT;
+}
+
+#define DICT_NEXT_VERSION(INTERP) dict_next_version(INTERP)
+
+#else
#define DICT_NEXT_VERSION(INTERP) \
((INTERP)->dict_state.global_version += DICT_VERSION_INCREMENT)
+#endif
void
_PyDict_SendEvent(int watcher_bits,
@@ -167,32 +270,70 @@ _PyDict_NotifyEvent(PyInterpreterState *interp,
PyObject *value)
{
assert(Py_REFCNT((PyObject*)mp) > 0);
- int watcher_bits = mp->ma_version_tag & DICT_VERSION_MASK;
+ int watcher_bits = mp->ma_version_tag & DICT_WATCHER_MASK;
if (watcher_bits) {
+ RARE_EVENT_STAT_INC(watched_dict_modification);
_PyDict_SendEvent(watcher_bits, event, mp, key, value);
- return DICT_NEXT_VERSION(interp) | watcher_bits;
}
- return DICT_NEXT_VERSION(interp);
+ return DICT_NEXT_VERSION(interp) | (mp->ma_version_tag & DICT_WATCHER_AND_MODIFICATION_MASK);
}
-extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values);
-extern PyObject *_PyDict_FromItems(
+extern PyDictObject *_PyObject_MaterializeManagedDict(PyObject *obj);
+
+PyAPI_FUNC(PyObject *)_PyDict_FromItems(
PyObject *const *keys, Py_ssize_t keys_offset,
PyObject *const *values, Py_ssize_t values_offset,
Py_ssize_t length);
+static inline uint8_t *
+get_insertion_order_array(PyDictValues *values)
+{
+ return (uint8_t *)&values->values[values->capacity];
+}
+
static inline void
_PyDictValues_AddToInsertionOrder(PyDictValues *values, Py_ssize_t ix)
{
assert(ix < SHARED_KEYS_MAX_SIZE);
- uint8_t *size_ptr = ((uint8_t *)values)-2;
- int size = *size_ptr;
- assert(size+2 < ((uint8_t *)values)[-1]);
- size++;
- size_ptr[-size] = (uint8_t)ix;
- *size_ptr = size;
+ int size = values->size;
+ uint8_t *array = get_insertion_order_array(values);
+ assert(size < values->capacity);
+ assert(((uint8_t)ix) == ix);
+ array[size] = (uint8_t)ix;
+ values->size = size+1;
+}
+
+static inline size_t
+shared_keys_usable_size(PyDictKeysObject *keys)
+{
+ // dk_usable will decrease for each instance that is created and each
+ // value that is added. dk_nentries will increase for each value that
+ // is added. We want to always return the right value or larger.
+ // We therefore increase dk_nentries first and we decrease dk_usable
+ // second, and conversely here we read dk_usable first and dk_entries
+ // second (to avoid the case where we read entries before the increment
+ // and read usable after the decrement)
+ Py_ssize_t dk_usable = FT_ATOMIC_LOAD_SSIZE_ACQUIRE(keys->dk_usable);
+ Py_ssize_t dk_nentries = FT_ATOMIC_LOAD_SSIZE_ACQUIRE(keys->dk_nentries);
+ return dk_nentries + dk_usable;
}
+static inline size_t
+_PyInlineValuesSize(PyTypeObject *tp)
+{
+ PyDictKeysObject *keys = ((PyHeapTypeObject*)tp)->ht_cached_keys;
+ assert(keys != NULL);
+ size_t size = shared_keys_usable_size(keys);
+ size_t prefix_size = _Py_SIZE_ROUND_UP(size, sizeof(PyObject *));
+ assert(prefix_size < 256);
+ return prefix_size + (size + 1) * sizeof(PyObject *);
+}
+
+int
+_PyDict_DetachFromObject(PyDictObject *dict, PyObject *obj);
+
+PyDictObject *_PyObject_MaterializeManagedDict_LockHeld(PyObject *);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_dict_state.h b/contrib/tools/python3/Include/internal/pycore_dict_state.h
index ece0f10ca25..1a44755c7a0 100644
--- a/contrib/tools/python3/Include/internal/pycore_dict_state.h
+++ b/contrib/tools/python3/Include/internal/pycore_dict_state.h
@@ -8,17 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-
-#ifndef WITH_FREELISTS
-// without freelists
-# define PyDict_MAXFREELIST 0
-#endif
-
-#ifndef PyDict_MAXFREELIST
-# define PyDict_MAXFREELIST 80
-#endif
-
#define DICT_MAX_WATCHERS 8
+#define DICT_WATCHED_MUTATION_BITS 4
struct _Py_dict_state {
/*Global counter used to set ma_version_tag field of dictionary.
@@ -26,15 +17,6 @@ struct _Py_dict_state {
* time that a dictionary is modified. */
uint64_t global_version;
uint32_t next_keys_version;
-
-#if PyDict_MAXFREELIST > 0
- /* Dictionary reuse scheme to save calls to malloc and free */
- PyDictObject *free_list[PyDict_MAXFREELIST];
- PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
- int numfree;
- int keys_numfree;
-#endif
-
PyDict_WatchCallback watchers[DICT_MAX_WATCHERS];
};
diff --git a/contrib/tools/python3/Include/internal/pycore_dtoa.h b/contrib/tools/python3/Include/internal/pycore_dtoa.h
index 899d413b05e..e4222c5267d 100644
--- a/contrib/tools/python3/Include/internal/pycore_dtoa.h
+++ b/contrib/tools/python3/Include/internal/pycore_dtoa.h
@@ -33,6 +33,9 @@ struct _dtoa_state {
/* The size of the Bigint freelist */
#define Bigint_Kmax 7
+/* The size of the cached powers of 5 array */
+#define Bigint_Pow5size 8
+
#ifndef PRIVATE_MEM
#define PRIVATE_MEM 2304
#endif
@@ -40,9 +43,10 @@ struct _dtoa_state {
((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
struct _dtoa_state {
- /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
+ // p5s is an array of powers of 5 of the form:
+ // 5**(2**(i+2)) for 0 <= i < Bigint_Pow5size
+ struct Bigint *p5s[Bigint_Pow5size];
// XXX This should be freed during runtime fini.
- struct Bigint *p5s;
struct Bigint *freelist[Bigint_Kmax+1];
double preallocated[Bigint_PREALLOC_SIZE];
double *preallocated_next;
@@ -55,13 +59,15 @@ struct _dtoa_state {
#endif // !Py_USING_MEMORY_DEBUGGER
-/* These functions are used by modules compiled as C extension like math:
- they must be exported. */
+extern double _Py_dg_strtod(const char *str, char **ptr);
+extern char* _Py_dg_dtoa(double d, int mode, int ndigits,
+ int *decpt, int *sign, char **rve);
+extern void _Py_dg_freedtoa(char *s);
+
+
+extern PyStatus _PyDtoa_Init(PyInterpreterState *interp);
+extern void _PyDtoa_Fini(PyInterpreterState *interp);
-PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr);
-PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits,
- int *decpt, int *sign, char **rve);
-PyAPI_FUNC(void) _Py_dg_freedtoa(char *s);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_emscripten_signal.h b/contrib/tools/python3/Include/internal/pycore_emscripten_signal.h
index 8b3287d85da..754193e21de 100644
--- a/contrib/tools/python3/Include/internal/pycore_emscripten_signal.h
+++ b/contrib/tools/python3/Include/internal/pycore_emscripten_signal.h
@@ -3,6 +3,10 @@
#if defined(__EMSCRIPTEN__)
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
void
_Py_CheckEmscriptenSignals(void);
@@ -14,6 +18,7 @@ _Py_CheckEmscriptenSignalsPeriodically(void);
#define _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY() _Py_CheckEmscriptenSignalsPeriodically()
extern int Py_EMSCRIPTEN_SIGNAL_HANDLING;
+extern int _Py_emscripten_signal_clock;
#else
diff --git a/contrib/tools/python3/Include/internal/pycore_emscripten_trampoline.h b/contrib/tools/python3/Include/internal/pycore_emscripten_trampoline.h
new file mode 100644
index 00000000000..e519c99ad86
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_emscripten_trampoline.h
@@ -0,0 +1,81 @@
+#ifndef Py_EMSCRIPTEN_TRAMPOLINE_H
+#define Py_EMSCRIPTEN_TRAMPOLINE_H
+
+#include "pycore_runtime.h" // _PyRuntimeState
+
+/**
+ * C function call trampolines to mitigate bad function pointer casts.
+ *
+ * Section 6.3.2.3, paragraph 8 reads:
+ *
+ * A pointer to a function of one type may be converted to a pointer to a
+ * function of another type and back again; the result shall compare equal to
+ * the original pointer. If a converted pointer is used to call a function
+ * whose type is not compatible with the pointed-to type, the behavior is
+ * undefined.
+ *
+ * Typical native ABIs ignore additional arguments or fill in missing values
+ * with 0/NULL in function pointer cast. Compilers do not show warnings when a
+ * function pointer is explicitly casted to an incompatible type.
+ *
+ * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict
+ * function signature checks. Argument count, types, and return type must match.
+ *
+ * Third party code unintentionally rely on problematic fpcasts. The call
+ * trampoline mitigates common occurrences of bad fpcasts on Emscripten.
+ */
+
+#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
+
+void _Py_EmscriptenTrampoline_Init(_PyRuntimeState *runtime);
+
+PyObject*
+_PyEM_TrampolineCall_JavaScript(PyCFunctionWithKeywords func,
+ PyObject* self,
+ PyObject* args,
+ PyObject* kw);
+
+PyObject*
+_PyEM_TrampolineCall_Reflection(PyCFunctionWithKeywords func,
+ PyObject* self,
+ PyObject* args,
+ PyObject* kw);
+
+#define _PyEM_TrampolineCall(meth, self, args, kw) \
+ ((_PyRuntime.wasm_type_reflection_available) ? \
+ (_PyEM_TrampolineCall_Reflection((PyCFunctionWithKeywords)(meth), (self), (args), (kw))) : \
+ (_PyEM_TrampolineCall_JavaScript((PyCFunctionWithKeywords)(meth), (self), (args), (kw))))
+
+#define _PyCFunction_TrampolineCall(meth, self, args) \
+ _PyEM_TrampolineCall( \
+ (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL)
+
+#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \
+ _PyEM_TrampolineCall((meth), (self), (args), (kw))
+
+#define descr_set_trampoline_call(set, obj, value, closure) \
+ ((int)_PyEM_TrampolineCall((PyCFunctionWithKeywords)(set), (obj), (value), (PyObject*)(closure)))
+
+#define descr_get_trampoline_call(get, obj, closure) \
+ _PyEM_TrampolineCall((PyCFunctionWithKeywords)(get), (obj), (PyObject*)(closure), NULL)
+
+
+#else // defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
+
+#define _Py_EmscriptenTrampoline_Init(runtime)
+
+#define _PyCFunction_TrampolineCall(meth, self, args) \
+ (meth)((self), (args))
+
+#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \
+ (meth)((self), (args), (kw))
+
+#define descr_set_trampoline_call(set, obj, value, closure) \
+ (set)((obj), (value), (closure))
+
+#define descr_get_trampoline_call(get, obj, closure) \
+ (get)((obj), (closure))
+
+#endif // defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
+
+#endif // ndef Py_EMSCRIPTEN_SIGNAL_H
diff --git a/contrib/tools/python3/Include/internal/pycore_exceptions.h b/contrib/tools/python3/Include/internal/pycore_exceptions.h
index 4a9df709131..26456d1966b 100644
--- a/contrib/tools/python3/Include/internal/pycore_exceptions.h
+++ b/contrib/tools/python3/Include/internal/pycore_exceptions.h
@@ -24,6 +24,9 @@ struct _Py_exc_state {
PyObject *errnomap;
PyBaseExceptionObject *memerrors_freelist;
int memerrors_numfree;
+#ifdef Py_GIL_DISABLED
+ PyMutex memerrors_lock;
+#endif
// The ExceptionGroup type
PyObject *PyExc_ExceptionGroup;
};
diff --git a/contrib/tools/python3/Include/internal/pycore_faulthandler.h b/contrib/tools/python3/Include/internal/pycore_faulthandler.h
index e6aec7745a6..6dd7d8d7ca9 100644
--- a/contrib/tools/python3/Include/internal/pycore_faulthandler.h
+++ b/contrib/tools/python3/Include/internal/pycore_faulthandler.h
@@ -9,7 +9,7 @@ extern "C" {
#endif
#ifdef HAVE_SIGACTION
-# include <signal.h>
+# include <signal.h> // sigaction
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_fileutils.h b/contrib/tools/python3/Include/internal/pycore_fileutils.h
index 7c2b6ec0bff..13f86b01bbf 100644
--- a/contrib/tools/python3/Include/internal/pycore_fileutils.h
+++ b/contrib/tools/python3/Include/internal/pycore_fileutils.h
@@ -5,12 +5,20 @@ extern "C" {
#endif
#ifndef Py_BUILD_CORE
-# error "Py_BUILD_CORE must be defined to include this header"
+# error "this header requires Py_BUILD_CORE define"
#endif
-#include <locale.h> /* struct lconv */
+#include <locale.h> // struct lconv
+/* A routine to check if a file descriptor can be select()-ed. */
+#ifdef _MSC_VER
+ /* On Windows, any socket fd can be select()-ed, no matter how high */
+ #define _PyIsSelectable_fd(FD) (1)
+#else
+ #define _PyIsSelectable_fd(FD) ((unsigned int)(FD) < (unsigned int)FD_SETSIZE)
+#endif
+
struct _fileutils_state {
int force_ascii;
};
@@ -27,8 +35,10 @@ typedef enum {
_Py_ERROR_OTHER
} _Py_error_handler;
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors);
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(int) _Py_DecodeLocaleEx(
const char *arg,
wchar_t **wstr,
@@ -37,6 +47,7 @@ PyAPI_FUNC(int) _Py_DecodeLocaleEx(
int current_locale,
_Py_error_handler errors);
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(int) _Py_EncodeLocaleEx(
const wchar_t *text,
char **str,
@@ -45,11 +56,11 @@ PyAPI_FUNC(int) _Py_EncodeLocaleEx(
int current_locale,
_Py_error_handler errors);
-PyAPI_FUNC(char*) _Py_EncodeLocaleRaw(
+extern char* _Py_EncodeLocaleRaw(
const wchar_t *text,
size_t *error_pos);
-PyAPI_FUNC(PyObject *) _Py_device_encoding(int);
+extern PyObject* _Py_device_encoding(int);
#if defined(MS_WINDOWS) || defined(__APPLE__)
/* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611).
@@ -90,47 +101,54 @@ struct _Py_stat_struct {
# define _Py_stat_struct stat
#endif
+// Export for 'mmap' shared extension
PyAPI_FUNC(int) _Py_fstat(
int fd,
struct _Py_stat_struct *status);
+// Export for 'mmap' shared extension
PyAPI_FUNC(int) _Py_fstat_noraise(
int fd,
struct _Py_stat_struct *status);
+// Export for '_tkinter' shared extension
PyAPI_FUNC(int) _Py_stat(
PyObject *path,
struct stat *status);
+// Export for 'select' shared extension (Solaris newDevPollObject())
PyAPI_FUNC(int) _Py_open(
const char *pathname,
int flags);
+// Export for '_posixsubprocess' shared extension
PyAPI_FUNC(int) _Py_open_noraise(
const char *pathname,
int flags);
-PyAPI_FUNC(FILE *) _Py_wfopen(
+extern FILE* _Py_wfopen(
const wchar_t *path,
const wchar_t *mode);
-PyAPI_FUNC(Py_ssize_t) _Py_read(
+extern Py_ssize_t _Py_read(
int fd,
void *buf,
size_t count);
+// Export for 'select' shared extension (Solaris devpoll_flush())
PyAPI_FUNC(Py_ssize_t) _Py_write(
int fd,
const void *buf,
size_t count);
+// Export for '_posixsubprocess' shared extension
PyAPI_FUNC(Py_ssize_t) _Py_write_noraise(
int fd,
const void *buf,
size_t count);
#ifdef HAVE_READLINK
-PyAPI_FUNC(int) _Py_wreadlink(
+extern int _Py_wreadlink(
const wchar_t *path,
wchar_t *buf,
/* Number of characters of 'buf' buffer
@@ -139,7 +157,7 @@ PyAPI_FUNC(int) _Py_wreadlink(
#endif
#ifdef HAVE_REALPATH
-PyAPI_FUNC(wchar_t*) _Py_wrealpath(
+extern wchar_t* _Py_wrealpath(
const wchar_t *path,
wchar_t *resolved_path,
/* Number of characters of 'resolved_path' buffer
@@ -147,34 +165,38 @@ PyAPI_FUNC(wchar_t*) _Py_wrealpath(
size_t resolved_path_len);
#endif
-PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
+extern wchar_t* _Py_wgetcwd(
wchar_t *buf,
/* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);
-PyAPI_FUNC(int) _Py_get_inheritable(int fd);
+extern int _Py_get_inheritable(int fd);
+// Export for '_socket' shared extension
PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable,
int *atomic_flag_works);
+// Export for '_posixsubprocess' shared extension
PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable,
int *atomic_flag_works);
+// Export for '_socket' shared extension
PyAPI_FUNC(int) _Py_dup(int fd);
-PyAPI_FUNC(int) _Py_get_blocking(int fd);
+extern int _Py_get_blocking(int fd);
-PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
+extern int _Py_set_blocking(int fd, int blocking);
#ifdef MS_WINDOWS
-PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd);
+extern void* _Py_get_osfhandle_noraise(int fd);
+// Export for '_testconsole' shared extension
PyAPI_FUNC(void*) _Py_get_osfhandle(int fd);
-PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags);
+extern int _Py_open_osfhandle_noraise(void *handle, int flags);
-PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags);
+extern int _Py_open_osfhandle(void *handle, int flags);
#endif /* MS_WINDOWS */
// This is used after getting NULL back from Py_DecodeLocale().
@@ -183,9 +205,9 @@ PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags);
? _PyStatus_ERR("cannot decode " NAME) \
: _PyStatus_NO_MEMORY()
-PyAPI_DATA(int) _Py_HasFileSystemDefaultEncodeErrors;
+extern int _Py_HasFileSystemDefaultEncodeErrors;
-PyAPI_FUNC(int) _Py_DecodeUTF8Ex(
+extern int _Py_DecodeUTF8Ex(
const char *arg,
Py_ssize_t arglen,
wchar_t **wstr,
@@ -193,7 +215,7 @@ PyAPI_FUNC(int) _Py_DecodeUTF8Ex(
const char **reason,
_Py_error_handler errors);
-PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
+extern int _Py_EncodeUTF8Ex(
const wchar_t *text,
char **str,
size_t *error_pos,
@@ -201,7 +223,7 @@ PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
int raw_malloc,
_Py_error_handler errors);
-PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(
+extern wchar_t* _Py_DecodeUTF8_surrogateescape(
const char *arg,
Py_ssize_t arglen,
size_t *wlen);
@@ -209,25 +231,26 @@ PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(
extern int
_Py_wstat(const wchar_t *, struct stat *);
-PyAPI_FUNC(int) _Py_GetForceASCII(void);
+extern int _Py_GetForceASCII(void);
/* Reset "force ASCII" mode (if it was initialized).
This function should be called when Python changes the LC_CTYPE locale,
so the "force ASCII" mode can be detected again on the new locale
encoding. */
-PyAPI_FUNC(void) _Py_ResetForceASCII(void);
+extern void _Py_ResetForceASCII(void);
-PyAPI_FUNC(int) _Py_GetLocaleconvNumeric(
+extern int _Py_GetLocaleconvNumeric(
struct lconv *lc,
PyObject **decimal_point,
PyObject **thousands_sep);
+// Export for '_posixsubprocess' (on macOS)
PyAPI_FUNC(void) _Py_closerange(int first, int last);
-PyAPI_FUNC(wchar_t*) _Py_GetLocaleEncoding(void);
-PyAPI_FUNC(PyObject*) _Py_GetLocaleEncodingObject(void);
+extern wchar_t* _Py_GetLocaleEncoding(void);
+extern PyObject* _Py_GetLocaleEncodingObject(void);
#ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
extern int _Py_LocaleUsesNonUnicodeWchar(void);
@@ -246,24 +269,29 @@ extern int _Py_abspath(const wchar_t *path, wchar_t **abspath_p);
#ifdef MS_WINDOWS
extern int _PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p);
#endif
-extern wchar_t * _Py_join_relfile(const wchar_t *dirname,
- const wchar_t *relfile);
+extern wchar_t* _Py_join_relfile(const wchar_t *dirname,
+ const wchar_t *relfile);
extern int _Py_add_relfile(wchar_t *dirname,
const wchar_t *relfile,
size_t bufsize);
extern size_t _Py_find_basename(const wchar_t *filename);
+
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(wchar_t*) _Py_normpath(wchar_t *path, Py_ssize_t size);
+
extern wchar_t *_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *length);
// The Windows Games API family does not provide these functions
// so provide our own implementations. Remove them in case they get added
// to the Games API family
#if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP)
-#include <winerror.h>
+#include <winerror.h> // HRESULT
extern HRESULT PathCchSkipRoot(const wchar_t *pszPath, const wchar_t **ppszRootEnd);
#endif /* defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) */
+extern void _Py_skiproot(const wchar_t *path, Py_ssize_t size, Py_ssize_t *drvsize, Py_ssize_t *rootsize);
+
// Macros to protect CRT calls against instant termination when passed an
// invalid parameter (bpo-23524). IPH stands for Invalid Parameter Handler.
// Usage:
@@ -286,6 +314,21 @@ extern HRESULT PathCchSkipRoot(const wchar_t *pszPath, const wchar_t **ppszRootE
# define _Py_END_SUPPRESS_IPH
#endif /* _MSC_VER >= 1900 */
+// Export for 'select' shared extension (Argument Clinic code)
+PyAPI_FUNC(int) _PyLong_FileDescriptor_Converter(PyObject *, void *);
+
+// Export for test_peg_generator
+PyAPI_FUNC(char*) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject *, size_t*);
+
+extern int _PyFile_Flush(PyObject *);
+
+#ifndef MS_WINDOWS
+extern int _Py_GetTicksPerSecond(long *ticks_per_second);
+#endif
+
+// Export for '_testcapi' shared extension
+PyAPI_FUNC(int) _Py_IsValidFD(int fd);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_fileutils_windows.h b/contrib/tools/python3/Include/internal/pycore_fileutils_windows.h
index e804d385e76..b79aa9fb465 100644
--- a/contrib/tools/python3/Include/internal/pycore_fileutils_windows.h
+++ b/contrib/tools/python3/Include/internal/pycore_fileutils_windows.h
@@ -5,7 +5,7 @@ extern "C" {
#endif
#ifndef Py_BUILD_CORE
-# error "Py_BUILD_CORE must be defined to include this header"
+# error "this header requires Py_BUILD_CORE define"
#endif
#ifdef MS_WINDOWS
diff --git a/contrib/tools/python3/Include/internal/pycore_floatobject.h b/contrib/tools/python3/Include/internal/pycore_floatobject.h
index 27c63bc87f3..f984df69569 100644
--- a/contrib/tools/python3/Include/internal/pycore_floatobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_floatobject.h
@@ -8,12 +8,13 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_freelist.h" // _PyFreeListState
+#include "pycore_unicodeobject.h" // _PyUnicodeWriter
/* runtime lifecycle */
extern void _PyFloat_InitState(PyInterpreterState *);
extern PyStatus _PyFloat_InitTypes(PyInterpreterState *);
-extern void _PyFloat_Fini(PyInterpreterState *);
extern void _PyFloat_FiniType(PyInterpreterState *);
@@ -31,40 +32,30 @@ struct _Py_float_runtime_state {
};
-#ifndef WITH_FREELISTS
-// without freelists
-# define PyFloat_MAXFREELIST 0
-#endif
-
-#ifndef PyFloat_MAXFREELIST
-# define PyFloat_MAXFREELIST 100
-#endif
-struct _Py_float_state {
-#if PyFloat_MAXFREELIST > 0
- /* Special free list
- free_list is a singly-linked list of available PyFloatObjects,
- linked via abuse of their ob_type members. */
- int numfree;
- PyFloatObject *free_list;
-#endif
-};
-void _PyFloat_ExactDealloc(PyObject *op);
+PyAPI_FUNC(void) _PyFloat_ExactDealloc(PyObject *op);
-PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out);
+extern void _PyFloat_DebugMallocStats(FILE* out);
/* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */
-PyAPI_FUNC(int) _PyFloat_FormatAdvancedWriter(
+extern int _PyFloat_FormatAdvancedWriter(
_PyUnicodeWriter *writer,
PyObject *obj,
PyObject *format_spec,
Py_ssize_t start,
Py_ssize_t end);
+extern PyObject* _Py_string_to_number_with_underscores(
+ const char *str, Py_ssize_t len, const char *what, PyObject *obj, void *arg,
+ PyObject *(*innerfunc)(const char *, Py_ssize_t, void *));
+
+extern double _Py_parse_inf_or_nan(const char *p, char **endptr);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_flowgraph.h b/contrib/tools/python3/Include/internal/pycore_flowgraph.h
index 98d3374a752..819117b8311 100644
--- a/contrib/tools/python3/Include/internal/pycore_flowgraph.h
+++ b/contrib/tools/python3/Include/internal/pycore_flowgraph.h
@@ -8,110 +8,30 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_opcode_utils.h"
#include "pycore_compile.h"
+#include "pycore_instruction_sequence.h"
+#include "pycore_opcode_utils.h"
+struct _PyCfgBuilder;
-typedef struct {
- int i_opcode;
- int i_oparg;
- _PyCompilerSrcLocation i_loc;
- struct _PyCfgBasicblock_ *i_target; /* target block (if jump instruction) */
- struct _PyCfgBasicblock_ *i_except; /* target block when exception is raised */
-} _PyCfgInstruction;
-
-typedef struct {
- int id;
-} _PyCfgJumpTargetLabel;
-
-
-typedef struct {
- struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+2];
- int depth;
-} _PyCfgExceptStack;
-
-typedef struct _PyCfgBasicblock_ {
- /* Each basicblock in a compilation unit is linked via b_list in the
- reverse order that the block are allocated. b_list points to the next
- block in this list, not to be confused with b_next, which is next by
- control flow. */
- struct _PyCfgBasicblock_ *b_list;
- /* The label of this block if it is a jump target, -1 otherwise */
- _PyCfgJumpTargetLabel b_label;
- /* Exception stack at start of block, used by assembler to create the exception handling table */
- _PyCfgExceptStack *b_exceptstack;
- /* pointer to an array of instructions, initially NULL */
- _PyCfgInstruction *b_instr;
- /* If b_next is non-NULL, it is a pointer to the next
- block reached by normal control flow. */
- struct _PyCfgBasicblock_ *b_next;
- /* number of instructions used */
- int b_iused;
- /* length of instruction array (b_instr) */
- int b_ialloc;
- /* Used by add_checks_for_loads_of_unknown_variables */
- uint64_t b_unsafe_locals_mask;
- /* Number of predecessors that a block has. */
- int b_predecessors;
- /* depth of stack upon entry of block, computed by stackdepth() */
- int b_startdepth;
- /* instruction offset for block, computed by assemble_jump_offsets() */
- int b_offset;
- /* Basic block is an exception handler that preserves lasti */
- unsigned b_preserve_lasti : 1;
- /* Used by compiler passes to mark whether they have visited a basic block. */
- unsigned b_visited : 1;
- /* b_except_handler is used by the cold-detection algorithm to mark exception targets */
- unsigned b_except_handler : 1;
- /* b_cold is true if this block is not perf critical (like an exception handler) */
- unsigned b_cold : 1;
- /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
- unsigned b_warm : 1;
-} _PyCfgBasicblock;
-
-int _PyBasicblock_InsertInstruction(_PyCfgBasicblock *block, int pos, _PyCfgInstruction *instr);
-
-typedef struct cfg_builder_ {
- /* The entryblock, at which control flow begins. All blocks of the
- CFG are reachable through the b_next links */
- _PyCfgBasicblock *g_entryblock;
- /* Pointer to the most recently allocated block. By following
- b_list links, you can reach all allocated blocks. */
- _PyCfgBasicblock *g_block_list;
- /* pointer to the block currently being constructed */
- _PyCfgBasicblock *g_curblock;
- /* label for the next instruction to be placed */
- _PyCfgJumpTargetLabel g_current_label;
-} _PyCfgBuilder;
-
-int _PyCfgBuilder_UseLabel(_PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl);
-int _PyCfgBuilder_Addop(_PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc);
-
-int _PyCfgBuilder_Init(_PyCfgBuilder *g);
-void _PyCfgBuilder_Fini(_PyCfgBuilder *g);
-
-_PyCfgInstruction* _PyCfg_BasicblockLastInstr(const _PyCfgBasicblock *b);
-int _PyCfg_OptimizeCodeUnit(_PyCfgBuilder *g, PyObject *consts, PyObject *const_cache,
- int code_flags, int nlocals, int nparams, int firstlineno);
-int _PyCfg_Stackdepth(_PyCfgBasicblock *entryblock, int code_flags);
-void _PyCfg_ConvertPseudoOps(_PyCfgBasicblock *entryblock);
-int _PyCfg_ResolveJumps(_PyCfgBuilder *g);
+int _PyCfgBuilder_UseLabel(struct _PyCfgBuilder *g, _PyJumpTargetLabel lbl);
+int _PyCfgBuilder_Addop(struct _PyCfgBuilder *g, int opcode, int oparg, _Py_SourceLocation loc);
+struct _PyCfgBuilder* _PyCfgBuilder_New(void);
+void _PyCfgBuilder_Free(struct _PyCfgBuilder *g);
+int _PyCfgBuilder_CheckSize(struct _PyCfgBuilder* g);
-static inline int
-basicblock_nofallthrough(const _PyCfgBasicblock *b) {
- _PyCfgInstruction *last = _PyCfg_BasicblockLastInstr(b);
- return (last &&
- (IS_SCOPE_EXIT_OPCODE(last->i_opcode) ||
- IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)));
-}
+int _PyCfg_OptimizeCodeUnit(struct _PyCfgBuilder *g, PyObject *consts, PyObject *const_cache,
+ int nlocals, int nparams, int firstlineno);
-#define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B))
-#define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B))
+int _PyCfg_ToInstructionSequence(struct _PyCfgBuilder *g, _PyInstructionSequence *seq);
+int _PyCfg_OptimizedCfgToInstructionSequence(struct _PyCfgBuilder *g, _PyCompile_CodeUnitMetadata *umd,
+ int code_flags, int *stackdepth, int *nlocalsplus,
+ _PyInstructionSequence *seq);
PyCodeObject *
_PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *u, PyObject *const_cache,
- PyObject *consts, int maxdepth, _PyCompile_InstructionSequence *instrs,
+ PyObject *consts, int maxdepth, _PyInstructionSequence *instrs,
int nlocalsplus, int code_flags, PyObject *filename);
#ifdef __cplusplus
diff --git a/contrib/tools/python3/Include/internal/pycore_frame.h b/contrib/tools/python3/Include/internal/pycore_frame.h
index 4d355b2bc8d..a6bd971ea0c 100644
--- a/contrib/tools/python3/Include/internal/pycore_frame.h
+++ b/contrib/tools/python3/Include/internal/pycore_frame.h
@@ -4,9 +4,14 @@
extern "C" {
#endif
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
#include <stdbool.h>
-#include <stddef.h>
-#include "pycore_code.h" // STATS
+#include <stddef.h> // offsetof()
+#include "pycore_code.h" // STATS
+#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
/* See Objects/frame_layout.md for an explanation of the frame stack
* including explanation of the PyFrameObject and _PyInterpreterFrame
@@ -21,7 +26,11 @@ struct _frame {
int f_lineno; /* Current line number. Only valid if non-zero */
char f_trace_lines; /* Emit per-line trace events? */
char f_trace_opcodes; /* Emit per-opcode trace events? */
- char f_fast_as_locals; /* Have the fast locals of this frame been converted to a dict? */
+ PyObject *f_extra_locals; /* Dict for locals set by users using f_locals, could be NULL */
+ /* This is purely for backwards compatibility for PyEval_GetLocals.
+ PyEval_GetLocals requires a borrowed reference so the actual reference
+ is stored here */
+ PyObject *f_locals_cache;
/* The frame data, if this frame object owns the frame */
PyObject *_f_frame_data[1];
};
@@ -32,13 +41,15 @@ extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code);
/* other API */
typedef enum _framestate {
- FRAME_CREATED = -2,
- FRAME_SUSPENDED = -1,
+ FRAME_CREATED = -3,
+ FRAME_SUSPENDED = -2,
+ FRAME_SUSPENDED_YIELD_FROM = -1,
FRAME_EXECUTING = 0,
FRAME_COMPLETED = 1,
FRAME_CLEARED = 4
} PyFrameState;
+#define FRAME_STATE_SUSPENDED(S) ((S) == FRAME_SUSPENDED || (S) == FRAME_SUSPENDED_YIELD_FROM)
#define FRAME_STATE_FINISHED(S) ((S) >= FRAME_COMPLETED)
enum _frameowner {
@@ -49,46 +60,64 @@ enum _frameowner {
};
typedef struct _PyInterpreterFrame {
- PyCodeObject *f_code; /* Strong reference */
+ PyObject *f_executable; /* Strong reference (code object or None) */
struct _PyInterpreterFrame *previous;
PyObject *f_funcobj; /* Strong reference. Only valid if not on C stack */
PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */
PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */
PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */
PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */
- // NOTE: This is not necessarily the last instruction started in the given
- // frame. Rather, it is the code unit *prior to* the *next* instruction. For
- // example, it may be an inline CACHE entry, an instruction we just jumped
- // over, or (in the case of a newly-created frame) a totally invalid value:
- _Py_CODEUNIT *prev_instr;
+ _Py_CODEUNIT *instr_ptr; /* Instruction currently executing (or about to begin) */
int stacktop; /* Offset of TOS from localsplus */
- /* The return_offset determines where a `RETURN` should go in the caller,
- * relative to `prev_instr`.
- * It is only meaningful to the callee,
- * so it needs to be set in any CALL (to a Python function)
- * or SEND (to a coroutine or generator).
- * If there is no callee, then it is meaningless. */
- uint16_t return_offset;
+ uint16_t return_offset; /* Only relevant during a function call */
char owner;
/* Locals and stack */
PyObject *localsplus[1];
} _PyInterpreterFrame;
#define _PyInterpreterFrame_LASTI(IF) \
- ((int)((IF)->prev_instr - _PyCode_CODE((IF)->f_code)))
+ ((int)((IF)->instr_ptr - _PyCode_CODE(_PyFrame_GetCode(IF))))
+
+static inline PyCodeObject *_PyFrame_GetCode(_PyInterpreterFrame *f) {
+ assert(PyCode_Check(f->f_executable));
+ return (PyCodeObject *)f->f_executable;
+}
+
+// Similar to _PyFrame_GetCode(), but return NULL if the frame is invalid or
+// freed. Used by dump_frame() in Python/traceback.c. The function uses
+// heuristics to detect freed memory, it's not 100% reliable.
+static inline PyCodeObject*
+_PyFrame_SafeGetCode(_PyInterpreterFrame *f)
+{
+ // globals and builtins may be NULL on a legit frame, but it's unlikely.
+ // It's more likely that it's a sign of an invalid frame.
+ if (f->f_globals == NULL || f->f_builtins == NULL) {
+ return NULL;
+ }
+
+ PyObject *executable = f->f_executable;
+ // Reimplement _PyObject_IsFreed() to avoid pycore_object.h dependency
+ if (_PyMem_IsPtrFreed(executable) || _PyMem_IsPtrFreed(Py_TYPE(executable))) {
+ return NULL;
+ }
+ if (!PyCode_Check(executable)) {
+ return NULL;
+ }
+ return (PyCodeObject *)executable;
+}
static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) {
- return f->localsplus + f->f_code->co_nlocalsplus;
+ return f->localsplus + _PyFrame_GetCode(f)->co_nlocalsplus;
}
static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) {
- assert(f->stacktop > f->f_code->co_nlocalsplus);
+ assert(f->stacktop > _PyFrame_GetCode(f)->co_nlocalsplus);
assert(f->localsplus[f->stacktop-1] != NULL);
return f->localsplus[f->stacktop-1];
}
static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) {
- assert(f->stacktop > f->f_code->co_nlocalsplus);
+ assert(f->stacktop > _PyFrame_GetCode(f)->co_nlocalsplus);
f->stacktop--;
return f->localsplus[f->stacktop];
}
@@ -109,7 +138,33 @@ _PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
return code->co_framesize - FRAME_SPECIALS_SIZE;
}
-void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest);
+static inline void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
+{
+ assert(src->stacktop >= _PyFrame_GetCode(src)->co_nlocalsplus);
+ *dest = *src;
+ for (int i = 1; i < src->stacktop; i++) {
+ dest->localsplus[i] = src->localsplus[i];
+ }
+ // Don't leave a dangling pointer to the old frame when creating generators
+ // and coroutines:
+ dest->previous = NULL;
+}
+
+// Similar to PyUnstable_InterpreterFrame_GetLasti(), but return NULL if the
+// frame is invalid or freed. Used by dump_frame() in Python/traceback.c. The
+// function uses heuristics to detect freed memory, it's not 100% reliable.
+static inline int
+_PyFrame_SafeGetLasti(struct _PyInterpreterFrame *f)
+{
+ // Code based on _PyFrame_GetBytecode() but replace _PyFrame_GetCode()
+ // with _PyFrame_SafeGetCode().
+ PyCodeObject *co = _PyFrame_SafeGetCode(f);
+ if (co == NULL) {
+ return -1;
+ }
+
+ return (int)(f->instr_ptr - _PyCode_CODE(co)) * sizeof(_Py_CODEUNIT);
+}
/* Consumes reference to func and locals.
Does not initialize frame->previous, which happens
@@ -121,13 +176,13 @@ _PyFrame_Initialize(
PyObject *locals, PyCodeObject *code, int null_locals_from)
{
frame->f_funcobj = (PyObject *)func;
- frame->f_code = (PyCodeObject *)Py_NewRef(code);
+ frame->f_executable = Py_NewRef(code);
frame->f_builtins = func->func_builtins;
frame->f_globals = func->func_globals;
frame->f_locals = locals;
frame->stacktop = code->co_nlocalsplus;
frame->frame_obj = NULL;
- frame->prev_instr = _PyCode_CODE(code) - 1;
+ frame->instr_ptr = _PyCode_CODE(code);
frame->return_offset = 0;
frame->owner = FRAME_OWNED_BY_THREAD;
@@ -174,8 +229,11 @@ _PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer)
static inline bool
_PyFrame_IsIncomplete(_PyInterpreterFrame *frame)
{
+ if (frame->owner == FRAME_OWNED_BY_CSTACK) {
+ return true;
+ }
return frame->owner != FRAME_OWNED_BY_GENERATOR &&
- frame->prev_instr < _PyCode_CODE(frame->f_code) + frame->f_code->_co_firsttraceable;
+ frame->instr_ptr < _PyCode_CODE(_PyFrame_GetCode(frame)) + _PyFrame_GetCode(frame)->_co_firsttraceable;
}
static inline _PyInterpreterFrame *
@@ -190,7 +248,7 @@ _PyFrame_GetFirstComplete(_PyInterpreterFrame *frame)
static inline _PyInterpreterFrame *
_PyThreadState_GetFrame(PyThreadState *tstate)
{
- return _PyFrame_GetFirstComplete(tstate->cframe->current_frame);
+ return _PyFrame_GetFirstComplete(tstate->current_frame);
}
/* For use by _PyFrame_GetFrameObject
@@ -213,6 +271,9 @@ _PyFrame_GetFrameObject(_PyInterpreterFrame *frame)
return _PyFrame_MakeAndSetFrameObject(frame);
}
+void
+_PyFrame_ClearLocals(_PyInterpreterFrame *frame);
+
/* Clears all references in the frame.
* If take is non-zero, then the _PyInterpreterFrame frame
* may be transferred to the frame object it references
@@ -228,14 +289,11 @@ _PyFrame_ClearExceptCode(_PyInterpreterFrame * frame);
int
_PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg);
-PyObject *
-_PyFrame_GetLocals(_PyInterpreterFrame *frame, int include_hidden);
-
-int
-_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame);
+bool
+_PyFrame_HasHiddenLocals(_PyInterpreterFrame *frame);
-void
-_PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear);
+PyObject *
+_PyFrame_GetLocals(_PyInterpreterFrame *frame);
static inline bool
_PyThreadState_HasStackSpace(PyThreadState *tstate, int size)
@@ -252,7 +310,7 @@ _PyThreadState_HasStackSpace(PyThreadState *tstate, int size)
extern _PyInterpreterFrame *
_PyThreadState_PushFrame(PyThreadState *tstate, size_t size);
-void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
+PyAPI_FUNC(void) _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame);
/* Pushes a frame without checking for space.
* Must be guarded by _PyThreadState_HasStackSpace()
@@ -269,6 +327,30 @@ _PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_l
return new_frame;
}
+/* Pushes a trampoline frame without checking for space.
+ * Must be guarded by _PyThreadState_HasStackSpace() */
+static inline _PyInterpreterFrame *
+_PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int stackdepth)
+{
+ CALL_STAT_INC(frames_pushed);
+ _PyInterpreterFrame *frame = (_PyInterpreterFrame *)tstate->datastack_top;
+ tstate->datastack_top += code->co_framesize;
+ assert(tstate->datastack_top < tstate->datastack_limit);
+ frame->f_funcobj = Py_None;
+ frame->f_executable = Py_NewRef(code);
+#ifdef Py_DEBUG
+ frame->f_builtins = NULL;
+ frame->f_globals = NULL;
+#endif
+ frame->f_locals = NULL;
+ frame->stacktop = code->co_nlocalsplus + stackdepth;
+ frame->frame_obj = NULL;
+ frame->instr_ptr = _PyCode_CODE(code);
+ frame->owner = FRAME_OWNED_BY_THREAD;
+ frame->return_offset = 0;
+ return frame;
+}
+
static inline
PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
{
@@ -277,6 +359,11 @@ PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
return (PyGenObject *)(((char *)frame) - offset_in_gen);
}
+PyAPI_FUNC(_PyInterpreterFrame *)
+_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
+ PyObject *locals, PyObject* const* args,
+ size_t argcount, PyObject *kwnames);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_freelist.h b/contrib/tools/python3/Include/internal/pycore_freelist.h
new file mode 100644
index 00000000000..e684e084b8b
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_freelist.h
@@ -0,0 +1,153 @@
+#ifndef Py_INTERNAL_FREELIST_H
+#define Py_INTERNAL_FREELIST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+// PyTuple_MAXSAVESIZE - largest tuple to save on free list
+// PyTuple_MAXFREELIST - maximum number of tuples of each size to save
+
+#ifdef WITH_FREELISTS
+// with freelists
+# define PyTuple_MAXSAVESIZE 20
+# define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE
+# define PyTuple_MAXFREELIST 2000
+# define PyList_MAXFREELIST 80
+# define PyDict_MAXFREELIST 80
+# define PyFloat_MAXFREELIST 100
+# define PyContext_MAXFREELIST 255
+# define _PyAsyncGen_MAXFREELIST 80
+# define _PyObjectStackChunk_MAXFREELIST 4
+#else
+# define PyTuple_NFREELISTS 0
+# define PyTuple_MAXFREELIST 0
+# define PyList_MAXFREELIST 0
+# define PyDict_MAXFREELIST 0
+# define PyFloat_MAXFREELIST 0
+# define PyContext_MAXFREELIST 0
+# define _PyAsyncGen_MAXFREELIST 0
+# define _PyObjectStackChunk_MAXFREELIST 0
+#endif
+
+struct _Py_list_freelist {
+#ifdef WITH_FREELISTS
+ PyListObject *items[PyList_MAXFREELIST];
+ int numfree;
+#endif
+};
+
+struct _Py_tuple_freelist {
+#if WITH_FREELISTS
+ /* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE.
+ The empty tuple is handled separately.
+
+ Each tuple stored in the array is the head of the linked list
+ (and the next available tuple) for that size. The actual tuple
+ object is used as the linked list node, with its first item
+ (ob_item[0]) pointing to the next node (i.e. the previous head).
+ Each linked list is initially NULL. */
+ PyTupleObject *items[PyTuple_NFREELISTS];
+ int numfree[PyTuple_NFREELISTS];
+#else
+ char _unused; // Empty structs are not allowed.
+#endif
+};
+
+struct _Py_float_freelist {
+#ifdef WITH_FREELISTS
+ /* Special free list
+ free_list is a singly-linked list of available PyFloatObjects,
+ linked via abuse of their ob_type members. */
+ int numfree;
+ PyFloatObject *items;
+#endif
+};
+
+struct _Py_dict_freelist {
+#ifdef WITH_FREELISTS
+ /* Dictionary reuse scheme to save calls to malloc and free */
+ PyDictObject *items[PyDict_MAXFREELIST];
+ int numfree;
+#endif
+};
+
+struct _Py_dictkeys_freelist {
+#ifdef WITH_FREELISTS
+ /* Dictionary keys reuse scheme to save calls to malloc and free */
+ PyDictKeysObject *items[PyDict_MAXFREELIST];
+ int numfree;
+#endif
+};
+
+struct _Py_slice_freelist {
+#ifdef WITH_FREELISTS
+ /* Using a cache is very effective since typically only a single slice is
+ created and then deleted again. */
+ PySliceObject *slice_cache;
+#endif
+};
+
+struct _Py_context_freelist {
+#ifdef WITH_FREELISTS
+ // List of free PyContext objects
+ PyContext *items;
+ int numfree;
+#endif
+};
+
+struct _Py_async_gen_freelist {
+#ifdef WITH_FREELISTS
+ /* Freelists boost performance 6-10%; they also reduce memory
+ fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
+ are short-living objects that are instantiated for every
+ __anext__() call. */
+ struct _PyAsyncGenWrappedValue* items[_PyAsyncGen_MAXFREELIST];
+ int numfree;
+#endif
+};
+
+struct _Py_async_gen_asend_freelist {
+#ifdef WITH_FREELISTS
+ struct PyAsyncGenASend* items[_PyAsyncGen_MAXFREELIST];
+ int numfree;
+#endif
+};
+
+struct _PyObjectStackChunk;
+
+struct _Py_object_stack_freelist {
+ struct _PyObjectStackChunk *items;
+ Py_ssize_t numfree;
+};
+
+struct _Py_object_freelists {
+ struct _Py_float_freelist floats;
+ struct _Py_tuple_freelist tuples;
+ struct _Py_list_freelist lists;
+ struct _Py_dict_freelist dicts;
+ struct _Py_dictkeys_freelist dictkeys;
+ struct _Py_slice_freelist slices;
+ struct _Py_context_freelist contexts;
+ struct _Py_async_gen_freelist async_gens;
+ struct _Py_async_gen_asend_freelist async_gen_asends;
+ struct _Py_object_stack_freelist object_stacks;
+};
+
+extern void _PyObject_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PyTuple_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PyFloat_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PyList_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PySlice_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PyDict_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PyAsyncGen_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PyContext_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
+extern void _PyObjectStackChunk_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_FREELIST_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_function.h b/contrib/tools/python3/Include/internal/pycore_function.h
index ecbb7001e7d..6d44e933e8a 100644
--- a/contrib/tools/python3/Include/internal/pycore_function.h
+++ b/contrib/tools/python3/Include/internal/pycore_function.h
@@ -4,19 +4,48 @@
extern "C" {
#endif
+#include "pycore_lock.h"
+
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
+extern PyObject* _PyFunction_Vectorcall(
+ PyObject *func,
+ PyObject *const *stack,
+ size_t nargsf,
+ PyObject *kwnames);
+
#define FUNC_MAX_WATCHERS 8
+#define FUNC_VERSION_CACHE_SIZE (1<<12) /* Must be a power of 2 */
+
+struct _func_version_cache_item {
+ PyFunctionObject *func;
+ PyObject *code;
+};
+
struct _py_func_state {
+#ifdef Py_GIL_DISABLED
+ // Protects next_version
+ PyMutex mutex;
+#endif
+
uint32_t next_version;
+ // Borrowed references to function and code objects whose
+ // func_version % FUNC_VERSION_CACHE_SIZE
+ // once was equal to the index in the table.
+ // They are cleared when the function or code object is deallocated.
+ struct _func_version_cache_item func_version_cache[FUNC_VERSION_CACHE_SIZE];
};
extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr);
extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func);
+PyAPI_FUNC(void) _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version);
+void _PyFunction_ClearCodeByVersion(uint32_t version);
+PyFunctionObject *_PyFunction_LookupByVersion(uint32_t version, PyObject **p_code);
+
extern PyObject *_Py_set_function_type_params(
PyThreadState* unused, PyObject *func, PyObject *type_params);
diff --git a/contrib/tools/python3/Include/internal/pycore_gc.h b/contrib/tools/python3/Include/internal/pycore_gc.h
index b3abe2030a0..357177bcd6f 100644
--- a/contrib/tools/python3/Include/internal/pycore_gc.h
+++ b/contrib/tools/python3/Include/internal/pycore_gc.h
@@ -8,6 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_freelist.h" // _PyFreeListState
+
/* GC information is stored BEFORE the object structure. */
typedef struct {
// Pointer to next object in the list.
@@ -19,15 +21,73 @@ typedef struct {
uintptr_t _gc_prev;
} PyGC_Head;
+#define _PyGC_Head_UNUSED PyGC_Head
+
+
+/* Get an object's GC head */
static inline PyGC_Head* _Py_AS_GC(PyObject *op) {
- return (_Py_CAST(PyGC_Head*, op) - 1);
+ char *gc = ((char*)op) - sizeof(PyGC_Head);
+ return (PyGC_Head*)gc;
+}
+
+/* Get the object given the GC head */
+static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) {
+ char *op = ((char *)gc) + sizeof(PyGC_Head);
+ return (PyObject *)op;
+}
+
+
+/* Bit flags for ob_gc_bits (in Py_GIL_DISABLED builds)
+ *
+ * Setting the bits requires a relaxed store. The per-object lock must also be
+ * held, except when the object is only visible to a single thread (e.g. during
+ * object initialization or destruction).
+ *
+ * Reading the bits requires using a relaxed load, but does not require holding
+ * the per-object lock.
+ */
+#ifdef Py_GIL_DISABLED
+# define _PyGC_BITS_TRACKED (1) // Tracked by the GC
+# define _PyGC_BITS_FINALIZED (2) // tp_finalize was called
+# define _PyGC_BITS_UNREACHABLE (4)
+# define _PyGC_BITS_FROZEN (8)
+# define _PyGC_BITS_SHARED (16)
+# define _PyGC_BITS_SHARED_INLINE (32)
+# define _PyGC_BITS_DEFERRED (64) // Use deferred reference counting
+#endif
+
+#ifdef Py_GIL_DISABLED
+
+static inline void
+_PyObject_SET_GC_BITS(PyObject *op, uint8_t new_bits)
+{
+ uint8_t bits = _Py_atomic_load_uint8_relaxed(&op->ob_gc_bits);
+ _Py_atomic_store_uint8_relaxed(&op->ob_gc_bits, bits | new_bits);
+}
+
+static inline int
+_PyObject_HAS_GC_BITS(PyObject *op, uint8_t bits)
+{
+ return (_Py_atomic_load_uint8_relaxed(&op->ob_gc_bits) & bits) != 0;
+}
+
+static inline void
+_PyObject_CLEAR_GC_BITS(PyObject *op, uint8_t bits_to_clear)
+{
+ uint8_t bits = _Py_atomic_load_uint8_relaxed(&op->ob_gc_bits);
+ _Py_atomic_store_uint8_relaxed(&op->ob_gc_bits, bits & ~bits_to_clear);
}
-#define _PyGC_Head_UNUSED PyGC_Head
+
+#endif
/* True if the object is currently tracked by the GC. */
static inline int _PyObject_GC_IS_TRACKED(PyObject *op) {
+#ifdef Py_GIL_DISABLED
+ return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_TRACKED);
+#else
PyGC_Head *gc = _Py_AS_GC(op);
return (gc->_gc_next != 0);
+#endif
}
#define _PyObject_GC_IS_TRACKED(op) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op))
@@ -43,6 +103,42 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
return 1;
}
+#ifdef Py_GIL_DISABLED
+
+/* True if memory the object references is shared between
+ * multiple threads and needs special purpose when freeing
+ * those references due to the possibility of in-flight
+ * lock-free reads occurring. The object is responsible
+ * for calling _PyMem_FreeDelayed on the referenced
+ * memory. */
+static inline int _PyObject_GC_IS_SHARED(PyObject *op) {
+ return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_SHARED);
+}
+#define _PyObject_GC_IS_SHARED(op) _PyObject_GC_IS_SHARED(_Py_CAST(PyObject*, op))
+
+static inline void _PyObject_GC_SET_SHARED(PyObject *op) {
+ _PyObject_SET_GC_BITS(op, _PyGC_BITS_SHARED);
+}
+#define _PyObject_GC_SET_SHARED(op) _PyObject_GC_SET_SHARED(_Py_CAST(PyObject*, op))
+
+/* True if the memory of the object is shared between multiple
+ * threads and needs special purpose when freeing due to
+ * the possibility of in-flight lock-free reads occurring.
+ * Objects with this bit that are GC objects will automatically
+ * delay-freed by PyObject_GC_Del. */
+static inline int _PyObject_GC_IS_SHARED_INLINE(PyObject *op) {
+ return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_SHARED_INLINE);
+}
+#define _PyObject_GC_IS_SHARED_INLINE(op) \
+ _PyObject_GC_IS_SHARED_INLINE(_Py_CAST(PyObject*, op))
+
+static inline void _PyObject_GC_SET_SHARED_INLINE(PyObject *op) {
+ _PyObject_SET_GC_BITS(op, _PyGC_BITS_SHARED_INLINE);
+}
+#define _PyObject_GC_SET_SHARED_INLINE(op) \
+ _PyObject_GC_SET_SHARED_INLINE(_Py_CAST(PyObject*, op))
+
+#endif
/* Bit flags for _gc_prev */
/* Bit 0 is set when tp_finalize is called */
@@ -53,41 +149,70 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
#define _PyGC_PREV_SHIFT (2)
#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT)
+/* set for debugging information */
+#define _PyGC_DEBUG_STATS (1<<0) /* print collection statistics */
+#define _PyGC_DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
+#define _PyGC_DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
+#define _PyGC_DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
+#define _PyGC_DEBUG_LEAK _PyGC_DEBUG_COLLECTABLE | \
+ _PyGC_DEBUG_UNCOLLECTABLE | \
+ _PyGC_DEBUG_SAVEALL
+
+typedef enum {
+ // GC was triggered by heap allocation
+ _Py_GC_REASON_HEAP,
+
+ // GC was called during shutdown
+ _Py_GC_REASON_SHUTDOWN,
+
+ // GC was called by gc.collect() or PyGC_Collect()
+ _Py_GC_REASON_MANUAL
+} _PyGC_Reason;
+
// Lowest bit of _gc_next is used for flags only in GC.
// But it is always 0 for normal code.
static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
uintptr_t next = gc->_gc_next;
- return _Py_CAST(PyGC_Head*, next);
+ return (PyGC_Head*)next;
}
static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) {
- gc->_gc_next = _Py_CAST(uintptr_t, next);
+ gc->_gc_next = (uintptr_t)next;
}
// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) {
uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK);
- return _Py_CAST(PyGC_Head*, prev);
+ return (PyGC_Head*)prev;
}
static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) {
- uintptr_t uprev = _Py_CAST(uintptr_t, prev);
+ uintptr_t uprev = (uintptr_t)prev;
assert((uprev & ~_PyGC_PREV_MASK) == 0);
gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev);
}
-static inline int _PyGCHead_FINALIZED(PyGC_Head *gc) {
- return ((gc->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0);
-}
-static inline void _PyGCHead_SET_FINALIZED(PyGC_Head *gc) {
- gc->_gc_prev |= _PyGC_PREV_MASK_FINALIZED;
-}
-
static inline int _PyGC_FINALIZED(PyObject *op) {
+#ifdef Py_GIL_DISABLED
+ return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_FINALIZED);
+#else
PyGC_Head *gc = _Py_AS_GC(op);
- return _PyGCHead_FINALIZED(gc);
+ return ((gc->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0);
+#endif
}
static inline void _PyGC_SET_FINALIZED(PyObject *op) {
+#ifdef Py_GIL_DISABLED
+ _PyObject_SET_GC_BITS(op, _PyGC_BITS_FINALIZED);
+#else
PyGC_Head *gc = _Py_AS_GC(op);
- _PyGCHead_SET_FINALIZED(gc);
+ gc->_gc_prev |= _PyGC_PREV_MASK_FINALIZED;
+#endif
+}
+static inline void _PyGC_CLEAR_FINALIZED(PyObject *op) {
+#ifdef Py_GIL_DISABLED
+ _PyObject_CLEAR_GC_BITS(op, _PyGC_BITS_FINALIZED);
+#else
+ PyGC_Head *gc = _Py_AS_GC(op);
+ gc->_gc_prev &= ~_PyGC_PREV_MASK_FINALIZED;
+#endif
}
@@ -176,6 +301,7 @@ struct _gc_runtime_state {
PyObject *garbage;
/* a list of callbacks to be invoked when collection is performed */
PyObject *callbacks;
+
/* This is the number of objects that survived the last full
collection. It approximates the number of long lived objects
tracked by the GC.
@@ -187,24 +313,52 @@ struct _gc_runtime_state {
collections, and are awaiting to undergo a full collection for
the first time. */
Py_ssize_t long_lived_pending;
+
+#ifdef Py_GIL_DISABLED
+ /* gh-117783: Deferred reference counting is not fully implemented yet, so
+ as a temporary measure we treat objects using deferred reference
+ counting as immortal. The value may be zero, one, or a negative number:
+ 0: immortalize deferred RC objects once the first thread is created
+ 1: immortalize all deferred RC objects immediately
+ <0: suppressed; don't immortalize objects */
+ int immortalize;
+#endif
};
+#ifdef Py_GIL_DISABLED
+struct _gc_thread_state {
+ /* Thread-local allocation count. */
+ Py_ssize_t alloc_count;
+};
+#endif
+
extern void _PyGC_InitState(struct _gc_runtime_state *);
-extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
+extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation,
+ _PyGC_Reason reason);
+extern void _PyGC_CollectNoFail(PyThreadState *tstate);
+/* Freeze objects tracked by the GC and ignore them in future collections. */
+extern void _PyGC_Freeze(PyInterpreterState *interp);
+/* Unfreezes objects placing them in the oldest generation */
+extern void _PyGC_Unfreeze(PyInterpreterState *interp);
+/* Number of frozen objects */
+extern Py_ssize_t _PyGC_GetFreezeCount(PyInterpreterState *interp);
+
+extern PyObject *_PyGC_GetObjects(PyInterpreterState *interp, int generation);
+extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs);
// Functions to clear types free lists
-extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
-extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
-extern void _PyList_ClearFreeList(PyInterpreterState *interp);
-extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
-extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
-extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
-extern void _Py_ScheduleGC(PyInterpreterState *interp);
+extern void _PyGC_ClearAllFreeLists(PyInterpreterState *interp);
+extern void _Py_ScheduleGC(PyThreadState *tstate);
extern void _Py_RunGC(PyThreadState *tstate);
+#ifdef Py_GIL_DISABLED
+// gh-117783: Immortalize objects that use deferred reference counting
+extern void _PyGC_ImmortalizeDeferredObjects(PyInterpreterState *interp);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_genobject.h b/contrib/tools/python3/Include/internal/pycore_genobject.h
index dc60b4ca705..9463c822ad8 100644
--- a/contrib/tools/python3/Include/internal/pycore_genobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_genobject.h
@@ -8,40 +8,23 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-extern PyObject *_PyGen_yf(PyGenObject *);
-extern PyObject *_PyCoro_GetAwaitableIter(PyObject *o);
-extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *);
-
-/* runtime lifecycle */
+#include "pycore_freelist.h"
-extern void _PyAsyncGen_Fini(PyInterpreterState *);
+PyAPI_FUNC(PyObject *)_PyGen_yf(PyGenObject *);
+extern void _PyGen_Finalize(PyObject *self);
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *);
-/* other API */
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **);
-#ifndef WITH_FREELISTS
-// without freelists
-# define _PyAsyncGen_MAXFREELIST 0
-#endif
-
-#ifndef _PyAsyncGen_MAXFREELIST
-# define _PyAsyncGen_MAXFREELIST 80
-#endif
-
-struct _Py_async_gen_state {
-#if _PyAsyncGen_MAXFREELIST > 0
- /* Freelists boost performance 6-10%; they also reduce memory
- fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
- are short-living objects that are instantiated for every
- __anext__() call. */
- struct _PyAsyncGenWrappedValue* value_freelist[_PyAsyncGen_MAXFREELIST];
- int value_numfree;
-
- struct PyAsyncGenASend* asend_freelist[_PyAsyncGen_MAXFREELIST];
- int asend_numfree;
-#endif
-};
+PyAPI_FUNC(PyObject *)_PyCoro_GetAwaitableIter(PyObject *o);
+extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *);
+extern PyTypeObject _PyCoroWrapper_Type;
+extern PyTypeObject _PyAsyncGenWrappedValue_Type;
+extern PyTypeObject _PyAsyncGenAThrow_Type;
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_gil.h b/contrib/tools/python3/Include/internal/pycore_gil.h
index 8ebad37b686..a2de5077371 100644
--- a/contrib/tools/python3/Include/internal/pycore_gil.h
+++ b/contrib/tools/python3/Include/internal/pycore_gil.h
@@ -8,8 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_atomic.h" /* _Py_atomic_address */
-#include "pycore_condvar.h" /* PyCOND_T */
+#include "pycore_condvar.h" // PyCOND_T
#ifndef Py_HAVE_CONDVAR
# error You need either a POSIX-compatible or a Windows system!
@@ -21,14 +20,31 @@ extern "C" {
#define FORCE_SWITCHING
struct _gil_runtime_state {
+#ifdef Py_GIL_DISABLED
+ /* If this GIL is disabled, enabled == 0.
+
+ If this GIL is enabled transiently (most likely to initialize a module
+ of unknown safety), enabled indicates the number of active transient
+ requests.
+
+ If this GIL is enabled permanently, enabled == INT_MAX.
+
+ It must not be modified directly; use _PyEval_EnableGILTransiently(),
+ _PyEval_EnableGILPermanently(), and _PyEval_DisableGIL()
+
+ It is always read and written atomically, but a thread can assume its
+ value will be stable as long as that thread is attached or knows that no
+ other threads are attached (e.g., during a stop-the-world.). */
+ int enabled;
+#endif
/* microseconds (the Python API uses seconds, though) */
unsigned long interval;
/* Last PyThreadState holding / having held the GIL. This helps us
know whether anyone else was scheduled after we dropped the GIL. */
- _Py_atomic_address last_holder;
+ PyThreadState* last_holder;
/* Whether the GIL is already taken (-1 if uninitialized). This is
atomic because it can be read without any lock taken in ceval.c. */
- _Py_atomic_int locked;
+ int locked;
/* Number of GIL switches since the beginning. */
unsigned long switch_number;
/* This condition variable allows one or several threads to wait
diff --git a/contrib/tools/python3/Include/internal/pycore_global_objects.h b/contrib/tools/python3/Include/internal/pycore_global_objects.h
index 442f8516278..9d376e7db02 100644
--- a/contrib/tools/python3/Include/internal/pycore_global_objects.h
+++ b/contrib/tools/python3/Include/internal/pycore_global_objects.h
@@ -8,11 +8,11 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_hashtable.h" // _Py_hashtable_t
-#include "pycore_gc.h" // PyGC_Head
+#include "pycore_context.h" // _PyContextTokenMissing
+#include "pycore_gc.h" // _PyGC_Head_UNUSED
#include "pycore_global_strings.h" // struct _Py_global_strings
#include "pycore_hamt.h" // PyHamtNode_Bitmap
-#include "pycore_context.h" // _PyContextTokenMissing
+#include "pycore_hashtable.h" // _Py_hashtable_t
#include "pycore_typeobject.h" // pytype_slotdef
@@ -67,7 +67,7 @@ struct _Py_interp_cached_objects {
PyObject *interned_strings;
/* AST */
- PyObject *str_replace_inf;
+ PyObject *_unused_str_replace_inf; // kept in 3.13 for ABI compatibility
/* object.__reduce__ */
PyObject *objreduce;
diff --git a/contrib/tools/python3/Include/internal/pycore_global_objects_fini_generated.h b/contrib/tools/python3/Include/internal/pycore_global_objects_fini_generated.h
index 75765254ded..cd56ffde9e5 100644
--- a/contrib/tools/python3/Include/internal/pycore_global_objects_fini_generated.h
+++ b/contrib/tools/python3/Include/internal/pycore_global_objects_fini_generated.h
@@ -547,6 +547,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_lambda));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_listcomp));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_module));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_null));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_setcomp));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_string));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_unknown));
@@ -560,7 +561,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(json_decoder));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(kwdefaults));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(list_err));
- _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(shim_name));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(str_replace_inf));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(type_params));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(utf_8));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(CANCELLED));
@@ -586,7 +587,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__anext__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__annotations__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__args__));
- _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__asyncio_running_event_loop__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__await__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bases__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bool__));
@@ -618,6 +618,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__eq__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__exit__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__file__));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__firstlineno__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__float__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__floordiv__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__format__));
@@ -663,6 +664,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lshift__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lt__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__main__));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__match_args__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__matmul__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__missing__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mod__));
@@ -717,6 +719,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__slotnames__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__slots__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__spec__));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__static_attributes__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__str__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__sub__));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__subclasscheck__));
@@ -735,6 +738,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_abc_impl));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_abstract_));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_active));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_align_));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_annotation));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_anonymous_));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_argtypes_));
@@ -745,6 +749,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_check_retval_));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_dealloc_warn));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_feature_version));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_field_types));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_fields_));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_finalizing));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_find_and_load));
@@ -766,6 +771,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_showwarnmsg));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_shutdown));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_slotnames));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_strptime));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_strptime_datetime));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_swappedbytes_));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_type_));
@@ -774,12 +780,14 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_xoptions));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(abs_tol));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(access));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(aclose));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add_done_callback));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_child));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_parent));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(aggregate_class));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(alias));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(allow_code));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(append));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arg));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argdefs));
@@ -787,7 +795,9 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arguments));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argv));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(as_integer_ratio));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(asend));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ast));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(athrow));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(attribute));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(authorizer_callback));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(autocommit));
@@ -811,12 +821,14 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_call));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_exception));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_return));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cached_datetime_module));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cached_statements));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cadata));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cafile));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_exception_handler));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_soon));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(callback));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cancel));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(capath));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(category));
@@ -847,6 +859,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_stacksize));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_varnames));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(code));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(col_offset));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(command));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(comment_factory));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(compile_mode));
@@ -862,12 +875,14 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cwd));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(data));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(database));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(day));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(decode));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(decoder));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(default));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(defaultaction));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(delete));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(depth));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(desired_access));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(detect_types));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(deterministic));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(device));
@@ -886,13 +901,13 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dont_inherit));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst_dir_fd));
- _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(duration));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eager_start));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(effective_ids));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(element_factory));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encode));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encoding));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end_col_offset));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end_lineno));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end_offset));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(endpos));
@@ -924,15 +939,16 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fileno));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filepath));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fillvalue));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filter));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filters));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(final));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(find_class));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fix_imports));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flags));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flush));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fold));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(follow_symlinks));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(format));
- _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(frequency));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(from_param));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromlist));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromtimestamp));
@@ -954,13 +970,16 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groupindex));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groups));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(handle));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(handle_seq));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(has_location));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hash_name));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(header));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(headers));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hi));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hook));
- _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(id));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hour));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ident));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(identity_hint));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ignore));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(imag));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(importlib));
@@ -969,9 +988,12 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(indexgroup));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inf));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(infer_variance));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inherit_handle));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inheritable));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_bytes));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_owner));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_state));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_value));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initval));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inner_size));
@@ -981,6 +1003,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(instructions));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intern));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intersection));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(interval));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(is_running));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isatty));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isinstance));
@@ -1002,6 +1025,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw1));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw2));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kwdefaults));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(label));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lambda));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_exc));
@@ -1025,11 +1050,13 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(locals));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(logoption));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(loop));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(manual_reset));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mapping));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(match));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(max_length));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxdigits));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxevents));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxlen));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxmem));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxsplit));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxvalue));
@@ -1039,13 +1066,18 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(metaclass));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(metadata));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(method));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(microsecond));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(milliseconds));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(minute));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mod));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mode));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module_globals));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(modules));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(month));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mro));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(msg));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mutex));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mycmp));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_arg));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_fields));
@@ -1057,6 +1089,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespaces));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(narg));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ndigits));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nested));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(new_file_name));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(new_limit));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(newline));
@@ -1144,6 +1177,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(salt));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sched_priority));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(scheduler));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(second));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(security_attributes));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seek));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seekable));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(selectors));
@@ -1169,7 +1204,6 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sleep));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sock));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sort));
- _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sound));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source_traceback));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(spam));
@@ -1222,6 +1256,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(type));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(type_params));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tz));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tzinfo));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tzname));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(uid));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unlink));
@@ -1232,6 +1267,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(values));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(version));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(volume));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(wait_all));
+ _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(warn_on_full_buffer));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(warnings));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(warnoptions));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(wbits));
diff --git a/contrib/tools/python3/Include/internal/pycore_global_strings.h b/contrib/tools/python3/Include/internal/pycore_global_strings.h
index 4f5bfd986f2..cad2d1a8d22 100644
--- a/contrib/tools/python3/Include/internal/pycore_global_strings.h
+++ b/contrib/tools/python3/Include/internal/pycore_global_strings.h
@@ -33,6 +33,7 @@ struct _Py_global_strings {
STRUCT_FOR_STR(anon_lambda, "<lambda>")
STRUCT_FOR_STR(anon_listcomp, "<listcomp>")
STRUCT_FOR_STR(anon_module, "<module>")
+ STRUCT_FOR_STR(anon_null, "<NULL>")
STRUCT_FOR_STR(anon_setcomp, "<setcomp>")
STRUCT_FOR_STR(anon_string, "<string>")
STRUCT_FOR_STR(anon_unknown, "<unknown>")
@@ -46,7 +47,7 @@ struct _Py_global_strings {
STRUCT_FOR_STR(json_decoder, "json.decoder")
STRUCT_FOR_STR(kwdefaults, ".kwdefaults")
STRUCT_FOR_STR(list_err, "list index out of range")
- STRUCT_FOR_STR(shim_name, "<shim>")
+ STRUCT_FOR_STR(str_replace_inf, "1e309")
STRUCT_FOR_STR(type_params, ".type_params")
STRUCT_FOR_STR(utf_8, "utf-8")
} literals;
@@ -75,7 +76,6 @@ struct _Py_global_strings {
STRUCT_FOR_ID(__anext__)
STRUCT_FOR_ID(__annotations__)
STRUCT_FOR_ID(__args__)
- STRUCT_FOR_ID(__asyncio_running_event_loop__)
STRUCT_FOR_ID(__await__)
STRUCT_FOR_ID(__bases__)
STRUCT_FOR_ID(__bool__)
@@ -107,6 +107,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(__eq__)
STRUCT_FOR_ID(__exit__)
STRUCT_FOR_ID(__file__)
+ STRUCT_FOR_ID(__firstlineno__)
STRUCT_FOR_ID(__float__)
STRUCT_FOR_ID(__floordiv__)
STRUCT_FOR_ID(__format__)
@@ -152,6 +153,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(__lshift__)
STRUCT_FOR_ID(__lt__)
STRUCT_FOR_ID(__main__)
+ STRUCT_FOR_ID(__match_args__)
STRUCT_FOR_ID(__matmul__)
STRUCT_FOR_ID(__missing__)
STRUCT_FOR_ID(__mod__)
@@ -206,6 +208,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(__slotnames__)
STRUCT_FOR_ID(__slots__)
STRUCT_FOR_ID(__spec__)
+ STRUCT_FOR_ID(__static_attributes__)
STRUCT_FOR_ID(__str__)
STRUCT_FOR_ID(__sub__)
STRUCT_FOR_ID(__subclasscheck__)
@@ -224,6 +227,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(_abc_impl)
STRUCT_FOR_ID(_abstract_)
STRUCT_FOR_ID(_active)
+ STRUCT_FOR_ID(_align_)
STRUCT_FOR_ID(_annotation)
STRUCT_FOR_ID(_anonymous_)
STRUCT_FOR_ID(_argtypes_)
@@ -234,6 +238,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(_check_retval_)
STRUCT_FOR_ID(_dealloc_warn)
STRUCT_FOR_ID(_feature_version)
+ STRUCT_FOR_ID(_field_types)
STRUCT_FOR_ID(_fields_)
STRUCT_FOR_ID(_finalizing)
STRUCT_FOR_ID(_find_and_load)
@@ -255,6 +260,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(_showwarnmsg)
STRUCT_FOR_ID(_shutdown)
STRUCT_FOR_ID(_slotnames)
+ STRUCT_FOR_ID(_strptime)
STRUCT_FOR_ID(_strptime_datetime)
STRUCT_FOR_ID(_swappedbytes_)
STRUCT_FOR_ID(_type_)
@@ -263,12 +269,14 @@ struct _Py_global_strings {
STRUCT_FOR_ID(_xoptions)
STRUCT_FOR_ID(abs_tol)
STRUCT_FOR_ID(access)
+ STRUCT_FOR_ID(aclose)
STRUCT_FOR_ID(add)
STRUCT_FOR_ID(add_done_callback)
STRUCT_FOR_ID(after_in_child)
STRUCT_FOR_ID(after_in_parent)
STRUCT_FOR_ID(aggregate_class)
STRUCT_FOR_ID(alias)
+ STRUCT_FOR_ID(allow_code)
STRUCT_FOR_ID(append)
STRUCT_FOR_ID(arg)
STRUCT_FOR_ID(argdefs)
@@ -276,7 +284,9 @@ struct _Py_global_strings {
STRUCT_FOR_ID(arguments)
STRUCT_FOR_ID(argv)
STRUCT_FOR_ID(as_integer_ratio)
+ STRUCT_FOR_ID(asend)
STRUCT_FOR_ID(ast)
+ STRUCT_FOR_ID(athrow)
STRUCT_FOR_ID(attribute)
STRUCT_FOR_ID(authorizer_callback)
STRUCT_FOR_ID(autocommit)
@@ -300,12 +310,14 @@ struct _Py_global_strings {
STRUCT_FOR_ID(c_call)
STRUCT_FOR_ID(c_exception)
STRUCT_FOR_ID(c_return)
+ STRUCT_FOR_ID(cached_datetime_module)
STRUCT_FOR_ID(cached_statements)
STRUCT_FOR_ID(cadata)
STRUCT_FOR_ID(cafile)
STRUCT_FOR_ID(call)
STRUCT_FOR_ID(call_exception_handler)
STRUCT_FOR_ID(call_soon)
+ STRUCT_FOR_ID(callback)
STRUCT_FOR_ID(cancel)
STRUCT_FOR_ID(capath)
STRUCT_FOR_ID(category)
@@ -336,6 +348,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(co_stacksize)
STRUCT_FOR_ID(co_varnames)
STRUCT_FOR_ID(code)
+ STRUCT_FOR_ID(col_offset)
STRUCT_FOR_ID(command)
STRUCT_FOR_ID(comment_factory)
STRUCT_FOR_ID(compile_mode)
@@ -351,12 +364,14 @@ struct _Py_global_strings {
STRUCT_FOR_ID(cwd)
STRUCT_FOR_ID(data)
STRUCT_FOR_ID(database)
+ STRUCT_FOR_ID(day)
STRUCT_FOR_ID(decode)
STRUCT_FOR_ID(decoder)
STRUCT_FOR_ID(default)
STRUCT_FOR_ID(defaultaction)
STRUCT_FOR_ID(delete)
STRUCT_FOR_ID(depth)
+ STRUCT_FOR_ID(desired_access)
STRUCT_FOR_ID(detect_types)
STRUCT_FOR_ID(deterministic)
STRUCT_FOR_ID(device)
@@ -375,13 +390,13 @@ struct _Py_global_strings {
STRUCT_FOR_ID(dont_inherit)
STRUCT_FOR_ID(dst)
STRUCT_FOR_ID(dst_dir_fd)
- STRUCT_FOR_ID(duration)
STRUCT_FOR_ID(eager_start)
STRUCT_FOR_ID(effective_ids)
STRUCT_FOR_ID(element_factory)
STRUCT_FOR_ID(encode)
STRUCT_FOR_ID(encoding)
STRUCT_FOR_ID(end)
+ STRUCT_FOR_ID(end_col_offset)
STRUCT_FOR_ID(end_lineno)
STRUCT_FOR_ID(end_offset)
STRUCT_FOR_ID(endpos)
@@ -413,15 +428,16 @@ struct _Py_global_strings {
STRUCT_FOR_ID(fileno)
STRUCT_FOR_ID(filepath)
STRUCT_FOR_ID(fillvalue)
+ STRUCT_FOR_ID(filter)
STRUCT_FOR_ID(filters)
STRUCT_FOR_ID(final)
STRUCT_FOR_ID(find_class)
STRUCT_FOR_ID(fix_imports)
STRUCT_FOR_ID(flags)
STRUCT_FOR_ID(flush)
+ STRUCT_FOR_ID(fold)
STRUCT_FOR_ID(follow_symlinks)
STRUCT_FOR_ID(format)
- STRUCT_FOR_ID(frequency)
STRUCT_FOR_ID(from_param)
STRUCT_FOR_ID(fromlist)
STRUCT_FOR_ID(fromtimestamp)
@@ -443,13 +459,16 @@ struct _Py_global_strings {
STRUCT_FOR_ID(groupindex)
STRUCT_FOR_ID(groups)
STRUCT_FOR_ID(handle)
+ STRUCT_FOR_ID(handle_seq)
+ STRUCT_FOR_ID(has_location)
STRUCT_FOR_ID(hash_name)
STRUCT_FOR_ID(header)
STRUCT_FOR_ID(headers)
STRUCT_FOR_ID(hi)
STRUCT_FOR_ID(hook)
- STRUCT_FOR_ID(id)
+ STRUCT_FOR_ID(hour)
STRUCT_FOR_ID(ident)
+ STRUCT_FOR_ID(identity_hint)
STRUCT_FOR_ID(ignore)
STRUCT_FOR_ID(imag)
STRUCT_FOR_ID(importlib)
@@ -458,9 +477,12 @@ struct _Py_global_strings {
STRUCT_FOR_ID(indexgroup)
STRUCT_FOR_ID(inf)
STRUCT_FOR_ID(infer_variance)
+ STRUCT_FOR_ID(inherit_handle)
STRUCT_FOR_ID(inheritable)
STRUCT_FOR_ID(initial)
STRUCT_FOR_ID(initial_bytes)
+ STRUCT_FOR_ID(initial_owner)
+ STRUCT_FOR_ID(initial_state)
STRUCT_FOR_ID(initial_value)
STRUCT_FOR_ID(initval)
STRUCT_FOR_ID(inner_size)
@@ -470,6 +492,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(instructions)
STRUCT_FOR_ID(intern)
STRUCT_FOR_ID(intersection)
+ STRUCT_FOR_ID(interval)
STRUCT_FOR_ID(is_running)
STRUCT_FOR_ID(isatty)
STRUCT_FOR_ID(isinstance)
@@ -491,6 +514,8 @@ struct _Py_global_strings {
STRUCT_FOR_ID(kw)
STRUCT_FOR_ID(kw1)
STRUCT_FOR_ID(kw2)
+ STRUCT_FOR_ID(kwdefaults)
+ STRUCT_FOR_ID(label)
STRUCT_FOR_ID(lambda)
STRUCT_FOR_ID(last)
STRUCT_FOR_ID(last_exc)
@@ -514,11 +539,13 @@ struct _Py_global_strings {
STRUCT_FOR_ID(locals)
STRUCT_FOR_ID(logoption)
STRUCT_FOR_ID(loop)
+ STRUCT_FOR_ID(manual_reset)
STRUCT_FOR_ID(mapping)
STRUCT_FOR_ID(match)
STRUCT_FOR_ID(max_length)
STRUCT_FOR_ID(maxdigits)
STRUCT_FOR_ID(maxevents)
+ STRUCT_FOR_ID(maxlen)
STRUCT_FOR_ID(maxmem)
STRUCT_FOR_ID(maxsplit)
STRUCT_FOR_ID(maxvalue)
@@ -528,13 +555,18 @@ struct _Py_global_strings {
STRUCT_FOR_ID(metaclass)
STRUCT_FOR_ID(metadata)
STRUCT_FOR_ID(method)
+ STRUCT_FOR_ID(microsecond)
+ STRUCT_FOR_ID(milliseconds)
+ STRUCT_FOR_ID(minute)
STRUCT_FOR_ID(mod)
STRUCT_FOR_ID(mode)
STRUCT_FOR_ID(module)
STRUCT_FOR_ID(module_globals)
STRUCT_FOR_ID(modules)
+ STRUCT_FOR_ID(month)
STRUCT_FOR_ID(mro)
STRUCT_FOR_ID(msg)
+ STRUCT_FOR_ID(mutex)
STRUCT_FOR_ID(mycmp)
STRUCT_FOR_ID(n_arg)
STRUCT_FOR_ID(n_fields)
@@ -546,6 +578,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(namespaces)
STRUCT_FOR_ID(narg)
STRUCT_FOR_ID(ndigits)
+ STRUCT_FOR_ID(nested)
STRUCT_FOR_ID(new_file_name)
STRUCT_FOR_ID(new_limit)
STRUCT_FOR_ID(newline)
@@ -633,6 +666,8 @@ struct _Py_global_strings {
STRUCT_FOR_ID(salt)
STRUCT_FOR_ID(sched_priority)
STRUCT_FOR_ID(scheduler)
+ STRUCT_FOR_ID(second)
+ STRUCT_FOR_ID(security_attributes)
STRUCT_FOR_ID(seek)
STRUCT_FOR_ID(seekable)
STRUCT_FOR_ID(selectors)
@@ -658,7 +693,6 @@ struct _Py_global_strings {
STRUCT_FOR_ID(sleep)
STRUCT_FOR_ID(sock)
STRUCT_FOR_ID(sort)
- STRUCT_FOR_ID(sound)
STRUCT_FOR_ID(source)
STRUCT_FOR_ID(source_traceback)
STRUCT_FOR_ID(spam)
@@ -711,6 +745,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(type)
STRUCT_FOR_ID(type_params)
STRUCT_FOR_ID(tz)
+ STRUCT_FOR_ID(tzinfo)
STRUCT_FOR_ID(tzname)
STRUCT_FOR_ID(uid)
STRUCT_FOR_ID(unlink)
@@ -721,6 +756,8 @@ struct _Py_global_strings {
STRUCT_FOR_ID(values)
STRUCT_FOR_ID(version)
STRUCT_FOR_ID(volume)
+ STRUCT_FOR_ID(wait_all)
+ STRUCT_FOR_ID(warn_on_full_buffer)
STRUCT_FOR_ID(warnings)
STRUCT_FOR_ID(warnoptions)
STRUCT_FOR_ID(wbits)
diff --git a/contrib/tools/python3/Include/internal/pycore_hashtable.h b/contrib/tools/python3/Include/internal/pycore_hashtable.h
index f57978a8d61..369d49c42bb 100644
--- a/contrib/tools/python3/Include/internal/pycore_hashtable.h
+++ b/contrib/tools/python3/Include/internal/pycore_hashtable.h
@@ -70,6 +70,11 @@ struct _Py_hashtable_t {
_Py_hashtable_allocator_t alloc;
};
+// Export _Py_hashtable functions for '_testinternalcapi' shared extension
+PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new(
+ _Py_hashtable_hash_func hash_func,
+ _Py_hashtable_compare_func compare_func);
+
/* Hash a pointer (void*) */
PyAPI_FUNC(Py_uhash_t) _Py_hashtable_hash_ptr(const void *key);
@@ -78,10 +83,6 @@ PyAPI_FUNC(int) _Py_hashtable_compare_direct(
const void *key1,
const void *key2);
-PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new(
- _Py_hashtable_hash_func hash_func,
- _Py_hashtable_compare_func compare_func);
-
PyAPI_FUNC(_Py_hashtable_t *) _Py_hashtable_new_full(
_Py_hashtable_hash_func hash_func,
_Py_hashtable_compare_func compare_func,
diff --git a/contrib/tools/python3/Include/internal/pycore_identifier.h b/contrib/tools/python3/Include/internal/pycore_identifier.h
new file mode 100644
index 00000000000..cda28810a48
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_identifier.h
@@ -0,0 +1,20 @@
+/* String Literals: _Py_Identifier API */
+
+#ifndef Py_INTERNAL_IDENTIFIER_H
+#define Py_INTERNAL_IDENTIFIER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+extern PyObject* _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
+extern PyObject* _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *);
+extern int _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_IDENTIFIER_H
diff --git a/contrib/tools/python3/Include/internal/pycore_import.h b/contrib/tools/python3/Include/internal/pycore_import.h
index 376957bdc99..55029abdd31 100644
--- a/contrib/tools/python3/Include/internal/pycore_import.h
+++ b/contrib/tools/python3/Include/internal/pycore_import.h
@@ -5,8 +5,37 @@
extern "C" {
#endif
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_lock.h" // PyMutex
#include "pycore_hashtable.h" // _Py_hashtable_t
-#include "pycore_time.h" // _PyTime_t
+
+extern int _PyImport_IsInitialized(PyInterpreterState *);
+
+// Export for 'pyexpat' shared extension
+PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module);
+
+extern int _PyImport_SetModuleString(const char *name, PyObject* module);
+
+extern void _PyImport_AcquireLock(PyInterpreterState *interp);
+extern void _PyImport_ReleaseLock(PyInterpreterState *interp);
+extern void _PyImport_ReInitLock(PyInterpreterState *interp);
+
+// This is used exclusively for the sys and builtins modules:
+extern int _PyImport_FixupBuiltin(
+ PyThreadState *tstate,
+ PyObject *mod,
+ const char *name, /* UTF-8 encoded string */
+ PyObject *modules
+ );
+
+// Export for many shared extensions, like '_json'
+PyAPI_FUNC(PyObject*) _PyImport_GetModuleAttr(PyObject *, PyObject *);
+
+// Export for many shared extensions, like '_datetime'
+PyAPI_FUNC(PyObject*) _PyImport_GetModuleAttrString(const char *, const char *);
struct _import_runtime_state {
@@ -19,12 +48,12 @@ struct _import_runtime_state {
Py_ssize_t last_module_index;
struct {
/* A lock to guard the cache. */
- PyThread_type_lock mutex;
+ PyMutex mutex;
/* The actual cache of (filename, name, PyModuleDef) for modules.
Only legacy (single-phase init) extension modules are added
and only if they support multiple initialization (m_size >- 0)
or are imported in the main interpreter.
- This is initialized lazily in _PyImport_FixupExtensionObject().
+ This is initialized lazily in fix_up_extension() in import.c.
Modules are added there and looked up in _imp.find_extension(). */
_Py_hashtable_t *hashtable;
} extensions;
@@ -66,21 +95,17 @@ struct _import_state {
#endif
PyObject *import_func;
/* The global import lock. */
- struct {
- PyThread_type_lock mutex;
- unsigned long thread;
- int level;
- } lock;
+ _PyRecursiveMutex lock;
/* diagnostic info in PyImport_ImportModuleLevelObject() */
struct {
int import_level;
- _PyTime_t accumulated;
+ PyTime_t accumulated;
int header;
} find_and_load;
};
#ifdef HAVE_DLOPEN
-# include <dlfcn.h>
+# include <dlfcn.h> // RTLD_NOW, RTLD_LAZY
# if HAVE_DECL_RTLD_NOW
# define _Py_DLOPEN_FLAGS RTLD_NOW
# else
@@ -95,11 +120,6 @@ struct _import_state {
#define IMPORTS_INIT \
{ \
DLOPENFLAGS_INIT \
- .lock = { \
- .mutex = NULL, \
- .thread = PYTHREAD_INVALID_THREAD_ID, \
- .level = 0, \
- }, \
.find_and_load = { \
.header = 1, \
}, \
@@ -152,11 +172,6 @@ extern void _PyImport_FiniCore(PyInterpreterState *interp);
extern void _PyImport_FiniExternal(PyInterpreterState *interp);
-#ifdef HAVE_FORK
-extern PyStatus _PyImport_ReInitLock(PyInterpreterState *interp);
-#endif
-
-
extern PyObject* _PyImport_GetBuiltinModuleNames(void);
struct _module_alias {
@@ -164,18 +179,33 @@ struct _module_alias {
const char *orig; /* ASCII encoded string */
};
-PyAPI_DATA(const struct _frozen *) _PyImport_FrozenBootstrap;
-PyAPI_DATA(const struct _frozen *) _PyImport_FrozenStdlib;
-PyAPI_DATA(const struct _frozen *) _PyImport_FrozenTest;
+// Export these 3 symbols for test_ctypes
+PyAPI_DATA(const struct _frozen*) _PyImport_FrozenBootstrap;
+PyAPI_DATA(const struct _frozen*) _PyImport_FrozenStdlib;
+PyAPI_DATA(const struct _frozen*) _PyImport_FrozenTest;
+
extern const struct _module_alias * _PyImport_FrozenAliases;
-PyAPI_FUNC(int) _PyImport_CheckSubinterpIncompatibleExtensionAllowed(
+extern int _PyImport_CheckSubinterpIncompatibleExtensionAllowed(
const char *name);
-// for testing
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(int) _PyImport_ClearExtension(PyObject *name, PyObject *filename);
+#ifdef Py_GIL_DISABLED
+// Assuming that the GIL is enabled from a call to
+// _PyEval_EnableGILTransient(), resolve the transient request depending on the
+// state of the module argument:
+// - If module is NULL or a PyModuleObject with md_gil == Py_MOD_GIL_NOT_USED,
+// call _PyEval_DisableGIL().
+// - Otherwise, call _PyEval_EnableGILPermanent(). If the GIL was not already
+// enabled permanently, issue a warning referencing the module's name.
+//
+// This function may raise an exception.
+extern int _PyImport_CheckGILForModule(PyObject *module, PyObject *module_name);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_importdl.h b/contrib/tools/python3/Include/internal/pycore_importdl.h
new file mode 100644
index 00000000000..525a16f6b97
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_importdl.h
@@ -0,0 +1,139 @@
+#ifndef Py_INTERNAL_IMPORTDL_H
+#define Py_INTERNAL_IMPORTDL_H
+
+#include "patchlevel.h" // PY_MAJOR_VERSION
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+extern const char *_PyImport_DynLoadFiletab[];
+
+
+typedef enum ext_module_kind {
+ _Py_ext_module_kind_UNKNOWN = 0,
+ _Py_ext_module_kind_SINGLEPHASE = 1,
+ _Py_ext_module_kind_MULTIPHASE = 2,
+ _Py_ext_module_kind_INVALID = 3,
+} _Py_ext_module_kind;
+
+typedef enum ext_module_origin {
+ _Py_ext_module_origin_CORE = 1,
+ _Py_ext_module_origin_BUILTIN = 2,
+ _Py_ext_module_origin_DYNAMIC = 3,
+} _Py_ext_module_origin;
+
+/* Input for loading an extension module. */
+struct _Py_ext_module_loader_info {
+ PyObject *filename;
+#ifndef MS_WINDOWS
+ PyObject *filename_encoded;
+#endif
+ PyObject *name;
+ PyObject *name_encoded;
+ /* path is always a borrowed ref of name or filename,
+ * depending on if it's builtin or not. */
+ PyObject *path;
+ _Py_ext_module_origin origin;
+ const char *hook_prefix;
+ const char *newcontext;
+};
+extern void _Py_ext_module_loader_info_clear(
+ struct _Py_ext_module_loader_info *info);
+extern int _Py_ext_module_loader_info_init(
+ struct _Py_ext_module_loader_info *info,
+ PyObject *name,
+ PyObject *filename,
+ _Py_ext_module_origin origin);
+extern int _Py_ext_module_loader_info_init_for_core(
+ struct _Py_ext_module_loader_info *p_info,
+ PyObject *name);
+extern int _Py_ext_module_loader_info_init_for_builtin(
+ struct _Py_ext_module_loader_info *p_info,
+ PyObject *name);
+#ifdef HAVE_DYNAMIC_LOADING
+extern int _Py_ext_module_loader_info_init_from_spec(
+ struct _Py_ext_module_loader_info *info,
+ PyObject *spec);
+#endif
+
+/* The result from running an extension module's init function. */
+struct _Py_ext_module_loader_result {
+ PyModuleDef *def;
+ PyObject *module;
+ _Py_ext_module_kind kind;
+ struct _Py_ext_module_loader_result_error *err;
+ struct _Py_ext_module_loader_result_error {
+ enum _Py_ext_module_loader_result_error_kind {
+ _Py_ext_module_loader_result_EXCEPTION = 0,
+ _Py_ext_module_loader_result_ERR_MISSING = 1,
+ _Py_ext_module_loader_result_ERR_UNREPORTED_EXC = 2,
+ _Py_ext_module_loader_result_ERR_UNINITIALIZED = 3,
+ _Py_ext_module_loader_result_ERR_NONASCII_NOT_MULTIPHASE = 4,
+ _Py_ext_module_loader_result_ERR_NOT_MODULE = 5,
+ _Py_ext_module_loader_result_ERR_MISSING_DEF = 6,
+ } kind;
+ PyObject *exc;
+ } _err;
+};
+extern void _Py_ext_module_loader_result_clear(
+ struct _Py_ext_module_loader_result *res);
+extern void _Py_ext_module_loader_result_apply_error(
+ struct _Py_ext_module_loader_result *res,
+ const char *name);
+
+/* The module init function. */
+typedef PyObject *(*PyModInitFunction)(void);
+#ifdef HAVE_DYNAMIC_LOADING
+extern PyModInitFunction _PyImport_GetModInitFunc(
+ struct _Py_ext_module_loader_info *info,
+ FILE *fp);
+#endif
+extern int _PyImport_RunModInitFunc(
+ PyModInitFunction p0,
+ struct _Py_ext_module_loader_info *info,
+ struct _Py_ext_module_loader_result *p_res);
+
+
+/* Max length of module suffix searched for -- accommodates "module.slb" */
+#define MAXSUFFIXSIZE 12
+
+#ifdef MS_WINDOWS
+#include <windows.h>
+typedef FARPROC dl_funcptr;
+
+#ifdef _DEBUG
+# define PYD_DEBUG_SUFFIX "_d"
+#else
+# define PYD_DEBUG_SUFFIX ""
+#endif
+
+#ifdef Py_GIL_DISABLED
+# define PYD_THREADING_TAG "t"
+#else
+# define PYD_THREADING_TAG ""
+#endif
+
+#ifdef PYD_PLATFORM_TAG
+# define PYD_SOABI "cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG "-" PYD_PLATFORM_TAG
+#else
+# define PYD_SOABI "cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) PYD_THREADING_TAG
+#endif
+
+#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX "." PYD_SOABI ".pyd"
+#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd"
+
+#else
+typedef void (*dl_funcptr)(void);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_IMPORTDL_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_initconfig.h b/contrib/tools/python3/Include/internal/pycore_initconfig.h
index 4cbd14a61d4..1c681613418 100644
--- a/contrib/tools/python3/Include/internal/pycore_initconfig.h
+++ b/contrib/tools/python3/Include/internal/pycore_initconfig.h
@@ -22,7 +22,7 @@ struct pyruntimestate;
#endif
#define _PyStatus_OK() \
- (PyStatus){._type = _PyStatus_TYPE_OK,}
+ (PyStatus){._type = _PyStatus_TYPE_OK}
/* other fields are set to 0 */
#define _PyStatus_ERR(ERR_MSG) \
(PyStatus){ \
@@ -30,7 +30,8 @@ struct pyruntimestate;
.func = _PyStatus_GET_FUNC(), \
.err_msg = (ERR_MSG)}
/* other fields are set to 0 */
-#define _PyStatus_NO_MEMORY() _PyStatus_ERR("memory allocation failed")
+#define _PyStatus_NO_MEMORY_ERRMSG "memory allocation failed"
+#define _PyStatus_NO_MEMORY() _PyStatus_ERR(_PyStatus_NO_MEMORY_ERRMSG)
#define _PyStatus_EXIT(EXITCODE) \
(PyStatus){ \
._type = _PyStatus_TYPE_EXIT, \
@@ -44,19 +45,23 @@ struct pyruntimestate;
#define _PyStatus_UPDATE_FUNC(err) \
do { (err).func = _PyStatus_GET_FUNC(); } while (0)
+// Export for '_testinternalcapi' shared extension
+PyAPI_FUNC(void) _PyErr_SetFromPyStatus(PyStatus status);
+
+
/* --- PyWideStringList ------------------------------------------------ */
#define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL}
#ifndef NDEBUG
-PyAPI_FUNC(int) _PyWideStringList_CheckConsistency(const PyWideStringList *list);
+extern int _PyWideStringList_CheckConsistency(const PyWideStringList *list);
#endif
-PyAPI_FUNC(void) _PyWideStringList_Clear(PyWideStringList *list);
-PyAPI_FUNC(int) _PyWideStringList_Copy(PyWideStringList *list,
+extern void _PyWideStringList_Clear(PyWideStringList *list);
+extern int _PyWideStringList_Copy(PyWideStringList *list,
const PyWideStringList *list2);
-PyAPI_FUNC(PyStatus) _PyWideStringList_Extend(PyWideStringList *list,
+extern PyStatus _PyWideStringList_Extend(PyWideStringList *list,
const PyWideStringList *list2);
-PyAPI_FUNC(PyObject*) _PyWideStringList_AsList(const PyWideStringList *list);
+extern PyObject* _PyWideStringList_AsList(const PyWideStringList *list);
/* --- _PyArgv ---------------------------------------------------- */
@@ -68,28 +73,28 @@ typedef struct _PyArgv {
wchar_t * const *wchar_argv;
} _PyArgv;
-PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args,
+extern PyStatus _PyArgv_AsWstrList(const _PyArgv *args,
PyWideStringList *list);
/* --- Helper functions ------------------------------------------- */
-PyAPI_FUNC(int) _Py_str_to_int(
+extern int _Py_str_to_int(
const char *str,
int *result);
-PyAPI_FUNC(const wchar_t*) _Py_get_xoption(
+extern const wchar_t* _Py_get_xoption(
const PyWideStringList *xoptions,
const wchar_t *name);
-PyAPI_FUNC(const char*) _Py_GetEnv(
+extern const char* _Py_GetEnv(
int use_environment,
const char *name);
-PyAPI_FUNC(void) _Py_get_env_flag(
+extern void _Py_get_env_flag(
int use_environment,
int *flag,
const char *name);
/* Py_GetArgcArgv() helper */
-PyAPI_FUNC(void) _Py_ClearArgcArgv(void);
+extern void _Py_ClearArgcArgv(void);
/* --- _PyPreCmdline ------------------------------------------------- */
@@ -122,7 +127,9 @@ extern PyStatus _PyPreCmdline_Read(_PyPreCmdline *cmdline,
/* --- PyPreConfig ----------------------------------------------- */
+// Export for '_testembed' program
PyAPI_FUNC(void) _PyPreConfig_InitCompatConfig(PyPreConfig *preconfig);
+
extern void _PyPreConfig_InitFromConfig(
PyPreConfig *preconfig,
const PyConfig *config);
@@ -146,7 +153,21 @@ typedef enum {
_PyConfig_INIT_ISOLATED = 3
} _PyConfigInitEnum;
+typedef enum {
+ /* For now, this means the GIL is enabled.
+
+ gh-116329: This will eventually change to "the GIL is disabled but can
+ be reenabled by loading an incompatible extension module." */
+ _PyConfig_GIL_DEFAULT = -1,
+
+ /* The GIL has been forced off or on, and will not be affected by module loading. */
+ _PyConfig_GIL_DISABLE = 0,
+ _PyConfig_GIL_ENABLE = 1,
+} _PyConfigGILEnum;
+
+// Export for '_testembed' program
PyAPI_FUNC(void) _PyConfig_InitCompatConfig(PyConfig *config);
+
extern PyStatus _PyConfig_Copy(
PyConfig *config,
const PyConfig *config2);
@@ -161,16 +182,16 @@ extern PyStatus _PyConfig_SetPyArgv(
PyConfig *config,
const _PyArgv *args);
-PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config);
-PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict);
extern void _Py_DumpPathConfig(PyThreadState *tstate);
-PyAPI_FUNC(PyObject*) _Py_Get_Getpath_CodeObject(void);
-
/* --- Function used for testing ---------------------------------- */
+// Export these functions for '_testinternalcapi' shared extension
+PyAPI_FUNC(PyObject*) _PyConfig_AsDict(const PyConfig *config);
+PyAPI_FUNC(int) _PyConfig_FromDict(PyConfig *config, PyObject *dict);
+PyAPI_FUNC(PyObject*) _Py_Get_Getpath_CodeObject(void);
PyAPI_FUNC(PyObject*) _Py_GetConfigsAsDict(void);
#ifdef __cplusplus
diff --git a/contrib/tools/python3/Include/internal/pycore_instruction_sequence.h b/contrib/tools/python3/Include/internal/pycore_instruction_sequence.h
new file mode 100644
index 00000000000..d6a79616db7
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_instruction_sequence.h
@@ -0,0 +1,73 @@
+#ifndef Py_INTERNAL_INSTRUCTION_SEQUENCE_H
+#define Py_INTERNAL_INSTRUCTION_SEQUENCE_H
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_symtable.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct {
+ int h_label;
+ int h_startdepth;
+ int h_preserve_lasti;
+} _PyExceptHandlerInfo;
+
+typedef struct {
+ int i_opcode;
+ int i_oparg;
+ _Py_SourceLocation i_loc;
+ _PyExceptHandlerInfo i_except_handler_info;
+
+ /* Temporary fields, used by the assembler and in instr_sequence_to_cfg */
+ int i_target;
+ int i_offset;
+} _PyInstruction;
+
+typedef struct instruction_sequence {
+ PyObject_HEAD
+ _PyInstruction *s_instrs;
+ int s_allocated;
+ int s_used;
+
+ int s_next_free_label; /* next free label id */
+
+ /* Map of a label id to instruction offset (index into s_instrs).
+ * If s_labelmap is NULL, then each label id is the offset itself.
+ */
+ int *s_labelmap;
+ int s_labelmap_size;
+
+ /* PyList of instruction sequences of nested functions */
+ PyObject *s_nested;
+} _PyInstructionSequence;
+
+typedef struct {
+ int id;
+} _PyJumpTargetLabel;
+
+PyAPI_FUNC(PyObject*)_PyInstructionSequence_New(void);
+
+int _PyInstructionSequence_UseLabel(_PyInstructionSequence *seq, int lbl);
+int _PyInstructionSequence_Addop(_PyInstructionSequence *seq,
+ int opcode, int oparg,
+ _Py_SourceLocation loc);
+_PyJumpTargetLabel _PyInstructionSequence_NewLabel(_PyInstructionSequence *seq);
+int _PyInstructionSequence_ApplyLabelMap(_PyInstructionSequence *seq);
+int _PyInstructionSequence_InsertInstruction(_PyInstructionSequence *seq, int pos,
+ int opcode, int oparg, _Py_SourceLocation loc);
+int _PyInstructionSequence_AddNested(_PyInstructionSequence *seq, _PyInstructionSequence *nested);
+void PyInstructionSequence_Fini(_PyInstructionSequence *seq);
+
+extern PyTypeObject _PyInstructionSequence_Type;
+#define _PyInstructionSequence_Check(v) Py_IS_TYPE((v), &_PyInstructionSequence_Type)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_INSTRUCTION_SEQUENCE_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_instruments.h b/contrib/tools/python3/Include/internal/pycore_instruments.h
index b8591563d76..c98e82c8be5 100644
--- a/contrib/tools/python3/Include/internal/pycore_instruments.h
+++ b/contrib/tools/python3/Include/internal/pycore_instruments.h
@@ -1,12 +1,11 @@
-
#ifndef Py_INTERNAL_INSTRUMENT_H
#define Py_INTERNAL_INSTRUMENT_H
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
-#include "pycore_bitutils.h" // _Py_popcount32
-#include "pycore_frame.h"
-
-#include "cpython/code.h"
+#include "pycore_frame.h" // _PyInterpreterFrame
#ifdef __cplusplus
extern "C" {
@@ -14,38 +13,6 @@ extern "C" {
#define PY_MONITORING_TOOL_IDS 8
-/* Local events.
- * These require bytecode instrumentation */
-
-#define PY_MONITORING_EVENT_PY_START 0
-#define PY_MONITORING_EVENT_PY_RESUME 1
-#define PY_MONITORING_EVENT_PY_RETURN 2
-#define PY_MONITORING_EVENT_PY_YIELD 3
-#define PY_MONITORING_EVENT_CALL 4
-#define PY_MONITORING_EVENT_LINE 5
-#define PY_MONITORING_EVENT_INSTRUCTION 6
-#define PY_MONITORING_EVENT_JUMP 7
-#define PY_MONITORING_EVENT_BRANCH 8
-#define PY_MONITORING_EVENT_STOP_ITERATION 9
-
-#define PY_MONITORING_IS_INSTRUMENTED_EVENT(ev) \
- ((ev) < _PY_MONITORING_LOCAL_EVENTS)
-
-/* Other events, mainly exceptions */
-
-#define PY_MONITORING_EVENT_RAISE 10
-#define PY_MONITORING_EVENT_EXCEPTION_HANDLED 11
-#define PY_MONITORING_EVENT_PY_UNWIND 12
-#define PY_MONITORING_EVENT_PY_THROW 13
-#define PY_MONITORING_EVENT_RERAISE 14
-
-
-/* Ancillary events */
-
-#define PY_MONITORING_EVENT_C_RETURN 15
-#define PY_MONITORING_EVENT_C_RAISE 16
-
-
typedef uint32_t _PyMonitoringEventSet;
/* Tool IDs */
@@ -64,6 +31,8 @@ typedef uint32_t _PyMonitoringEventSet;
PyObject *_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj);
int _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events);
+int _PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet events);
+int _PyMonitoring_GetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet *events);
extern int
_Py_call_instrumentation(PyThreadState *tstate, int event,
diff --git a/contrib/tools/python3/Include/internal/pycore_interp.h b/contrib/tools/python3/Include/internal/pycore_interp.h
index 37cc88ed081..3243b1e618d 100644
--- a/contrib/tools/python3/Include/internal/pycore_interp.h
+++ b/contrib/tools/python3/Include/internal/pycore_interp.h
@@ -8,29 +8,34 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include <stdbool.h>
+#include <stdbool.h> // bool
#include "pycore_ast_state.h" // struct ast_state
#include "pycore_atexit.h" // struct atexit_state
-#include "pycore_atomic.h" // _Py_atomic_address
#include "pycore_ceval_state.h" // struct _ceval_state
#include "pycore_code.h" // struct callable_cache
+#include "pycore_codecs.h" // struct codecs_state
#include "pycore_context.h" // struct _Py_context_state
+#include "pycore_crossinterp.h" // struct _xidregistry
#include "pycore_dict_state.h" // struct _Py_dict_state
#include "pycore_dtoa.h" // struct _dtoa_state
#include "pycore_exceptions.h" // struct _Py_exc_state
#include "pycore_floatobject.h" // struct _Py_float_state
#include "pycore_function.h" // FUNC_MAX_WATCHERS
-#include "pycore_genobject.h" // struct _Py_async_gen_state
#include "pycore_gc.h" // struct _gc_runtime_state
-#include "pycore_global_objects.h" // struct _Py_interp_static_objects
+#include "pycore_genobject.h" // struct _Py_async_gen_state
+#include "pycore_global_objects.h"// struct _Py_interp_cached_objects
#include "pycore_import.h" // struct _import_state
#include "pycore_instruments.h" // _PY_MONITORING_EVENTS
#include "pycore_list.h" // struct _Py_list_state
-#include "pycore_object_state.h" // struct _py_object_state
-#include "pycore_obmalloc.h" // struct obmalloc_state
+#include "pycore_mimalloc.h" // struct _mimalloc_interp_state
+#include "pycore_object_state.h" // struct _py_object_state
+#include "pycore_optimizer.h" // _PyOptimizerObject
+#include "pycore_obmalloc.h" // struct _obmalloc_state
+#include "pycore_qsbr.h" // struct _qsbr_state
+#include "pycore_tstate.h" // _PyThreadStateImpl
#include "pycore_tuple.h" // struct _Py_tuple_state
-#include "pycore_typeobject.h" // struct type_cache
+#include "pycore_typeobject.h" // struct types_state
#include "pycore_unicodeobject.h" // struct _Py_unicode_state
#include "pycore_warnings.h" // struct _warnings_runtime_state
@@ -39,31 +44,45 @@ struct _Py_long_state {
int max_str_digits;
};
+// Support for stop-the-world events. This exists in both the PyRuntime struct
+// for global pauses and in each PyInterpreterState for per-interpreter pauses.
+struct _stoptheworld_state {
+ PyMutex mutex; // Serializes stop-the-world attempts.
-/* cross-interpreter data registry */
+ // NOTE: The below fields are protected by HEAD_LOCK(runtime), not by the
+ // above mutex.
+ bool requested; // Set when a pause is requested.
+ bool world_stopped; // Set when the world is stopped.
+ bool is_global; // Set when contained in PyRuntime struct.
-/* For now we use a global registry of shareable classes. An
- alternative would be to add a tp_* slot for a class's
- crossinterpdatafunc. It would be simpler and more efficient. */
+ PyEvent stop_event; // Set when thread_countdown reaches zero.
+ Py_ssize_t thread_countdown; // Number of threads that must pause.
-struct _xidregitem;
-
-struct _xidregitem {
- struct _xidregitem *prev;
- struct _xidregitem *next;
- /* This can be a dangling pointer, but only if weakref is set. */
- PyTypeObject *cls;
- /* This is NULL for builtin types. */
- PyObject *weakref;
- size_t refcount;
- crossinterpdatafunc getdata;
+ PyThreadState *requester; // Thread that requested the pause (may be NULL).
};
-struct _xidregistry {
- PyThread_type_lock mutex;
- struct _xidregitem *head;
-};
+#ifdef Py_GIL_DISABLED
+// This should be prime but otherwise the choice is arbitrary. A larger value
+// increases concurrency at the expense of memory.
+# define NUM_WEAKREF_LIST_LOCKS 127
+#endif
+
+/* cross-interpreter data registry */
+/* Tracks some rare events per-interpreter, used by the optimizer to turn on/off
+ specific optimizations. */
+typedef struct _rare_events {
+ /* Setting an object's class, obj.__class__ = ... */
+ uint8_t set_class;
+ /* Setting the bases of a class, cls.__bases__ = ... */
+ uint8_t set_bases;
+ /* Setting the PEP 523 frame eval function, _PyInterpreterState_SetFrameEvalFunc() */
+ uint8_t set_eval_frame_func;
+ /* Modifying the builtins, __builtins__.__dict__[var] = ... */
+ uint8_t builtin_dict;
+ /* Modifying a function, e.g. func.__defaults__ = ..., etc. */
+ uint8_t func_modification;
+} _rare_events;
/* interpreter state */
@@ -74,6 +93,11 @@ struct _xidregistry {
*/
struct _is {
+ /* This struct contains the eval_breaker,
+ * which is by far the hottest field in this struct
+ * and should be placed at the beginning. */
+ struct _ceval_state ceval;
+
PyInterpreterState *next;
int64_t id;
@@ -81,21 +105,34 @@ struct _is {
int requires_idref;
PyThread_type_lock id_mutex;
+#define _PyInterpreterState_WHENCE_NOTSET -1
+#define _PyInterpreterState_WHENCE_UNKNOWN 0
+#define _PyInterpreterState_WHENCE_RUNTIME 1
+#define _PyInterpreterState_WHENCE_LEGACY_CAPI 2
+#define _PyInterpreterState_WHENCE_CAPI 3
+#define _PyInterpreterState_WHENCE_XI 4
+#define _PyInterpreterState_WHENCE_STDLIB 5
+#define _PyInterpreterState_WHENCE_MAX 5
+ long _whence;
+
/* Has been initialized to a safe state.
In order to be effective, this must be set to 0 during or right
after allocation. */
int _initialized;
+ /* Has been fully initialized via pylifecycle.c. */
+ int _ready;
int finalizing;
- uint64_t monitoring_version;
- uint64_t last_restart_version;
+ uintptr_t last_restart_version;
struct pythreads {
uint64_t next_unique_id;
/* The linked list of threads, newest first. */
PyThreadState *head;
+ /* The thread currently executing in the __main__ module, if any. */
+ PyThreadState *main;
/* Used in Modules/_threadmodule.c. */
- long count;
+ Py_ssize_t count;
/* Support for runtime thread stack size tuning.
A value of 0 means using the platform's default stack size
or the size specified by the THREAD_STACK_SIZE macro. */
@@ -113,7 +150,9 @@ struct _is {
Use _PyInterpreterState_GetFinalizing()
and _PyInterpreterState_SetFinalizing()
to access it, don't access it directly. */
- _Py_atomic_address _finalizing;
+ PyThreadState* _finalizing;
+ /* The ID of the OS thread in which we are finalizing. */
+ unsigned long _finalizing_id;
struct _gc_runtime_state gc;
@@ -135,8 +174,6 @@ struct _is {
// Dictionary of the builtins module
PyObject *builtins;
- struct _ceval_state ceval;
-
struct _import_state imports;
/* The per-interpreter GIL, which might not be used. */
@@ -147,10 +184,7 @@ struct _is {
possible to facilitate out-of-process observability
tools. */
- PyObject *codec_search_path;
- PyObject *codec_search_cache;
- PyObject *codec_error_registry;
- int codecs_initialized;
+ struct codecs_state codecs;
PyConfig config;
unsigned long feature_flags;
@@ -169,6 +203,9 @@ struct _is {
Py_ssize_t co_extra_user_count;
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];
+ /* cross-interpreter data and utils */
+ struct _xi_state xi;
+
#ifdef HAVE_FORK
PyObject *before_forkers;
PyObject *after_forkers_parent;
@@ -177,8 +214,26 @@ struct _is {
struct _warnings_runtime_state warnings;
struct atexit_state atexit;
+ struct _stoptheworld_state stoptheworld;
+ struct _qsbr_shared qsbr;
- struct _obmalloc_state obmalloc;
+#if defined(Py_GIL_DISABLED)
+ struct _mimalloc_interp_state mimalloc;
+ struct _brc_state brc; // biased reference counting state
+ PyMutex weakref_locks[NUM_WEAKREF_LIST_LOCKS];
+#endif
+
+ // Per-interpreter state for the obmalloc allocator. For the main
+ // interpreter and for all interpreters that don't have their
+ // own obmalloc state, this points to the static structure in
+ // obmalloc.c obmalloc_state_main. For other interpreters, it is
+ // heap allocated by _PyMem_init_obmalloc() and freed when the
+ // interpreter structure is freed. In the case of a heap allocated
+ // obmalloc state, it is not safe to hold on to or use memory after
+ // the interpreter is freed. The obmalloc state corresponding to
+ // that allocated memory is gone. See free_obmalloc_arenas() for
+ // more comments.
+ struct _obmalloc_state *obmalloc;
PyObject *audit_hooks;
PyType_WatchCallback type_watchers[TYPE_MAX_WATCHERS];
@@ -188,30 +243,27 @@ struct _is {
struct _py_object_state object_state;
struct _Py_unicode_state unicode;
- struct _Py_float_state float_state;
struct _Py_long_state long_state;
struct _dtoa_state dtoa;
struct _py_func_state func_state;
- /* Using a cache is very effective since typically only a single slice is
- created and then deleted again. */
- PySliceObject *slice_cache;
+ struct _py_code_state code_state;
- struct _Py_tuple_state tuple;
- struct _Py_list_state list;
struct _Py_dict_state dict_state;
- struct _Py_async_gen_state async_gen;
- struct _Py_context_state context;
struct _Py_exc_state exc_state;
+ struct _Py_mem_interp_free_queue mem_free_queue;
struct ast_state ast;
struct types_state types;
struct callable_cache callable_cache;
- PyCodeObject *interpreter_trampoline;
+ _PyOptimizerObject *optimizer;
+ _PyExecutorObject *executor_list_head;
+
+ _rare_events rare_events;
+ PyDict_WatchCallback builtins_dict_watcher;
_Py_GlobalMonitors monitors;
- bool f_opcode_trace_set;
- bool sys_profile_initialized;
- bool sys_trace_initialized;
+ _PyOnceFlag sys_profile_once_flag;
+ _PyOnceFlag sys_trace_once_flag;
Py_ssize_t sys_profiling_threads; /* Count of threads with c_profilefunc set */
Py_ssize_t sys_tracing_threads; /* Count of threads with c_tracefunc set */
PyObject *monitoring_callables[PY_MONITORING_TOOL_IDS][_PY_MONITORING_EVENTS];
@@ -220,16 +272,11 @@ struct _is {
struct _Py_interp_cached_objects cached_objects;
struct _Py_interp_static_objects static_objects;
- // XXX Remove this field once we have a tp_* slot.
- struct _xidregistry xidregistry;
- /* The thread currently executing in the __main__ module, if any. */
- PyThreadState *threads_main;
- /* The ID of the OS thread in which we are finalizing.
- We use _Py_atomic_address instead of adding a new _Py_atomic_ulong. */
- _Py_atomic_address _finalizing_id;
-
- /* the initial PyInterpreterState.threads.head */
- PyThreadState _initial_thread;
+ /* the initial PyInterpreterState.threads.head */
+ _PyThreadStateImpl _initial_thread;
+ Py_ssize_t _interactive_src_count;
+ // In 3.14+ this is interp->threads.preallocated.
+ _PyThreadStateImpl *threads_preallocated;
};
@@ -240,35 +287,136 @@ extern void _PyInterpreterState_Clear(PyThreadState *tstate);
static inline PyThreadState*
_PyInterpreterState_GetFinalizing(PyInterpreterState *interp) {
- return (PyThreadState*)_Py_atomic_load_relaxed(&interp->_finalizing);
+ return (PyThreadState*)_Py_atomic_load_ptr_relaxed(&interp->_finalizing);
}
static inline unsigned long
_PyInterpreterState_GetFinalizingID(PyInterpreterState *interp) {
- return (unsigned long)_Py_atomic_load_relaxed(&interp->_finalizing_id);
+ return _Py_atomic_load_ulong_relaxed(&interp->_finalizing_id);
}
static inline void
_PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tstate) {
- _Py_atomic_store_relaxed(&interp->_finalizing, (uintptr_t)tstate);
+ _Py_atomic_store_ptr_relaxed(&interp->_finalizing, tstate);
if (tstate == NULL) {
- _Py_atomic_store_relaxed(&interp->_finalizing_id, 0);
+ _Py_atomic_store_ulong_relaxed(&interp->_finalizing_id, 0);
}
else {
// XXX Re-enable this assert once gh-109860 is fixed.
//assert(tstate->thread_id == PyThread_get_thread_ident());
- _Py_atomic_store_relaxed(&interp->_finalizing_id,
- (uintptr_t)tstate->thread_id);
+ _Py_atomic_store_ulong_relaxed(&interp->_finalizing_id,
+ tstate->thread_id);
}
}
-PyAPI_FUNC(PyInterpreterState*) _PyInterpreterState_LookUpID(int64_t);
+// Exports for the _testinternalcapi module.
+PyAPI_FUNC(int64_t) _PyInterpreterState_ObjectToID(PyObject *);
+PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(int64_t);
+PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpIDObject(PyObject *);
PyAPI_FUNC(int) _PyInterpreterState_IDInitref(PyInterpreterState *);
PyAPI_FUNC(int) _PyInterpreterState_IDIncref(PyInterpreterState *);
PyAPI_FUNC(void) _PyInterpreterState_IDDecref(PyInterpreterState *);
+PyAPI_FUNC(int) _PyInterpreterState_IsReady(PyInterpreterState *interp);
+
+PyAPI_FUNC(long) _PyInterpreterState_GetWhence(PyInterpreterState *interp);
+extern void _PyInterpreterState_SetWhence(
+ PyInterpreterState *interp,
+ long whence);
+
+extern const PyConfig* _PyInterpreterState_GetConfig(PyInterpreterState *interp);
+
+// Get a copy of the current interpreter configuration.
+//
+// Return 0 on success. Raise an exception and return -1 on error.
+//
+// The caller must initialize 'config', using PyConfig_InitPythonConfig()
+// for example.
+//
+// Python must be preinitialized to call this method.
+// The caller must hold the GIL.
+//
+// Once done with the configuration, PyConfig_Clear() must be called to clear
+// it.
+//
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy(
+ struct PyConfig *config);
+
+// Set the configuration of the current interpreter.
+//
+// This function should be called during or just after the Python
+// initialization.
+//
+// Update the sys module with the new configuration. If the sys module was
+// modified directly after the Python initialization, these changes are lost.
+//
+// Some configuration like faulthandler or warnoptions can be updated in the
+// configuration, but don't reconfigure Python (don't enable/disable
+// faulthandler and don't reconfigure warnings filters).
+//
+// Return 0 on success. Raise an exception and return -1 on error.
+//
+// The configuration should come from _PyInterpreterState_GetConfigCopy().
+//
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(int) _PyInterpreterState_SetConfig(
+ const struct PyConfig *config);
+
+
+/*
+Runtime Feature Flags
+
+Each flag indicate whether or not a specific runtime feature
+is available in a given context. For example, forking the process
+might not be allowed in the current interpreter (i.e. os.fork() would fail).
+*/
+
+/* Set if the interpreter share obmalloc runtime state
+ with the main interpreter. */
+#define Py_RTFLAGS_USE_MAIN_OBMALLOC (1UL << 5)
+
+/* Set if import should check a module for subinterpreter support. */
+#define Py_RTFLAGS_MULTI_INTERP_EXTENSIONS (1UL << 8)
+
+/* Set if threads are allowed. */
+#define Py_RTFLAGS_THREADS (1UL << 10)
+
+/* Set if daemon threads are allowed. */
+#define Py_RTFLAGS_DAEMON_THREADS (1UL << 11)
+
+/* Set if os.fork() is allowed. */
+#define Py_RTFLAGS_FORK (1UL << 15)
+
+/* Set if os.exec*() is allowed. */
+#define Py_RTFLAGS_EXEC (1UL << 16)
+
+extern int _PyInterpreterState_HasFeature(PyInterpreterState *interp,
+ unsigned long feature);
+
+PyAPI_FUNC(PyStatus) _PyInterpreterState_New(
+ PyThreadState *tstate,
+ PyInterpreterState **pinterp);
+
+
+#define RARE_EVENT_INTERP_INC(interp, name) \
+ do { \
+ /* saturating add */ \
+ int val = FT_ATOMIC_LOAD_UINT8_RELAXED(interp->rare_events.name); \
+ if (val < UINT8_MAX) { \
+ FT_ATOMIC_STORE_UINT8(interp->rare_events.name, val + 1); \
+ } \
+ RARE_EVENT_STAT_INC(name); \
+ } while (0); \
+
+#define RARE_EVENT_INC(name) \
+ do { \
+ PyInterpreterState *interp = PyInterpreterState_Get(); \
+ RARE_EVENT_INTERP_INC(interp, name); \
+ } while (0); \
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_intrinsics.h b/contrib/tools/python3/Include/internal/pycore_intrinsics.h
index 39f15681b7b..39c2a30f6e9 100644
--- a/contrib/tools/python3/Include/internal/pycore_intrinsics.h
+++ b/contrib/tools/python3/Include/internal/pycore_intrinsics.h
@@ -1,4 +1,9 @@
-// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py
+#ifndef Py_INTERNAL_INTRINSIC_H
+#define Py_INTERNAL_INTRINSIC_H
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
/* Unary Functions: */
#define INTRINSIC_1_INVALID 0
@@ -23,10 +28,24 @@
#define INTRINSIC_TYPEVAR_WITH_BOUND 2
#define INTRINSIC_TYPEVAR_WITH_CONSTRAINTS 3
#define INTRINSIC_SET_FUNCTION_TYPE_PARAMS 4
+#define INTRINSIC_SET_TYPEPARAM_DEFAULT 5
+
+#define MAX_INTRINSIC_2 5
+
+typedef PyObject *(*intrinsic_func1)(PyThreadState* tstate, PyObject *value);
+typedef PyObject *(*intrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
+
+typedef struct {
+ intrinsic_func1 func;
+ const char *name;
+} intrinsic_func1_info;
+
+typedef struct {
+ intrinsic_func2 func;
+ const char *name;
+} intrinsic_func2_info;
-#define MAX_INTRINSIC_2 4
+PyAPI_DATA(const intrinsic_func1_info) _PyIntrinsics_UnaryFunctions[];
+PyAPI_DATA(const intrinsic_func2_info) _PyIntrinsics_BinaryFunctions[];
-typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
-typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
-extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[];
-extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[];
+#endif // !Py_INTERNAL_INTRINSIC_H
diff --git a/contrib/tools/python3/Include/internal/pycore_jit.h b/contrib/tools/python3/Include/internal/pycore_jit.h
new file mode 100644
index 00000000000..17bd23f0752
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_jit.h
@@ -0,0 +1,25 @@
+#ifndef Py_INTERNAL_JIT_H
+#define Py_INTERNAL_JIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#ifdef _Py_JIT
+
+typedef _Py_CODEUNIT *(*jit_func)(_PyInterpreterFrame *frame, PyObject **stack_pointer, PyThreadState *tstate);
+
+int _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction *trace, size_t length);
+void _PyJIT_Free(_PyExecutorObject *executor);
+
+#endif // _Py_JIT
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !Py_INTERNAL_JIT_H
diff --git a/contrib/tools/python3/Include/internal/pycore_list.h b/contrib/tools/python3/Include/internal/pycore_list.h
index 2fcbe12cd65..73695d10e0c 100644
--- a/contrib/tools/python3/Include/internal/pycore_list.h
+++ b/contrib/tools/python3/Include/internal/pycore_list.h
@@ -8,48 +8,31 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "listobject.h" // _PyList_CAST()
+#include "pycore_freelist.h" // _PyFreeListState
-
-/* runtime lifecycle */
-
-extern void _PyList_Fini(PyInterpreterState *);
-
-
-/* other API */
-
-#ifndef WITH_FREELISTS
-// without freelists
-# define PyList_MAXFREELIST 0
-#endif
-
-/* Empty list reuse scheme to save calls to malloc and free */
-#ifndef PyList_MAXFREELIST
-# define PyList_MAXFREELIST 80
-#endif
-
-struct _Py_list_state {
-#if PyList_MAXFREELIST > 0
- PyListObject *free_list[PyList_MAXFREELIST];
- int numfree;
-#endif
-};
+PyAPI_FUNC(PyObject*) _PyList_Extend(PyListObject *, PyObject *);
+extern void _PyList_DebugMallocStats(FILE *out);
#define _PyList_ITEMS(op) _Py_RVALUE(_PyList_CAST(op)->ob_item)
-extern int
+PyAPI_FUNC(int)
_PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem);
+// In free-threaded build: self should be locked by the caller, if it should be thread-safe.
static inline int
_PyList_AppendTakeRef(PyListObject *self, PyObject *newitem)
{
assert(self != NULL && newitem != NULL);
assert(PyList_Check(self));
- Py_ssize_t len = PyList_GET_SIZE(self);
+ Py_ssize_t len = Py_SIZE(self);
Py_ssize_t allocated = self->allocated;
assert((size_t)len + 1 < PY_SSIZE_T_MAX);
if (allocated > len) {
+#ifdef Py_GIL_DISABLED
+ _Py_atomic_store_ptr_release(&self->ob_item[len], newitem);
+#else
PyList_SET_ITEM(self, len, newitem);
+#endif
Py_SET_SIZE(self, len + 1);
return 0;
}
@@ -75,7 +58,7 @@ typedef struct {
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
} _PyListIterObject;
-extern PyObject *_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n);
+PyAPI_FUNC(PyObject *)_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_llist.h b/contrib/tools/python3/Include/internal/pycore_llist.h
new file mode 100644
index 00000000000..f629902fda9
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_llist.h
@@ -0,0 +1,106 @@
+// A doubly-linked list that can be embedded in a struct.
+//
+// Usage:
+// struct llist_node head = LLIST_INIT(head);
+// typedef struct {
+// ...
+// struct llist_node node;
+// ...
+// } MyObj;
+//
+// llist_insert_tail(&head, &obj->node);
+// llist_remove(&obj->node);
+//
+// struct llist_node *node;
+// llist_for_each(node, &head) {
+// MyObj *obj = llist_data(node, MyObj, node);
+// ...
+// }
+//
+
+#ifndef Py_INTERNAL_LLIST_H
+#define Py_INTERNAL_LLIST_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "Py_BUILD_CORE must be defined to include this header"
+#endif
+
+struct llist_node {
+ struct llist_node *next;
+ struct llist_node *prev;
+};
+
+// Get the struct containing a node.
+#define llist_data(node, type, member) (_Py_CONTAINER_OF(node, type, member))
+
+// Iterate over a list.
+#define llist_for_each(node, head) \
+ for (node = (head)->next; node != (head); node = node->next)
+
+// Iterate over a list, but allow removal of the current node.
+#define llist_for_each_safe(node, head) \
+ for (struct llist_node *_next = (node = (head)->next, node->next); \
+ node != (head); node = _next, _next = node->next)
+
+#define LLIST_INIT(head) { &head, &head }
+
+static inline void
+llist_init(struct llist_node *head)
+{
+ head->next = head;
+ head->prev = head;
+}
+
+// Returns 1 if the list is empty, 0 otherwise.
+static inline int
+llist_empty(struct llist_node *head)
+{
+ return head->next == head;
+}
+
+// Appends to the tail of the list.
+static inline void
+llist_insert_tail(struct llist_node *head, struct llist_node *node)
+{
+ node->prev = head->prev;
+ node->next = head;
+ head->prev->next = node;
+ head->prev = node;
+}
+
+// Remove a node from the list.
+static inline void
+llist_remove(struct llist_node *node)
+{
+ struct llist_node *prev = node->prev;
+ struct llist_node *next = node->next;
+ prev->next = next;
+ next->prev = prev;
+ node->prev = NULL;
+ node->next = NULL;
+}
+
+// Append all nodes from head2 onto head1. head2 is left empty.
+static inline void
+llist_concat(struct llist_node *head1, struct llist_node *head2)
+{
+ if (!llist_empty(head2)) {
+ head1->prev->next = head2->next;
+ head2->next->prev = head1->prev;
+
+ head1->prev = head2->prev;
+ head2->prev->next = head1;
+ llist_init(head2);
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_LLIST_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_lock.h b/contrib/tools/python3/Include/internal/pycore_lock.h
new file mode 100644
index 00000000000..2a18bb76447
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_lock.h
@@ -0,0 +1,241 @@
+// Lightweight locks and other synchronization mechanisms.
+//
+// These implementations are based on WebKit's WTF::Lock. See
+// https://webkit.org/blog/6161/locking-in-webkit/ for a description of the
+// design.
+#ifndef Py_INTERNAL_LOCK_H
+#define Py_INTERNAL_LOCK_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+//_Py_UNLOCKED is defined as 0 and _Py_LOCKED as 1 in Include/cpython/lock.h
+#define _Py_HAS_PARKED 2
+#define _Py_ONCE_INITIALIZED 4
+
+static inline int
+PyMutex_LockFast(uint8_t *lock_bits)
+{
+ uint8_t expected = _Py_UNLOCKED;
+ return _Py_atomic_compare_exchange_uint8(lock_bits, &expected, _Py_LOCKED);
+}
+
+// Checks if the mutex is currently locked.
+static inline int
+PyMutex_IsLocked(PyMutex *m)
+{
+ return (_Py_atomic_load_uint8(&m->_bits) & _Py_LOCKED) != 0;
+}
+
+// Re-initializes the mutex after a fork to the unlocked state.
+static inline void
+_PyMutex_at_fork_reinit(PyMutex *m)
+{
+ memset(m, 0, sizeof(*m));
+}
+
+typedef enum _PyLockFlags {
+ // Do not detach/release the GIL when waiting on the lock.
+ _Py_LOCK_DONT_DETACH = 0,
+
+ // Detach/release the GIL while waiting on the lock.
+ _PY_LOCK_DETACH = 1,
+
+ // Handle signals if interrupted while waiting on the lock.
+ _PY_LOCK_HANDLE_SIGNALS = 2,
+} _PyLockFlags;
+
+// Lock a mutex with an optional timeout and additional options. See
+// _PyLockFlags for details.
+extern PyLockStatus
+_PyMutex_LockTimed(PyMutex *m, PyTime_t timeout_ns, _PyLockFlags flags);
+
+// Lock a mutex with aditional options. See _PyLockFlags for details.
+static inline void
+PyMutex_LockFlags(PyMutex *m, _PyLockFlags flags)
+{
+ uint8_t expected = _Py_UNLOCKED;
+ if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_LOCKED)) {
+ _PyMutex_LockTimed(m, -1, flags);
+ }
+}
+
+// Unlock a mutex, returns 0 if the mutex is not locked (used for improved
+// error messages).
+extern int _PyMutex_TryUnlock(PyMutex *m);
+
+
+// PyEvent is a one-time event notification
+typedef struct {
+ uint8_t v;
+} PyEvent;
+
+// Check if the event is set without blocking. Returns 1 if the event is set or
+// 0 otherwise.
+PyAPI_FUNC(int) _PyEvent_IsSet(PyEvent *evt);
+
+// Set the event and notify any waiting threads.
+// Export for '_testinternalcapi' shared extension
+PyAPI_FUNC(void) _PyEvent_Notify(PyEvent *evt);
+
+// Wait for the event to be set. If the event is already set, then this returns
+// immediately.
+PyAPI_FUNC(void) PyEvent_Wait(PyEvent *evt);
+
+// Wait for the event to be set, or until the timeout expires. If the event is
+// already set, then this returns immediately. Returns 1 if the event was set,
+// and 0 if the timeout expired or thread was interrupted. If `detach` is
+// true, then the thread will detach/release the GIL while waiting.
+PyAPI_FUNC(int)
+PyEvent_WaitTimed(PyEvent *evt, PyTime_t timeout_ns, int detach);
+
+// _PyRawMutex implements a word-sized mutex that that does not depend on the
+// parking lot API, and therefore can be used in the parking lot
+// implementation.
+//
+// The mutex uses a packed representation: the least significant bit is used to
+// indicate whether the mutex is locked or not. The remaining bits are either
+// zero or a pointer to a `struct raw_mutex_entry` (see lock.c).
+typedef struct {
+ uintptr_t v;
+} _PyRawMutex;
+
+// Slow paths for lock/unlock
+extern void _PyRawMutex_LockSlow(_PyRawMutex *m);
+extern void _PyRawMutex_UnlockSlow(_PyRawMutex *m);
+
+static inline void
+_PyRawMutex_Lock(_PyRawMutex *m)
+{
+ uintptr_t unlocked = _Py_UNLOCKED;
+ if (_Py_atomic_compare_exchange_uintptr(&m->v, &unlocked, _Py_LOCKED)) {
+ return;
+ }
+ _PyRawMutex_LockSlow(m);
+}
+
+static inline void
+_PyRawMutex_Unlock(_PyRawMutex *m)
+{
+ uintptr_t locked = _Py_LOCKED;
+ if (_Py_atomic_compare_exchange_uintptr(&m->v, &locked, _Py_UNLOCKED)) {
+ return;
+ }
+ _PyRawMutex_UnlockSlow(m);
+}
+
+// Type signature for one-time initialization functions. The function should
+// return 0 on success and -1 on failure.
+typedef int _Py_once_fn_t(void *arg);
+
+// (private) slow path for one time initialization
+PyAPI_FUNC(int)
+_PyOnceFlag_CallOnceSlow(_PyOnceFlag *flag, _Py_once_fn_t *fn, void *arg);
+
+// Calls `fn` once using `flag`. The `arg` is passed to the call to `fn`.
+//
+// Returns 0 on success and -1 on failure.
+//
+// If `fn` returns 0 (success), then subsequent calls immediately return 0.
+// If `fn` returns -1 (failure), then subsequent calls will retry the call.
+static inline int
+_PyOnceFlag_CallOnce(_PyOnceFlag *flag, _Py_once_fn_t *fn, void *arg)
+{
+ if (_Py_atomic_load_uint8(&flag->v) == _Py_ONCE_INITIALIZED) {
+ return 0;
+ }
+ return _PyOnceFlag_CallOnceSlow(flag, fn, arg);
+}
+
+// A recursive mutex. The mutex should zero-initialized.
+typedef struct {
+ PyMutex mutex;
+ unsigned long long thread; // i.e., PyThread_get_thread_ident_ex()
+ size_t level;
+} _PyRecursiveMutex;
+
+PyAPI_FUNC(int) _PyRecursiveMutex_IsLockedByCurrentThread(_PyRecursiveMutex *m);
+PyAPI_FUNC(void) _PyRecursiveMutex_Lock(_PyRecursiveMutex *m);
+PyAPI_FUNC(void) _PyRecursiveMutex_Unlock(_PyRecursiveMutex *m);
+
+
+// A readers-writer (RW) lock. The lock supports multiple concurrent readers or
+// a single writer. The lock is write-preferring: if a writer is waiting while
+// the lock is read-locked then, new readers will be blocked. This avoids
+// starvation of writers.
+//
+// In C++, the equivalent synchronization primitive is std::shared_mutex
+// with shared ("read") and exclusive ("write") locking.
+//
+// The two least significant bits are used to indicate if the lock is
+// write-locked and if there are parked threads (either readers or writers)
+// waiting to acquire the lock. The remaining bits are used to indicate the
+// number of readers holding the lock.
+//
+// 0b000..00000: unlocked
+// 0bnnn..nnn00: nnn..nnn readers holding the lock
+// 0bnnn..nnn10: nnn..nnn readers holding the lock and a writer is waiting
+// 0b00000..010: unlocked with awoken writer about to acquire lock
+// 0b00000..001: write-locked
+// 0b00000..011: write-locked and readers or other writers are waiting
+//
+// Note that reader_count must be zero if the lock is held by a writer, and
+// vice versa. The lock can only be held by readers or a writer, but not both.
+//
+// The design is optimized for simplicity of the implementation. The lock is
+// not fair: if fairness is desired, use an additional PyMutex to serialize
+// writers. The lock is also not reentrant.
+typedef struct {
+ uintptr_t bits;
+} _PyRWMutex;
+
+// Read lock (i.e., shared lock)
+PyAPI_FUNC(void) _PyRWMutex_RLock(_PyRWMutex *rwmutex);
+PyAPI_FUNC(void) _PyRWMutex_RUnlock(_PyRWMutex *rwmutex);
+
+// Write lock (i.e., exclusive lock)
+PyAPI_FUNC(void) _PyRWMutex_Lock(_PyRWMutex *rwmutex);
+PyAPI_FUNC(void) _PyRWMutex_Unlock(_PyRWMutex *rwmutex);
+
+// Similar to linux seqlock: https://en.wikipedia.org/wiki/Seqlock
+// We use a sequence number to lock the writer, an even sequence means we're unlocked, an odd
+// sequence means we're locked. Readers will read the sequence before attempting to read the
+// underlying data and then read the sequence number again after reading the data. If the
+// sequence has not changed the data is valid.
+//
+// Differs a little bit in that we use CAS on sequence as the lock, instead of a separate spin lock.
+// The writer can also detect that the undelering data has not changed and abandon the write
+// and restore the previous sequence.
+typedef struct {
+ uint32_t sequence;
+} _PySeqLock;
+
+// Lock the sequence lock for the writer
+PyAPI_FUNC(void) _PySeqLock_LockWrite(_PySeqLock *seqlock);
+
+// Unlock the sequence lock and move to the next sequence number.
+PyAPI_FUNC(void) _PySeqLock_UnlockWrite(_PySeqLock *seqlock);
+
+// Abandon the current update indicating that no mutations have occurred
+// and restore the previous sequence value.
+PyAPI_FUNC(void) _PySeqLock_AbandonWrite(_PySeqLock *seqlock);
+
+// Begin a read operation and return the current sequence number.
+PyAPI_FUNC(uint32_t) _PySeqLock_BeginRead(_PySeqLock *seqlock);
+
+// End the read operation and confirm that the sequence number has not changed.
+// Returns 1 if the read was successful or 0 if the read should be retried.
+PyAPI_FUNC(int) _PySeqLock_EndRead(_PySeqLock *seqlock, uint32_t previous);
+
+// Check if the lock was held during a fork and clear the lock. Returns 1
+// if the lock was held and any associated data should be cleared.
+PyAPI_FUNC(int) _PySeqLock_AfterFork(_PySeqLock *seqlock);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_LOCK_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_long.h b/contrib/tools/python3/Include/internal/pycore_long.h
index 64c00cb1475..ff7d9afc03a 100644
--- a/contrib/tools/python3/Include/internal/pycore_long.h
+++ b/contrib/tools/python3/Include/internal/pycore_long.h
@@ -8,7 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_global_objects.h" // _PY_NSMALLNEGINTS
+#include "pycore_bytesobject.h" // _PyBytesWriter
+#include "pycore_global_objects.h"// _PY_NSMALLNEGINTS
#include "pycore_runtime.h" // _PyRuntime
/*
@@ -46,7 +47,6 @@ extern "C" {
# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
#endif
-
/* runtime lifecycle */
extern PyStatus _PyLong_InitTypes(PyInterpreterState *);
@@ -63,51 +63,99 @@ extern void _PyLong_FiniTypes(PyInterpreterState *interp);
# error "_PY_NSMALLPOSINTS must be greater than or equal to 257"
#endif
-// Return a borrowed reference to the zero singleton.
+// Return a reference to the immortal zero singleton.
// The function cannot return NULL.
static inline PyObject* _PyLong_GetZero(void)
{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; }
-// Return a borrowed reference to the one singleton.
+// Return a reference to the immortal one singleton.
// The function cannot return NULL.
static inline PyObject* _PyLong_GetOne(void)
{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i)
{
- return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]);
+ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i];
}
-PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
-PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
-PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
+// _PyLong_Frexp returns a double x and an exponent e such that the
+// true value is approximately equal to x * 2**e. e is >= 0. x is
+// 0.0 if and only if the input is 0 (in which case, e and x are both
+// zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is
+// possible if the number of bits doesn't fit into a Py_ssize_t, sets
+// OverflowError and returns -1.0 for x, 0 for e.
+//
+// Export for 'math' shared extension
+PyAPI_DATA(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);
+
+extern PyObject* _PyLong_FromBytes(const char *, Py_ssize_t, int);
+
+// _PyLong_DivmodNear. Given integers a and b, compute the nearest
+// integer q to the exact quotient a / b, rounding to the nearest even integer
+// in the case of a tie. Return (q, r), where r = a - q*b. The remainder r
+// will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
+// even.
+//
+// Export for '_datetime' shared extension.
+PyAPI_DATA(PyObject*) _PyLong_DivmodNear(PyObject *, PyObject *);
+
+// _PyLong_Format: Convert the long to a string object with given base,
+// appending a base prefix of 0[box] if base is 2, 8 or 16.
+// Export for '_tkinter' shared extension.
+PyAPI_DATA(PyObject*) _PyLong_Format(PyObject *obj, int base);
-/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
- _PyBytes_DecodeEscape(), etc. */
+// Export for 'math' shared extension
+PyAPI_DATA(PyObject*) _PyLong_Rshift(PyObject *, size_t);
+
+// Export for 'math' shared extension
+PyAPI_DATA(PyObject*) _PyLong_Lshift(PyObject *, size_t);
+
+PyAPI_FUNC(PyObject*) _PyLong_Add(PyLongObject *left, PyLongObject *right);
+PyAPI_FUNC(PyObject*) _PyLong_Multiply(PyLongObject *left, PyLongObject *right);
+PyAPI_FUNC(PyObject*) _PyLong_Subtract(PyLongObject *left, PyLongObject *right);
+
+// Export for 'binascii' shared extension.
PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
/* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */
-PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter(
+extern int _PyLong_FormatAdvancedWriter(
_PyUnicodeWriter *writer,
PyObject *obj,
PyObject *format_spec,
Py_ssize_t start,
Py_ssize_t end);
-PyAPI_FUNC(int) _PyLong_FormatWriter(
+extern int _PyLong_FormatWriter(
_PyUnicodeWriter *writer,
PyObject *obj,
int base,
int alternate);
-PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
+extern char* _PyLong_FormatBytesWriter(
_PyBytesWriter *writer,
char *str,
PyObject *obj,
int base,
int alternate);
+// Argument converters used by Argument Clinic
+
+// Export for 'select' shared extension (Argument Clinic code)
+PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
+
+// Export for '_testclinic' shared extension (Argument Clinic code)
+PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);
+
+// Export for '_blake2' shared extension (Argument Clinic code)
+PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
+
+// Export for '_blake2' shared extension (Argument Clinic code)
+PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
+
+// Export for '_testclinic' shared extension (Argument Clinic code)
+PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);
+
/* Long value tag bits:
* 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1.
* 2: Reserved for immortality bit
@@ -130,8 +178,12 @@ PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
* we define them to the numbers in both places and then assert that
* they're the same.
*/
-static_assert(SIGN_MASK == _PyLong_SIGN_MASK, "SIGN_MASK does not match _PyLong_SIGN_MASK");
-static_assert(NON_SIZE_BITS == _PyLong_NON_SIZE_BITS, "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS");
+#if SIGN_MASK != _PyLong_SIGN_MASK
+# error "SIGN_MASK does not match _PyLong_SIGN_MASK"
+#endif
+#if NON_SIZE_BITS != _PyLong_NON_SIZE_BITS
+# error "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS"
+#endif
/* All *compact" values are guaranteed to fit into
* a Py_ssize_t with at least one bit to spare.
@@ -240,7 +292,7 @@ _PyLong_FlipSign(PyLongObject *op) {
#define _PyLong_DIGIT_INIT(val) \
{ \
- .ob_base = _PyObject_HEAD_INIT(&PyLong_Type) \
+ .ob_base = _PyObject_HEAD_INIT(&PyLong_Type), \
.long_value = { \
.lv_tag = TAG_FROM_SIGN_AND_SIZE( \
(val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \
diff --git a/contrib/tools/python3/Include/internal/pycore_memoryobject.h b/contrib/tools/python3/Include/internal/pycore_memoryobject.h
index fe19e3f9611..62e204fcbf6 100644
--- a/contrib/tools/python3/Include/internal/pycore_memoryobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_memoryobject.h
@@ -8,6 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+extern PyTypeObject _PyManagedBuffer_Type;
+
PyObject *
_PyMemoryView_FromBufferProc(PyObject *v, int flags,
getbufferproc bufferproc);
diff --git a/contrib/tools/python3/Include/internal/pycore_mimalloc.h b/contrib/tools/python3/Include/internal/pycore_mimalloc.h
new file mode 100644
index 00000000000..d870d01beb7
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_mimalloc.h
@@ -0,0 +1,69 @@
+#ifndef Py_INTERNAL_MIMALLOC_H
+#define Py_INTERNAL_MIMALLOC_H
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#if defined(MIMALLOC_H) || defined(MIMALLOC_TYPES_H)
+# error "pycore_mimalloc.h must be included before mimalloc.h"
+#endif
+
+typedef enum {
+ _Py_MIMALLOC_HEAP_MEM = 0, // PyMem_Malloc() and friends
+ _Py_MIMALLOC_HEAP_OBJECT = 1, // non-GC objects
+ _Py_MIMALLOC_HEAP_GC = 2, // GC objects without pre-header
+ _Py_MIMALLOC_HEAP_GC_PRE = 3, // GC objects with pre-header
+ _Py_MIMALLOC_HEAP_COUNT
+} _Py_mimalloc_heap_id;
+
+#include "pycore_pymem.h"
+
+#ifdef WITH_MIMALLOC
+# ifdef Py_GIL_DISABLED
+# define MI_PRIM_THREAD_ID _Py_ThreadId
+# endif
+# define MI_DEBUG_UNINIT PYMEM_CLEANBYTE
+# define MI_DEBUG_FREED PYMEM_DEADBYTE
+# define MI_DEBUG_PADDING PYMEM_FORBIDDENBYTE
+#ifdef Py_DEBUG
+# define MI_DEBUG 2
+#else
+# define MI_DEBUG 0
+#endif
+
+#ifdef _Py_THREAD_SANITIZER
+# define MI_TSAN 1
+#endif
+
+#ifdef __cplusplus
+extern "C++" {
+#endif
+
+#include "mimalloc/mimalloc.h"
+#include "mimalloc/mimalloc/types.h"
+#include "mimalloc/mimalloc/internal.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#ifdef Py_GIL_DISABLED
+struct _mimalloc_interp_state {
+ // When exiting, threads place any segments with live blocks in this
+ // shared pool for other threads to claim and reuse.
+ mi_abandoned_pool_t abandoned_pool;
+};
+
+struct _mimalloc_thread_state {
+ mi_heap_t *current_object_heap;
+ mi_heap_t heaps[_Py_MIMALLOC_HEAP_COUNT];
+ mi_tld_t tld;
+ int initialized;
+ struct llist_node page_list;
+};
+#endif
+
+#endif // Py_INTERNAL_MIMALLOC_H
diff --git a/contrib/tools/python3/Include/internal/pycore_modsupport.h b/contrib/tools/python3/Include/internal/pycore_modsupport.h
new file mode 100644
index 00000000000..11fde814875
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_modsupport.h
@@ -0,0 +1,107 @@
+#ifndef Py_INTERNAL_MODSUPPORT_H
+#define Py_INTERNAL_MODSUPPORT_H
+
+#include "pycore_lock.h" // _PyOnceFlag
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+extern int _PyArg_NoKwnames(const char *funcname, PyObject *kwnames);
+#define _PyArg_NoKwnames(funcname, kwnames) \
+ ((kwnames) == NULL || _PyArg_NoKwnames((funcname), (kwnames)))
+
+// Export for '_bz2' shared extension
+PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args);
+#define _PyArg_NoPositional(funcname, args) \
+ ((args) == NULL || _PyArg_NoPositional((funcname), (args)))
+
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kwargs);
+#define _PyArg_NoKeywords(funcname, kwargs) \
+ ((kwargs) == NULL || _PyArg_NoKeywords((funcname), (kwargs)))
+
+// Export for 'zlib' shared extension
+PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t,
+ Py_ssize_t, Py_ssize_t);
+#define _Py_ANY_VARARGS(n) ((n) == PY_SSIZE_T_MAX)
+#define _PyArg_CheckPositional(funcname, nargs, min, max) \
+ ((!_Py_ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \
+ || _PyArg_CheckPositional((funcname), (nargs), (min), (max)))
+
+extern PyObject ** _Py_VaBuildStack(
+ PyObject **small_stack,
+ Py_ssize_t small_stack_len,
+ const char *format,
+ va_list va,
+ Py_ssize_t *p_nargs);
+
+extern PyObject* _PyModule_CreateInitialized(PyModuleDef*, int apiver);
+
+// Export for '_curses' shared extension
+PyAPI_FUNC(int) _PyArg_ParseStack(
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ const char *format,
+ ...);
+
+extern int _PyArg_UnpackStack(
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ const char *name,
+ Py_ssize_t min,
+ Py_ssize_t max,
+ ...);
+
+// Export for '_heapq' shared extension
+PyAPI_FUNC(void) _PyArg_BadArgument(
+ const char *fname,
+ const char *displayname,
+ const char *expected,
+ PyObject *arg);
+
+// --- _PyArg_Parser API ---------------------------------------------------
+
+// Export for '_dbm' shared extension
+PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords(
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ PyObject *kwnames,
+ struct _PyArg_Parser *,
+ ...);
+
+// Export for 'math' shared extension
+PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords(
+ PyObject *const *args,
+ Py_ssize_t nargs,
+ PyObject *kwargs,
+ PyObject *kwnames,
+ struct _PyArg_Parser *parser,
+ int minpos,
+ int maxpos,
+ int minkw,
+ PyObject **buf);
+#define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \
+ (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \
+ (minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? (args) : \
+ _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \
+ (minpos), (maxpos), (minkw), (buf)))
+
+// Export for '_testclinic' shared extension
+PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg(
+ PyObject *const *args, Py_ssize_t nargs,
+ PyObject *kwargs, PyObject *kwnames,
+ struct _PyArg_Parser *parser,
+ int minpos, int maxpos, int minkw,
+ int vararg, PyObject **buf);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_MODSUPPORT_H
+
diff --git a/contrib/tools/python3/Include/internal/pycore_moduleobject.h b/contrib/tools/python3/Include/internal/pycore_moduleobject.h
index 15a1bcb6ae5..dacc00dba54 100644
--- a/contrib/tools/python3/Include/internal/pycore_moduleobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_moduleobject.h
@@ -8,6 +8,14 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+extern void _PyModule_Clear(PyObject *);
+extern void _PyModule_ClearDict(PyObject *);
+extern int _PyModuleSpec_IsInitializing(PyObject *);
+extern int _PyModuleSpec_GetFileOrigin(PyObject *, PyObject **);
+extern int _PyModule_IsPossiblyShadowing(PyObject *);
+
+extern int _PyModule_IsExtension(PyObject *obj);
+
typedef struct {
PyObject_HEAD
PyObject *md_dict;
@@ -16,6 +24,9 @@ typedef struct {
PyObject *md_weaklist;
// for logging purposes after md_dict is cleared
PyObject *md_name;
+#ifdef Py_GIL_DISABLED
+ void *md_gil;
+#endif
} PyModuleObject;
static inline PyModuleDef* _PyModule_GetDef(PyObject *mod) {
@@ -33,7 +44,7 @@ static inline PyObject* _PyModule_GetDict(PyObject *mod) {
PyObject *dict = ((PyModuleObject *)mod) -> md_dict;
// _PyModule_GetDict(mod) must not be used after calling module_clear(mod)
assert(dict != NULL);
- return dict;
+ return dict; // borrowed reference
}
PyObject* _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress);
diff --git a/contrib/tools/python3/Include/internal/pycore_namespace.h b/contrib/tools/python3/Include/internal/pycore_namespace.h
index cb76f040693..f165cf15319 100644
--- a/contrib/tools/python3/Include/internal/pycore_namespace.h
+++ b/contrib/tools/python3/Include/internal/pycore_namespace.h
@@ -10,9 +10,10 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-PyAPI_DATA(PyTypeObject) _PyNamespace_Type;
+extern PyTypeObject _PyNamespace_Type;
-PyAPI_FUNC(PyObject *) _PyNamespace_New(PyObject *kwds);
+// Export for '_testmultiphase' shared extension
+PyAPI_FUNC(PyObject*) _PyNamespace_New(PyObject *kwds);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_object.h b/contrib/tools/python3/Include/internal/pycore_object.h
index de82d9e76f3..5877d43f4fd 100644
--- a/contrib/tools/python3/Include/internal/pycore_object.h
+++ b/contrib/tools/python3/Include/internal/pycore_object.h
@@ -10,29 +10,93 @@ extern "C" {
#include <stdbool.h>
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
+#include "pycore_emscripten_trampoline.h" // _PyCFunction_TrampolineCall()
#include "pycore_interp.h" // PyInterpreterState.gc
+#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED
#include "pycore_pystate.h" // _PyInterpreterState_GET()
-#include "pycore_runtime.h" // _PyRuntime
+
+
+#define _Py_IMMORTAL_REFCNT_LOOSE ((_Py_IMMORTAL_REFCNT >> 1) + 1)
+
+// gh-121528, gh-118997: Similar to _Py_IsImmortal() but be more loose when
+// comparing the reference count to stay compatible with C extensions built
+// with the stable ABI 3.11 or older. Such extensions implement INCREF/DECREF
+// as refcnt++ and refcnt-- without taking in account immortal objects. For
+// example, the reference count of an immortal object can change from
+// _Py_IMMORTAL_REFCNT to _Py_IMMORTAL_REFCNT+1 (INCREF) or
+// _Py_IMMORTAL_REFCNT-1 (DECREF).
+//
+// This function should only be used in assertions. Otherwise, _Py_IsImmortal()
+// must be used instead.
+static inline int _Py_IsImmortalLoose(PyObject *op)
+{
+#if defined(Py_GIL_DISABLED)
+ return _Py_IsImmortal(op);
+#else
+ return (op->ob_refcnt >= _Py_IMMORTAL_REFCNT_LOOSE);
+#endif
+}
+#define _Py_IsImmortalLoose(op) _Py_IsImmortalLoose(_PyObject_CAST(op))
+
+
+/* Check if an object is consistent. For example, ensure that the reference
+ counter is greater than or equal to 1, and ensure that ob_type is not NULL.
+
+ Call _PyObject_AssertFailed() if the object is inconsistent.
+
+ If check_content is zero, only check header fields: reduce the overhead.
+
+ The function always return 1. The return value is just here to be able to
+ write:
+
+ assert(_PyObject_CheckConsistency(obj, 1)); */
+extern int _PyObject_CheckConsistency(PyObject *op, int check_content);
+
+extern void _PyDebugAllocatorStats(FILE *out, const char *block_name,
+ int num_blocks, size_t sizeof_block);
+
+extern void _PyObject_DebugTypeStats(FILE *out);
+
+#ifdef Py_TRACE_REFS
+// Forget a reference registered by _Py_NewReference(). Function called by
+// _Py_Dealloc().
+//
+// On a free list, the function can be used before modifying an object to
+// remove the object from traced objects. Then _Py_NewReference() or
+// _Py_NewReferenceNoTotal() should be called again on the object to trace
+// it again.
+extern void _Py_ForgetReference(PyObject *);
+#endif
+
+// Export for shared _testinternalcapi extension
+PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
/* We need to maintain an internal copy of Py{Var}Object_HEAD_INIT to avoid
- designated initializer conflicts in C++20. If we use the deinition in
+ designated initializer conflicts in C++20. If we use the definition in
object.h, we will be mixing designated and non-designated initializers in
pycore objects which is forbiddent in C++20. However, if we then use
designated initializers in object.h then Extensions without designated break.
Furthermore, we can't use designated initializers in Extensions since these
are not supported pre-C++20. Thus, keeping an internal copy here is the most
backwards compatible solution */
+#if defined(Py_GIL_DISABLED)
+#define _PyObject_HEAD_INIT(type) \
+ { \
+ .ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL, \
+ .ob_type = (type) \
+ }
+#else
#define _PyObject_HEAD_INIT(type) \
{ \
- _PyObject_EXTRA_INIT \
.ob_refcnt = _Py_IMMORTAL_REFCNT, \
.ob_type = (type) \
- },
+ }
+#endif
#define _PyVarObject_HEAD_INIT(type, size) \
{ \
- .ob_base = _PyObject_HEAD_INIT(type) \
+ .ob_base = _PyObject_HEAD_INIT(type), \
.ob_size = size \
- },
+ }
PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
const char *func,
@@ -41,15 +105,23 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
#define _Py_FatalRefcountError(message) \
_Py_FatalRefcountErrorFunc(__func__, (message))
+#define _PyReftracerTrack(obj, operation) \
+ do { \
+ struct _reftracer_runtime_state *tracer = &_PyRuntime.ref_tracer; \
+ if (tracer->tracer_func != NULL) { \
+ void *data = tracer->tracer_data; \
+ tracer->tracer_func((obj), (operation), data); \
+ } \
+ } while(0)
#ifdef Py_REF_DEBUG
/* The symbol is only exposed in the API for the sake of extensions
built against the pre-3.12 stable ABI. */
PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
-extern void _Py_AddRefTotal(PyInterpreterState *, Py_ssize_t);
-extern void _Py_IncRefTotal(PyInterpreterState *);
-extern void _Py_DecRefTotal(PyInterpreterState *);
+extern void _Py_AddRefTotal(PyThreadState *, Py_ssize_t);
+extern void _Py_IncRefTotal(PyThreadState *);
+extern void _Py_DecRefTotal(PyThreadState *);
# define _Py_DEC_REFTOTAL(interp) \
interp->object_state.reftotal--
@@ -62,10 +134,27 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n)
return;
}
#ifdef Py_REF_DEBUG
- _Py_AddRefTotal(_PyInterpreterState_GET(), n);
+ _Py_AddRefTotal(_PyThreadState_GET(), n);
#endif
+#if !defined(Py_GIL_DISABLED)
op->ob_refcnt += n;
-
+#else
+ if (_Py_IsOwnedByCurrentThread(op)) {
+ uint32_t local = op->ob_ref_local;
+ Py_ssize_t refcnt = (Py_ssize_t)local + n;
+# if PY_SSIZE_T_MAX > UINT32_MAX
+ if (refcnt > (Py_ssize_t)UINT32_MAX) {
+ // Make the object immortal if the 32-bit local reference count
+ // would overflow.
+ refcnt = _Py_IMMORTAL_REFCNT_LOCAL;
+ }
+# endif
+ _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, (uint32_t)refcnt);
+ }
+ else {
+ _Py_atomic_add_ssize(&op->ob_ref_shared, (n << _Py_REF_SHARED_SHIFT));
+ }
+#endif
// Although the ref count was increased by `n` (which may be greater than 1)
// it is only a single increment (i.e. addition) operation, so only 1 refcnt
// increment operation is counted.
@@ -73,27 +162,47 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n)
}
#define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n)
-static inline void _Py_SetImmortal(PyObject *op)
+extern void _Py_SetImmortal(PyObject *op);
+extern void _Py_SetImmortalUntracked(PyObject *op);
+
+// Checks if an object has a single, unique reference. If the caller holds a
+// unique reference, it may be able to safely modify the object in-place.
+static inline int
+_PyObject_IsUniquelyReferenced(PyObject *ob)
{
-#ifdef Py_DEBUG
- // For strings, use _PyUnicode_InternImmortal instead.
- if (PyUnicode_CheckExact(op)) {
- assert(PyUnicode_CHECK_INTERNED(op) == SSTATE_INTERNED_IMMORTAL
- || PyUnicode_CHECK_INTERNED(op) == SSTATE_INTERNED_IMMORTAL_STATIC);
- }
+#if !defined(Py_GIL_DISABLED)
+ return Py_REFCNT(ob) == 1;
+#else
+ // NOTE: the entire ob_ref_shared field must be zero, including flags, to
+ // ensure that other threads cannot concurrently create new references to
+ // this object.
+ return (_Py_IsOwnedByCurrentThread(ob) &&
+ _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local) == 1 &&
+ _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared) == 0);
#endif
+}
+
+// Makes an immortal object mortal again with the specified refcnt. Should only
+// be used during runtime finalization.
+static inline void _Py_SetMortal(PyObject *op, Py_ssize_t refcnt)
+{
if (op) {
- op->ob_refcnt = _Py_IMMORTAL_REFCNT;
+ assert(_Py_IsImmortalLoose(op));
+#ifdef Py_GIL_DISABLED
+ op->ob_tid = _Py_UNOWNED_TID;
+ op->ob_ref_local = 0;
+ op->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED);
+#else
+ op->ob_refcnt = refcnt;
+#endif
}
}
-#define _Py_SetImmortal(op) _Py_SetImmortal(_PyObject_CAST(op))
/* _Py_ClearImmortal() should only be used during runtime finalization. */
static inline void _Py_ClearImmortal(PyObject *op)
{
if (op) {
- assert(_Py_IsImmortal(op));
- op->ob_refcnt = 1;
+ _Py_SetMortal(op, 1);
Py_DECREF(op);
}
}
@@ -103,6 +212,22 @@ static inline void _Py_ClearImmortal(PyObject *op)
op = NULL; \
} while (0)
+// Mark an object as supporting deferred reference counting. This is a no-op
+// in the default (with GIL) build. Objects that use deferred reference
+// counting should be tracked by the GC so that they are eventually collected.
+extern void _PyObject_SetDeferredRefcount(PyObject *op);
+
+static inline int
+_PyObject_HasDeferredRefcount(PyObject *op)
+{
+#ifdef Py_GIL_DISABLED
+ return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_DEFERRED);
+#else
+ return 0;
+#endif
+}
+
+#if !defined(Py_GIL_DISABLED)
static inline void
_Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
{
@@ -111,7 +236,7 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
}
_Py_DECREF_STAT_INC();
#ifdef Py_REF_DEBUG
- _Py_DEC_REFTOTAL(_PyInterpreterState_GET());
+ _Py_DEC_REFTOTAL(PyInterpreterState_Get());
#endif
if (--op->ob_refcnt != 0) {
assert(op->ob_refcnt > 0);
@@ -120,6 +245,7 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
#ifdef Py_TRACE_REFS
_Py_ForgetReference(op);
#endif
+ _PyReftracerTrack(op, PyRefTracer_DESTROY);
destruct(op);
}
}
@@ -132,7 +258,7 @@ _Py_DECREF_NO_DEALLOC(PyObject *op)
}
_Py_DECREF_STAT_INC();
#ifdef Py_REF_DEBUG
- _Py_DEC_REFTOTAL(_PyInterpreterState_GET());
+ _Py_DEC_REFTOTAL(PyInterpreterState_Get());
#endif
op->ob_refcnt--;
#ifdef Py_DEBUG
@@ -142,29 +268,62 @@ _Py_DECREF_NO_DEALLOC(PyObject *op)
#endif
}
+#else
+// TODO: implement Py_DECREF specializations for Py_GIL_DISABLED build
+static inline void
+_Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
+{
+ Py_DECREF(op);
+}
+
+static inline void
+_Py_DECREF_NO_DEALLOC(PyObject *op)
+{
+ Py_DECREF(op);
+}
+
+static inline int
+_Py_REF_IS_MERGED(Py_ssize_t ob_ref_shared)
+{
+ return (ob_ref_shared & _Py_REF_SHARED_FLAG_MASK) == _Py_REF_MERGED;
+}
+
+static inline int
+_Py_REF_IS_QUEUED(Py_ssize_t ob_ref_shared)
+{
+ return (ob_ref_shared & _Py_REF_SHARED_FLAG_MASK) == _Py_REF_QUEUED;
+}
+
+// Merge the local and shared reference count fields and add `extra` to the
+// refcount when merging.
+Py_ssize_t _Py_ExplicitMergeRefcount(PyObject *op, Py_ssize_t extra);
+#endif // !defined(Py_GIL_DISABLED)
+
#ifdef Py_REF_DEBUG
# undef _Py_DEC_REFTOTAL
#endif
-PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
-PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
+extern int _PyType_CheckConsistency(PyTypeObject *type);
+extern int _PyDict_CheckConsistency(PyObject *mp, int check_content);
/* Update the Python traceback of an object. This function must be called
when a memory block is reused from a free list.
Internal function called by _Py_NewReference(). */
-extern int _PyTraceMalloc_NewReference(PyObject *op);
+extern int _PyTraceMalloc_TraceRef(PyObject *op, PyRefTracerEvent event, void*);
// Fast inlined version of PyType_HasFeature()
static inline int
_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
- return ((type->tp_flags & feature) != 0);
+ return ((FT_ATOMIC_LOAD_ULONG_RELAXED(type->tp_flags) & feature) != 0);
}
extern void _PyType_InitCache(PyInterpreterState *interp);
-extern void _PyObject_InitState(PyInterpreterState *interp);
+extern PyStatus _PyObject_InitState(PyInterpreterState *interp);
+extern void _PyObject_FiniState(PyInterpreterState *interp);
+extern bool _PyRefchain_IsTraced(PyInterpreterState *interp, PyObject *obj);
/* Inline functions trading binary compatibility for speed:
_PyObject_Init() is the fast version of PyObject_Init(), and
@@ -176,9 +335,8 @@ _PyObject_Init(PyObject *op, PyTypeObject *typeobj)
{
assert(op != NULL);
Py_SET_TYPE(op, typeobj);
- if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
- Py_INCREF(typeobj);
- }
+ assert(_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE) || _Py_IsImmortalLoose(typeobj));
+ Py_INCREF(typeobj);
_Py_NewReference(op);
}
@@ -215,7 +373,9 @@ static inline void _PyObject_GC_TRACK(
_PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op),
"object already tracked by the garbage collector",
filename, lineno, __func__);
-
+#ifdef Py_GIL_DISABLED
+ _PyObject_SET_GC_BITS(op, _PyGC_BITS_TRACKED);
+#else
PyGC_Head *gc = _Py_AS_GC(op);
_PyObject_ASSERT_FROM(op,
(gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0,
@@ -229,6 +389,7 @@ static inline void _PyObject_GC_TRACK(
_PyGCHead_SET_PREV(gc, last);
_PyGCHead_SET_NEXT(gc, generation0);
generation0->_gc_prev = (uintptr_t)gc;
+#endif
}
/* Tell the GC to stop tracking this object.
@@ -252,6 +413,9 @@ static inline void _PyObject_GC_UNTRACK(
"object not tracked by the garbage collector",
filename, lineno, __func__);
+#ifdef Py_GIL_DISABLED
+ _PyObject_CLEAR_GC_BITS(op, _PyGC_BITS_TRACKED);
+#else
PyGC_Head *gc = _Py_AS_GC(op);
PyGC_Head *prev = _PyGCHead_PREV(gc);
PyGC_Head *next = _PyGCHead_NEXT(gc);
@@ -259,6 +423,7 @@ static inline void _PyObject_GC_UNTRACK(
_PyGCHead_SET_PREV(next, prev);
gc->_gc_next = 0;
gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
+#endif
}
// Macros to accept any type for the parameter, and to automatically pass
@@ -276,6 +441,223 @@ static inline void _PyObject_GC_UNTRACK(
_PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op))
#endif
+#ifdef Py_GIL_DISABLED
+
+/* Tries to increment an object's reference count
+ *
+ * This is a specialized version of _Py_TryIncref that only succeeds if the
+ * object is immortal or local to this thread. It does not handle the case
+ * where the reference count modification requires an atomic operation. This
+ * allows call sites to specialize for the immortal/local case.
+ */
+static inline int
+_Py_TryIncrefFast(PyObject *op) {
+ uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local);
+ local += 1;
+ if (local == 0) {
+ // immortal
+ return 1;
+ }
+ if (_Py_IsOwnedByCurrentThread(op)) {
+ _Py_INCREF_STAT_INC();
+ _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, local);
+#ifdef Py_REF_DEBUG
+ _Py_IncRefTotal(_PyThreadState_GET());
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+static inline int
+_Py_TryIncRefShared(PyObject *op)
+{
+ Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&op->ob_ref_shared);
+ for (;;) {
+ // If the shared refcount is zero and the object is either merged
+ // or may not have weak references, then we cannot incref it.
+ if (shared == 0 || shared == _Py_REF_MERGED) {
+ return 0;
+ }
+
+ if (_Py_atomic_compare_exchange_ssize(
+ &op->ob_ref_shared,
+ &shared,
+ shared + (1 << _Py_REF_SHARED_SHIFT))) {
+#ifdef Py_REF_DEBUG
+ _Py_IncRefTotal(_PyThreadState_GET());
+#endif
+ _Py_INCREF_STAT_INC();
+ return 1;
+ }
+ }
+}
+
+/* Tries to incref the object op and ensures that *src still points to it. */
+static inline int
+_Py_TryIncrefCompare(PyObject **src, PyObject *op)
+{
+ if (_Py_TryIncrefFast(op)) {
+ return 1;
+ }
+ if (!_Py_TryIncRefShared(op)) {
+ return 0;
+ }
+ if (op != _Py_atomic_load_ptr(src)) {
+ Py_DECREF(op);
+ return 0;
+ }
+ return 1;
+}
+
+/* Loads and increfs an object from ptr, which may contain a NULL value.
+ Safe with concurrent (atomic) updates to ptr.
+ NOTE: The writer must set maybe-weakref on the stored object! */
+static inline PyObject *
+_Py_XGetRef(PyObject **ptr)
+{
+ for (;;) {
+ PyObject *value = _Py_atomic_load_ptr(ptr);
+ if (value == NULL) {
+ return value;
+ }
+ if (_Py_TryIncrefCompare(ptr, value)) {
+ return value;
+ }
+ }
+}
+
+/* Attempts to loads and increfs an object from ptr. Returns NULL
+ on failure, which may be due to a NULL value or a concurrent update. */
+static inline PyObject *
+_Py_TryXGetRef(PyObject **ptr)
+{
+ PyObject *value = _Py_atomic_load_ptr(ptr);
+ if (value == NULL) {
+ return value;
+ }
+ if (_Py_TryIncrefCompare(ptr, value)) {
+ return value;
+ }
+ return NULL;
+}
+
+/* Like Py_NewRef but also optimistically sets _Py_REF_MAYBE_WEAKREF
+ on objects owned by a different thread. */
+static inline PyObject *
+_Py_NewRefWithLock(PyObject *op)
+{
+ if (_Py_TryIncrefFast(op)) {
+ return op;
+ }
+#ifdef Py_REF_DEBUG
+ _Py_IncRefTotal(_PyThreadState_GET());
+#endif
+ _Py_INCREF_STAT_INC();
+ for (;;) {
+ Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&op->ob_ref_shared);
+ Py_ssize_t new_shared = shared + (1 << _Py_REF_SHARED_SHIFT);
+ if ((shared & _Py_REF_SHARED_FLAG_MASK) == 0) {
+ new_shared |= _Py_REF_MAYBE_WEAKREF;
+ }
+ if (_Py_atomic_compare_exchange_ssize(
+ &op->ob_ref_shared,
+ &shared,
+ new_shared)) {
+ return op;
+ }
+ }
+}
+
+static inline PyObject *
+_Py_XNewRefWithLock(PyObject *obj)
+{
+ if (obj == NULL) {
+ return NULL;
+ }
+ return _Py_NewRefWithLock(obj);
+}
+
+static inline void
+_PyObject_SetMaybeWeakref(PyObject *op)
+{
+ if (_Py_IsImmortal(op)) {
+ return;
+ }
+ for (;;) {
+ Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&op->ob_ref_shared);
+ if ((shared & _Py_REF_SHARED_FLAG_MASK) != 0) {
+ // Nothing to do if it's in WEAKREFS, QUEUED, or MERGED states.
+ return;
+ }
+ if (_Py_atomic_compare_exchange_ssize(
+ &op->ob_ref_shared, &shared, shared | _Py_REF_MAYBE_WEAKREF)) {
+ return;
+ }
+ }
+}
+
+extern int _PyObject_ResurrectEndSlow(PyObject *op);
+#endif
+
+// Temporarily resurrects an object during deallocation. The refcount is set
+// to one.
+static inline void
+_PyObject_ResurrectStart(PyObject *op)
+{
+ assert(Py_REFCNT(op) == 0);
+#ifdef Py_REF_DEBUG
+ _Py_IncRefTotal(_PyThreadState_GET());
+#endif
+#ifdef Py_GIL_DISABLED
+ _Py_atomic_store_uintptr_relaxed(&op->ob_tid, _Py_ThreadId());
+ _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, 1);
+ _Py_atomic_store_ssize_relaxed(&op->ob_ref_shared, 0);
+#else
+ Py_SET_REFCNT(op, 1);
+#endif
+}
+
+// Undoes an object resurrection by decrementing the refcount without calling
+// _Py_Dealloc(). Returns 0 if the object is dead (the normal case), and
+// deallocation should continue. Returns 1 if the object is still alive.
+static inline int
+_PyObject_ResurrectEnd(PyObject *op)
+{
+#ifdef Py_REF_DEBUG
+ _Py_DecRefTotal(_PyThreadState_GET());
+#endif
+#ifndef Py_GIL_DISABLED
+ Py_SET_REFCNT(op, Py_REFCNT(op) - 1);
+ return Py_REFCNT(op) != 0;
+#else
+ uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local);
+ Py_ssize_t shared = _Py_atomic_load_ssize_acquire(&op->ob_ref_shared);
+ if (_Py_IsOwnedByCurrentThread(op) && local == 1 && shared == 0) {
+ // Fast-path: object has a single refcount and is owned by this thread
+ _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, 0);
+ return 0;
+ }
+ // Slow-path: object has a shared refcount or is not owned by this thread
+ return _PyObject_ResurrectEndSlow(op);
+#endif
+}
+
+/* Tries to incref op and returns 1 if successful or 0 otherwise. */
+static inline int
+_Py_TryIncref(PyObject *op)
+{
+#ifdef Py_GIL_DISABLED
+ return _Py_TryIncrefFast(op) || _Py_TryIncRefShared(op);
+#else
+ if (Py_REFCNT(op) > 0) {
+ Py_INCREF(op);
+ return 1;
+ }
+ return 0;
+#endif
+}
+
#ifdef Py_REF_DEBUG
extern void _PyInterpreterState_FinalizeRefTotal(PyInterpreterState *);
extern void _Py_FinalizeRefTotal(_PyRuntimeState *);
@@ -283,7 +665,7 @@ extern void _PyDebug_PrintTotalRefs(void);
#endif
#ifdef Py_TRACE_REFS
-extern void _Py_AddToAllObjects(PyObject *op, int force);
+extern void _Py_AddToAllObjects(PyObject *op);
extern void _Py_PrintReferences(PyInterpreterState *, FILE *);
extern void _Py_PrintReferenceAddresses(PyInterpreterState *, FILE *);
#endif
@@ -304,7 +686,7 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
if (PyType_Check(op) &&
((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
- static_builtin_state *state = _PyStaticType_GetState(
+ managed_static_type_state *state = _PyStaticType_GetState(
interp, (PyTypeObject *)op);
return _PyStaticType_GET_WEAKREFS_LISTPTR(state);
}
@@ -334,14 +716,27 @@ _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op)
return (PyWeakReference **)((char *)op + offset);
}
-
// Fast inlined version of PyObject_IS_GC()
static inline int
_PyObject_IS_GC(PyObject *obj)
{
- return (PyType_IS_GC(Py_TYPE(obj))
- && (Py_TYPE(obj)->tp_is_gc == NULL
- || Py_TYPE(obj)->tp_is_gc(obj)));
+ PyTypeObject *type = Py_TYPE(obj);
+ return (PyType_IS_GC(type)
+ && (type->tp_is_gc == NULL || type->tp_is_gc(obj)));
+}
+
+// Fast inlined version of PyObject_Hash()
+static inline Py_hash_t
+_PyObject_HashFast(PyObject *op)
+{
+ if (PyUnicode_CheckExact(op)) {
+ Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(
+ _PyASCIIObject_CAST(op)->hash);
+ if (hash != -1) {
+ return hash;
+ }
+ }
+ return PyObject_Hash(op);
}
// Fast inlined version of PyType_IS_GC()
@@ -350,8 +745,12 @@ _PyObject_IS_GC(PyObject *obj)
static inline size_t
_PyType_PreHeaderSize(PyTypeObject *tp)
{
- return _PyType_IS_GC(tp) * sizeof(PyGC_Head) +
- _PyType_HasFeature(tp, Py_TPFLAGS_PREHEADER) * 2 * sizeof(PyObject *);
+ return (
+#ifndef Py_GIL_DISABLED
+ _PyType_IS_GC(tp) * sizeof(PyGC_Head) +
+#endif
+ _PyType_HasFeature(tp, Py_TPFLAGS_PREHEADER) * 2 * sizeof(PyObject *)
+ );
}
void _PyObject_GC_Link(PyObject *op);
@@ -368,59 +767,68 @@ static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
}
extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
+extern PyObject *_PyType_NewManagedObject(PyTypeObject *type);
+
+extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
+extern PyObject* _PyType_GetDocFromInternalDoc(const char *, const char *);
+extern PyObject* _PyType_GetTextSignatureFromInternalDoc(const char *, const char *, int);
+extern int _PyObject_SetAttributeErrorContext(PyObject *v, PyObject* name);
-extern int _PyObject_InitializeDict(PyObject *obj);
-extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
- PyObject *name, PyObject *value);
-PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values,
- PyObject *name);
+void _PyObject_InitInlineValues(PyObject *obj, PyTypeObject *tp);
+extern int _PyObject_StoreInstanceAttribute(PyObject *obj,
+ PyObject *name, PyObject *value);
+extern bool _PyObject_TryGetInstanceAttribute(PyObject *obj, PyObject *name,
+ PyObject **attr);
+
+#ifdef Py_GIL_DISABLED
+# define MANAGED_DICT_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-1)
+# define MANAGED_WEAKREF_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-2)
+#else
+# define MANAGED_DICT_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-3)
+# define MANAGED_WEAKREF_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-4)
+#endif
typedef union {
- PyObject *dict;
- /* Use a char* to generate a warning if directly assigning a PyDictValues */
- char *values;
-} PyDictOrValues;
+ PyDictObject *dict;
+} PyManagedDictPointer;
-static inline PyDictOrValues *
-_PyObject_DictOrValuesPointer(PyObject *obj)
+static inline PyManagedDictPointer *
+_PyObject_ManagedDictPointer(PyObject *obj)
{
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- return ((PyDictOrValues *)obj)-3;
+ return (PyManagedDictPointer *)((char *)obj + MANAGED_DICT_OFFSET);
}
-static inline int
-_PyDictOrValues_IsValues(PyDictOrValues dorv)
+static inline PyDictObject *
+_PyObject_GetManagedDict(PyObject *obj)
{
- return ((uintptr_t)dorv.values) & 1;
+ PyManagedDictPointer *dorv = _PyObject_ManagedDictPointer(obj);
+ return (PyDictObject *)FT_ATOMIC_LOAD_PTR_ACQUIRE(dorv->dict);
}
static inline PyDictValues *
-_PyDictOrValues_GetValues(PyDictOrValues dorv)
+_PyObject_InlineValues(PyObject *obj)
{
- assert(_PyDictOrValues_IsValues(dorv));
- return (PyDictValues *)(dorv.values + 1);
+ assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_INLINE_VALUES);
+ assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
+ assert(Py_TYPE(obj)->tp_basicsize == sizeof(PyObject));
+ return (PyDictValues *)((char *)obj + sizeof(PyObject));
}
-static inline PyObject *
-_PyDictOrValues_GetDict(PyDictOrValues dorv)
-{
- assert(!_PyDictOrValues_IsValues(dorv));
- return dorv.dict;
-}
+extern PyObject ** _PyObject_ComputedDictPointer(PyObject *);
+extern int _PyObject_IsInstanceDictEmpty(PyObject *);
-static inline void
-_PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values)
-{
- ptr->values = ((char *)values) - 1;
-}
+// Export for 'math' shared extension
+PyAPI_FUNC(PyObject*) _PyObject_LookupSpecial(PyObject *, PyObject *);
-#define MANAGED_WEAKREF_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-4)
+extern int _PyObject_IsAbstract(PyObject *);
-extern PyObject ** _PyObject_ComputedDictPointer(PyObject *);
-extern void _PyObject_FreeInstanceAttributes(PyObject *obj);
-extern int _PyObject_IsInstanceDictEmpty(PyObject *);
+PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);
+extern PyObject* _PyObject_NextNotImplemented(PyObject *);
-PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *);
+// Pickle support.
+// Export for '_datetime' shared extension
+PyAPI_FUNC(PyObject*) _PyObject_GetState(PyObject *);
/* C function call trampolines to mitigate bad function pointer casts.
*
@@ -436,19 +844,23 @@ PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *);
* Third party code unintentionally rely on problematic fpcasts. The call
* trampoline mitigates common occurrences of bad fpcasts on Emscripten.
*/
-#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
-#define _PyCFunction_TrampolineCall(meth, self, args) \
- _PyCFunctionWithKeywords_TrampolineCall( \
- (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL)
-extern PyObject* _PyCFunctionWithKeywords_TrampolineCall(
- PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *);
-#else
+#if !(defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE))
#define _PyCFunction_TrampolineCall(meth, self, args) \
(meth)((self), (args))
#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \
(meth)((self), (args), (kw))
#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE
+// Export these 2 symbols for '_pickle' shared extension
+PyAPI_DATA(PyTypeObject) _PyNone_Type;
+PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type;
+
+// Maps Py_LT to Py_GT, ..., Py_GE to Py_LE.
+// Export for the stable ABI.
+PyAPI_DATA(int) _Py_SwappedOp[];
+
+extern void _Py_GetConstant_Init(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_object_alloc.h b/contrib/tools/python3/Include/internal/pycore_object_alloc.h
new file mode 100644
index 00000000000..8cc7a444bc9
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_object_alloc.h
@@ -0,0 +1,71 @@
+#ifndef Py_INTERNAL_OBJECT_ALLOC_H
+#define Py_INTERNAL_OBJECT_ALLOC_H
+
+#include "pycore_object.h" // _PyType_HasFeature()
+#include "pycore_pystate.h" // _PyThreadState_GET()
+#include "pycore_tstate.h" // _PyThreadStateImpl
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#ifdef Py_GIL_DISABLED
+static inline mi_heap_t *
+_PyObject_GetAllocationHeap(_PyThreadStateImpl *tstate, PyTypeObject *tp)
+{
+ struct _mimalloc_thread_state *m = &tstate->mimalloc;
+ if (_PyType_HasFeature(tp, Py_TPFLAGS_PREHEADER)) {
+ return &m->heaps[_Py_MIMALLOC_HEAP_GC_PRE];
+ }
+ else if (_PyType_IS_GC(tp)) {
+ return &m->heaps[_Py_MIMALLOC_HEAP_GC];
+ }
+ else {
+ return &m->heaps[_Py_MIMALLOC_HEAP_OBJECT];
+ }
+}
+#endif
+
+// Sets the heap used for PyObject_Malloc(), PyObject_Realloc(), etc. calls in
+// Py_GIL_DISABLED builds. We use different heaps depending on if the object
+// supports GC and if it has a pre-header. We smuggle the choice of heap
+// through the _mimalloc_thread_state. In the default build, this simply
+// calls PyObject_Malloc().
+static inline void *
+_PyObject_MallocWithType(PyTypeObject *tp, size_t size)
+{
+#ifdef Py_GIL_DISABLED
+ _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
+ struct _mimalloc_thread_state *m = &tstate->mimalloc;
+ m->current_object_heap = _PyObject_GetAllocationHeap(tstate, tp);
+#endif
+ void *mem = PyObject_Malloc(size);
+#ifdef Py_GIL_DISABLED
+ m->current_object_heap = &m->heaps[_Py_MIMALLOC_HEAP_OBJECT];
+#endif
+ return mem;
+}
+
+static inline void *
+_PyObject_ReallocWithType(PyTypeObject *tp, void *ptr, size_t size)
+{
+#ifdef Py_GIL_DISABLED
+ _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
+ struct _mimalloc_thread_state *m = &tstate->mimalloc;
+ m->current_object_heap = _PyObject_GetAllocationHeap(tstate, tp);
+#endif
+ void *mem = PyObject_Realloc(ptr, size);
+#ifdef Py_GIL_DISABLED
+ m->current_object_heap = &m->heaps[_Py_MIMALLOC_HEAP_OBJECT];
+#endif
+ return mem;
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_OBJECT_ALLOC_H
diff --git a/contrib/tools/python3/Include/internal/pycore_object_stack.h b/contrib/tools/python3/Include/internal/pycore_object_stack.h
new file mode 100644
index 00000000000..639f3c0c0d0
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_object_stack.h
@@ -0,0 +1,97 @@
+#ifndef Py_INTERNAL_OBJECT_STACK_H
+#define Py_INTERNAL_OBJECT_STACK_H
+
+#include "pycore_freelist.h" // _PyFreeListState
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+// _PyObjectStack is a stack of Python objects implemented as a linked list of
+// fixed size buffers.
+
+// Chosen so that _PyObjectStackChunk is a power-of-two size.
+#define _Py_OBJECT_STACK_CHUNK_SIZE 254
+
+typedef struct _PyObjectStackChunk {
+ struct _PyObjectStackChunk *prev;
+ Py_ssize_t n;
+ PyObject *objs[_Py_OBJECT_STACK_CHUNK_SIZE];
+} _PyObjectStackChunk;
+
+typedef struct _PyObjectStack {
+ _PyObjectStackChunk *head;
+} _PyObjectStack;
+
+
+extern _PyObjectStackChunk *
+_PyObjectStackChunk_New(void);
+
+extern void
+_PyObjectStackChunk_Free(_PyObjectStackChunk *);
+
+// Push an item onto the stack. Return -1 on allocation failure, 0 on success.
+static inline int
+_PyObjectStack_Push(_PyObjectStack *stack, PyObject *obj)
+{
+ _PyObjectStackChunk *buf = stack->head;
+ if (buf == NULL || buf->n == _Py_OBJECT_STACK_CHUNK_SIZE) {
+ buf = _PyObjectStackChunk_New();
+ if (buf == NULL) {
+ return -1;
+ }
+ buf->prev = stack->head;
+ buf->n = 0;
+ stack->head = buf;
+ }
+
+ assert(buf->n >= 0 && buf->n < _Py_OBJECT_STACK_CHUNK_SIZE);
+ buf->objs[buf->n] = obj;
+ buf->n++;
+ return 0;
+}
+
+// Pop the top item from the stack. Return NULL if the stack is empty.
+static inline PyObject *
+_PyObjectStack_Pop(_PyObjectStack *stack)
+{
+ _PyObjectStackChunk *buf = stack->head;
+ if (buf == NULL) {
+ return NULL;
+ }
+ assert(buf->n > 0 && buf->n <= _Py_OBJECT_STACK_CHUNK_SIZE);
+ buf->n--;
+ PyObject *obj = buf->objs[buf->n];
+ if (buf->n == 0) {
+ stack->head = buf->prev;
+ _PyObjectStackChunk_Free(buf);
+ }
+ return obj;
+}
+
+static inline Py_ssize_t
+_PyObjectStack_Size(_PyObjectStack *stack)
+{
+ Py_ssize_t size = 0;
+ for (_PyObjectStackChunk *buf = stack->head; buf != NULL; buf = buf->prev) {
+ size += buf->n;
+ }
+ return size;
+}
+
+// Merge src into dst, leaving src empty
+extern void
+_PyObjectStack_Merge(_PyObjectStack *dst, _PyObjectStack *src);
+
+// Remove all items from the stack
+extern void
+_PyObjectStack_Clear(_PyObjectStack *stack);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_OBJECT_STACK_H
diff --git a/contrib/tools/python3/Include/internal/pycore_object_state.h b/contrib/tools/python3/Include/internal/pycore_object_state.h
index 6e07b1a01b0..cd7c9335b3e 100644
--- a/contrib/tools/python3/Include/internal/pycore_object_state.h
+++ b/contrib/tools/python3/Include/internal/pycore_object_state.h
@@ -8,6 +8,9 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_freelist.h" // _PyObject_freelists
+#include "pycore_hashtable.h" // _Py_hashtable_t
+
struct _py_object_runtime_state {
#ifdef Py_REF_DEBUG
Py_ssize_t interpreter_leaks;
@@ -16,21 +19,17 @@ struct _py_object_runtime_state {
};
struct _py_object_state {
+#if !defined(Py_GIL_DISABLED)
+ struct _Py_object_freelists freelists;
+#endif
#ifdef Py_REF_DEBUG
Py_ssize_t reftotal;
#endif
#ifdef Py_TRACE_REFS
- /* Head of circular doubly-linked list of all objects. These are linked
- * together via the _ob_prev and _ob_next members of a PyObject, which
- * exist only in a Py_TRACE_REFS build.
- */
- PyObject *refchain;
- /* In most cases, refchain points to _refchain_obj.
- * In sub-interpreters that share objmalloc state with the main interp,
- * refchain points to the main interpreter's _refchain_obj, and their own
- * _refchain_obj is unused.
- */
- PyObject _refchain_obj;
+ // Hash table storing all objects. The key is the object pointer
+ // (PyObject*) and the value is always the number 1 (as uintptr_t).
+ // See _PyRefchain_IsTraced() and _PyRefchain_Trace() functions.
+ _Py_hashtable_t *refchain;
#endif
int _not_used;
};
diff --git a/contrib/tools/python3/Include/internal/pycore_obmalloc.h b/contrib/tools/python3/Include/internal/pycore_obmalloc.h
index b1c00654ac1..9140d8f08f0 100644
--- a/contrib/tools/python3/Include/internal/pycore_obmalloc.h
+++ b/contrib/tools/python3/Include/internal/pycore_obmalloc.h
@@ -686,10 +686,12 @@ extern Py_ssize_t _Py_GetGlobalAllocatedBlocks(void);
_Py_GetGlobalAllocatedBlocks()
extern Py_ssize_t _PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *);
extern void _PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *);
+extern int _PyMem_init_obmalloc(PyInterpreterState *interp);
+extern bool _PyMem_obmalloc_state_on_heap(PyInterpreterState *interp);
#ifdef WITH_PYMALLOC
-// Export the symbol for the 3rd party guppy3 project
+// Export the symbol for the 3rd party 'guppy3' project
PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out);
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_obmalloc_init.h b/contrib/tools/python3/Include/internal/pycore_obmalloc_init.h
index 8ee72ff2d41..e6811b7aeca 100644
--- a/contrib/tools/python3/Include/internal/pycore_obmalloc_init.h
+++ b/contrib/tools/python3/Include/internal/pycore_obmalloc_init.h
@@ -59,13 +59,6 @@ extern "C" {
.dump_debug_stats = -1, \
}
-#define _obmalloc_state_INIT(obmalloc) \
- { \
- .pools = { \
- .used = _obmalloc_pools_INIT(obmalloc.pools), \
- }, \
- }
-
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_opcode.h b/contrib/tools/python3/Include/internal/pycore_opcode.h
deleted file mode 100644
index 15d96503830..00000000000
--- a/contrib/tools/python3/Include/internal/pycore_opcode.h
+++ /dev/null
@@ -1,587 +0,0 @@
-// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py
-
-#ifndef Py_INTERNAL_OPCODE_H
-#define Py_INTERNAL_OPCODE_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef Py_BUILD_CORE
-# error "this header requires Py_BUILD_CORE define"
-#endif
-
-#include "opcode.h"
-
-extern const uint32_t _PyOpcode_Jump[9];
-
-extern const uint8_t _PyOpcode_Caches[256];
-
-extern const uint8_t _PyOpcode_Deopt[256];
-
-#ifdef NEED_OPCODE_TABLES
-const uint32_t _PyOpcode_Jump[9] = {
- 0U,
- 0U,
- 536870912U,
- 135020544U,
- 4163U,
- 0U,
- 0U,
- 0U,
- 48U,
-};
-
-const uint8_t _PyOpcode_Caches[256] = {
- [BINARY_SUBSCR] = 1,
- [STORE_SUBSCR] = 1,
- [UNPACK_SEQUENCE] = 1,
- [FOR_ITER] = 1,
- [STORE_ATTR] = 4,
- [LOAD_ATTR] = 9,
- [COMPARE_OP] = 1,
- [LOAD_GLOBAL] = 4,
- [BINARY_OP] = 1,
- [SEND] = 1,
- [LOAD_SUPER_ATTR] = 1,
- [CALL] = 3,
-};
-
-const uint8_t _PyOpcode_Deopt[256] = {
- [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH,
- [BEFORE_WITH] = BEFORE_WITH,
- [BINARY_OP] = BINARY_OP,
- [BINARY_OP_ADD_FLOAT] = BINARY_OP,
- [BINARY_OP_ADD_INT] = BINARY_OP,
- [BINARY_OP_ADD_UNICODE] = BINARY_OP,
- [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP,
- [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP,
- [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
- [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
- [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
- [BINARY_SLICE] = BINARY_SLICE,
- [BINARY_SUBSCR] = BINARY_SUBSCR,
- [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
- [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
- [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
- [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
- [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
- [BUILD_LIST] = BUILD_LIST,
- [BUILD_MAP] = BUILD_MAP,
- [BUILD_SET] = BUILD_SET,
- [BUILD_SLICE] = BUILD_SLICE,
- [BUILD_STRING] = BUILD_STRING,
- [BUILD_TUPLE] = BUILD_TUPLE,
- [CACHE] = CACHE,
- [CALL] = CALL,
- [CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
- [CALL_BUILTIN_CLASS] = CALL,
- [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
- [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
- [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
- [CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
- [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
- [CALL_NO_KW_BUILTIN_FAST] = CALL,
- [CALL_NO_KW_BUILTIN_O] = CALL,
- [CALL_NO_KW_ISINSTANCE] = CALL,
- [CALL_NO_KW_LEN] = CALL,
- [CALL_NO_KW_LIST_APPEND] = CALL,
- [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL,
- [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL,
- [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL,
- [CALL_NO_KW_STR_1] = CALL,
- [CALL_NO_KW_TUPLE_1] = CALL,
- [CALL_NO_KW_TYPE_1] = CALL,
- [CALL_PY_EXACT_ARGS] = CALL,
- [CALL_PY_WITH_DEFAULTS] = CALL,
- [CHECK_EG_MATCH] = CHECK_EG_MATCH,
- [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
- [CLEANUP_THROW] = CLEANUP_THROW,
- [COMPARE_OP] = COMPARE_OP,
- [COMPARE_OP_FLOAT] = COMPARE_OP,
- [COMPARE_OP_INT] = COMPARE_OP,
- [COMPARE_OP_STR] = COMPARE_OP,
- [CONTAINS_OP] = CONTAINS_OP,
- [COPY] = COPY,
- [COPY_FREE_VARS] = COPY_FREE_VARS,
- [DELETE_ATTR] = DELETE_ATTR,
- [DELETE_DEREF] = DELETE_DEREF,
- [DELETE_FAST] = DELETE_FAST,
- [DELETE_GLOBAL] = DELETE_GLOBAL,
- [DELETE_NAME] = DELETE_NAME,
- [DELETE_SUBSCR] = DELETE_SUBSCR,
- [DICT_MERGE] = DICT_MERGE,
- [DICT_UPDATE] = DICT_UPDATE,
- [END_ASYNC_FOR] = END_ASYNC_FOR,
- [END_FOR] = END_FOR,
- [END_SEND] = END_SEND,
- [EXTENDED_ARG] = EXTENDED_ARG,
- [FORMAT_VALUE] = FORMAT_VALUE,
- [FOR_ITER] = FOR_ITER,
- [FOR_ITER_GEN] = FOR_ITER,
- [FOR_ITER_LIST] = FOR_ITER,
- [FOR_ITER_RANGE] = FOR_ITER,
- [FOR_ITER_TUPLE] = FOR_ITER,
- [GET_AITER] = GET_AITER,
- [GET_ANEXT] = GET_ANEXT,
- [GET_AWAITABLE] = GET_AWAITABLE,
- [GET_ITER] = GET_ITER,
- [GET_LEN] = GET_LEN,
- [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
- [IMPORT_FROM] = IMPORT_FROM,
- [IMPORT_NAME] = IMPORT_NAME,
- [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
- [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
- [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
- [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
- [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
- [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
- [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
- [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
- [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
- [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
- [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
- [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
- [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
- [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
- [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME,
- [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
- [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
- [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
- [INTERPRETER_EXIT] = INTERPRETER_EXIT,
- [IS_OP] = IS_OP,
- [JUMP_BACKWARD] = JUMP_BACKWARD,
- [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
- [JUMP_FORWARD] = JUMP_FORWARD,
- [KW_NAMES] = KW_NAMES,
- [LIST_APPEND] = LIST_APPEND,
- [LIST_EXTEND] = LIST_EXTEND,
- [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
- [LOAD_ATTR] = LOAD_ATTR,
- [LOAD_ATTR_CLASS] = LOAD_ATTR,
- [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
- [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
- [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
- [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
- [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
- [LOAD_ATTR_MODULE] = LOAD_ATTR,
- [LOAD_ATTR_PROPERTY] = LOAD_ATTR,
- [LOAD_ATTR_SLOT] = LOAD_ATTR,
- [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
- [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
- [LOAD_CLOSURE] = LOAD_CLOSURE,
- [LOAD_CONST] = LOAD_CONST,
- [LOAD_CONST__LOAD_FAST] = LOAD_CONST,
- [LOAD_DEREF] = LOAD_DEREF,
- [LOAD_FAST] = LOAD_FAST,
- [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR,
- [LOAD_FAST_CHECK] = LOAD_FAST_CHECK,
- [LOAD_FAST__LOAD_CONST] = LOAD_FAST,
- [LOAD_FAST__LOAD_FAST] = LOAD_FAST,
- [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF,
- [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS,
- [LOAD_GLOBAL] = LOAD_GLOBAL,
- [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
- [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
- [LOAD_LOCALS] = LOAD_LOCALS,
- [LOAD_NAME] = LOAD_NAME,
- [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
- [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
- [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
- [MAKE_CELL] = MAKE_CELL,
- [MAKE_FUNCTION] = MAKE_FUNCTION,
- [MAP_ADD] = MAP_ADD,
- [MATCH_CLASS] = MATCH_CLASS,
- [MATCH_KEYS] = MATCH_KEYS,
- [MATCH_MAPPING] = MATCH_MAPPING,
- [MATCH_SEQUENCE] = MATCH_SEQUENCE,
- [NOP] = NOP,
- [POP_EXCEPT] = POP_EXCEPT,
- [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
- [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
- [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
- [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
- [POP_TOP] = POP_TOP,
- [PUSH_EXC_INFO] = PUSH_EXC_INFO,
- [PUSH_NULL] = PUSH_NULL,
- [RAISE_VARARGS] = RAISE_VARARGS,
- [RERAISE] = RERAISE,
- [RESERVED] = RESERVED,
- [RESUME] = RESUME,
- [RETURN_CONST] = RETURN_CONST,
- [RETURN_GENERATOR] = RETURN_GENERATOR,
- [RETURN_VALUE] = RETURN_VALUE,
- [SEND] = SEND,
- [SEND_GEN] = SEND,
- [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
- [SET_ADD] = SET_ADD,
- [SET_UPDATE] = SET_UPDATE,
- [STORE_ATTR] = STORE_ATTR,
- [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
- [STORE_ATTR_SLOT] = STORE_ATTR,
- [STORE_ATTR_WITH_HINT] = STORE_ATTR,
- [STORE_DEREF] = STORE_DEREF,
- [STORE_FAST] = STORE_FAST,
- [STORE_FAST__LOAD_FAST] = STORE_FAST,
- [STORE_FAST__STORE_FAST] = STORE_FAST,
- [STORE_GLOBAL] = STORE_GLOBAL,
- [STORE_NAME] = STORE_NAME,
- [STORE_SLICE] = STORE_SLICE,
- [STORE_SUBSCR] = STORE_SUBSCR,
- [STORE_SUBSCR_DICT] = STORE_SUBSCR,
- [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR,
- [SWAP] = SWAP,
- [UNARY_INVERT] = UNARY_INVERT,
- [UNARY_NEGATIVE] = UNARY_NEGATIVE,
- [UNARY_NOT] = UNARY_NOT,
- [UNPACK_EX] = UNPACK_EX,
- [UNPACK_SEQUENCE] = UNPACK_SEQUENCE,
- [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE,
- [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE,
- [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
- [WITH_EXCEPT_START] = WITH_EXCEPT_START,
- [YIELD_VALUE] = YIELD_VALUE,
-};
-#endif // NEED_OPCODE_TABLES
-
-#ifdef Py_DEBUG
-static const char *const _PyOpcode_OpName[267] = {
- [CACHE] = "CACHE",
- [POP_TOP] = "POP_TOP",
- [PUSH_NULL] = "PUSH_NULL",
- [INTERPRETER_EXIT] = "INTERPRETER_EXIT",
- [END_FOR] = "END_FOR",
- [END_SEND] = "END_SEND",
- [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT",
- [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT",
- [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE",
- [NOP] = "NOP",
- [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE",
- [UNARY_NEGATIVE] = "UNARY_NEGATIVE",
- [UNARY_NOT] = "UNARY_NOT",
- [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT",
- [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT",
- [UNARY_INVERT] = "UNARY_INVERT",
- [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT",
- [RESERVED] = "RESERVED",
- [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT",
- [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT",
- [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM",
- [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT",
- [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT",
- [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
- [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS",
- [BINARY_SUBSCR] = "BINARY_SUBSCR",
- [BINARY_SLICE] = "BINARY_SLICE",
- [STORE_SLICE] = "STORE_SLICE",
- [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
- [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
- [GET_LEN] = "GET_LEN",
- [MATCH_MAPPING] = "MATCH_MAPPING",
- [MATCH_SEQUENCE] = "MATCH_SEQUENCE",
- [MATCH_KEYS] = "MATCH_KEYS",
- [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
- [PUSH_EXC_INFO] = "PUSH_EXC_INFO",
- [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH",
- [CHECK_EG_MATCH] = "CHECK_EG_MATCH",
- [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
- [CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST",
- [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O",
- [CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE",
- [CALL_NO_KW_LEN] = "CALL_NO_KW_LEN",
- [CALL_NO_KW_LIST_APPEND] = "CALL_NO_KW_LIST_APPEND",
- [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "CALL_NO_KW_METHOD_DESCRIPTOR_FAST",
- [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
- [CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O",
- [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1",
- [CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1",
- [WITH_EXCEPT_START] = "WITH_EXCEPT_START",
- [GET_AITER] = "GET_AITER",
- [GET_ANEXT] = "GET_ANEXT",
- [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH",
- [BEFORE_WITH] = "BEFORE_WITH",
- [END_ASYNC_FOR] = "END_ASYNC_FOR",
- [CLEANUP_THROW] = "CLEANUP_THROW",
- [CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1",
- [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT",
- [COMPARE_OP_INT] = "COMPARE_OP_INT",
- [COMPARE_OP_STR] = "COMPARE_OP_STR",
- [STORE_SUBSCR] = "STORE_SUBSCR",
- [DELETE_SUBSCR] = "DELETE_SUBSCR",
- [FOR_ITER_LIST] = "FOR_ITER_LIST",
- [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE",
- [FOR_ITER_RANGE] = "FOR_ITER_RANGE",
- [FOR_ITER_GEN] = "FOR_ITER_GEN",
- [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR",
- [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
- [GET_ITER] = "GET_ITER",
- [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER",
- [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
- [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS",
- [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
- [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
- [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR",
- [RETURN_GENERATOR] = "RETURN_GENERATOR",
- [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
- [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY",
- [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT",
- [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT",
- [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
- [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
- [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
- [RETURN_VALUE] = "RETURN_VALUE",
- [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST",
- [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
- [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST",
- [LOAD_LOCALS] = "LOAD_LOCALS",
- [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST",
- [POP_EXCEPT] = "POP_EXCEPT",
- [STORE_NAME] = "STORE_NAME",
- [DELETE_NAME] = "DELETE_NAME",
- [UNPACK_SEQUENCE] = "UNPACK_SEQUENCE",
- [FOR_ITER] = "FOR_ITER",
- [UNPACK_EX] = "UNPACK_EX",
- [STORE_ATTR] = "STORE_ATTR",
- [DELETE_ATTR] = "DELETE_ATTR",
- [STORE_GLOBAL] = "STORE_GLOBAL",
- [DELETE_GLOBAL] = "DELETE_GLOBAL",
- [SWAP] = "SWAP",
- [LOAD_CONST] = "LOAD_CONST",
- [LOAD_NAME] = "LOAD_NAME",
- [BUILD_TUPLE] = "BUILD_TUPLE",
- [BUILD_LIST] = "BUILD_LIST",
- [BUILD_SET] = "BUILD_SET",
- [BUILD_MAP] = "BUILD_MAP",
- [LOAD_ATTR] = "LOAD_ATTR",
- [COMPARE_OP] = "COMPARE_OP",
- [IMPORT_NAME] = "IMPORT_NAME",
- [IMPORT_FROM] = "IMPORT_FROM",
- [JUMP_FORWARD] = "JUMP_FORWARD",
- [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
- [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
- [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
- [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
- [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
- [LOAD_GLOBAL] = "LOAD_GLOBAL",
- [IS_OP] = "IS_OP",
- [CONTAINS_OP] = "CONTAINS_OP",
- [RERAISE] = "RERAISE",
- [COPY] = "COPY",
- [RETURN_CONST] = "RETURN_CONST",
- [BINARY_OP] = "BINARY_OP",
- [SEND] = "SEND",
- [LOAD_FAST] = "LOAD_FAST",
- [STORE_FAST] = "STORE_FAST",
- [DELETE_FAST] = "DELETE_FAST",
- [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK",
- [POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE",
- [POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE",
- [RAISE_VARARGS] = "RAISE_VARARGS",
- [GET_AWAITABLE] = "GET_AWAITABLE",
- [MAKE_FUNCTION] = "MAKE_FUNCTION",
- [BUILD_SLICE] = "BUILD_SLICE",
- [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT",
- [MAKE_CELL] = "MAKE_CELL",
- [LOAD_CLOSURE] = "LOAD_CLOSURE",
- [LOAD_DEREF] = "LOAD_DEREF",
- [STORE_DEREF] = "STORE_DEREF",
- [DELETE_DEREF] = "DELETE_DEREF",
- [JUMP_BACKWARD] = "JUMP_BACKWARD",
- [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR",
- [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
- [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR",
- [EXTENDED_ARG] = "EXTENDED_ARG",
- [LIST_APPEND] = "LIST_APPEND",
- [SET_ADD] = "SET_ADD",
- [MAP_ADD] = "MAP_ADD",
- [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
- [COPY_FREE_VARS] = "COPY_FREE_VARS",
- [YIELD_VALUE] = "YIELD_VALUE",
- [RESUME] = "RESUME",
- [MATCH_CLASS] = "MATCH_CLASS",
- [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
- [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST",
- [FORMAT_VALUE] = "FORMAT_VALUE",
- [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
- [BUILD_STRING] = "BUILD_STRING",
- [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST",
- [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
- [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
- [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
- [LIST_EXTEND] = "LIST_EXTEND",
- [SET_UPDATE] = "SET_UPDATE",
- [DICT_MERGE] = "DICT_MERGE",
- [DICT_UPDATE] = "DICT_UPDATE",
- [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
- [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
- [SEND_GEN] = "SEND_GEN",
- [169] = "<169>",
- [170] = "<170>",
- [CALL] = "CALL",
- [KW_NAMES] = "KW_NAMES",
- [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1",
- [CALL_INTRINSIC_2] = "CALL_INTRINSIC_2",
- [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS",
- [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF",
- [177] = "<177>",
- [178] = "<178>",
- [179] = "<179>",
- [180] = "<180>",
- [181] = "<181>",
- [182] = "<182>",
- [183] = "<183>",
- [184] = "<184>",
- [185] = "<185>",
- [186] = "<186>",
- [187] = "<187>",
- [188] = "<188>",
- [189] = "<189>",
- [190] = "<190>",
- [191] = "<191>",
- [192] = "<192>",
- [193] = "<193>",
- [194] = "<194>",
- [195] = "<195>",
- [196] = "<196>",
- [197] = "<197>",
- [198] = "<198>",
- [199] = "<199>",
- [200] = "<200>",
- [201] = "<201>",
- [202] = "<202>",
- [203] = "<203>",
- [204] = "<204>",
- [205] = "<205>",
- [206] = "<206>",
- [207] = "<207>",
- [208] = "<208>",
- [209] = "<209>",
- [210] = "<210>",
- [211] = "<211>",
- [212] = "<212>",
- [213] = "<213>",
- [214] = "<214>",
- [215] = "<215>",
- [216] = "<216>",
- [217] = "<217>",
- [218] = "<218>",
- [219] = "<219>",
- [220] = "<220>",
- [221] = "<221>",
- [222] = "<222>",
- [223] = "<223>",
- [224] = "<224>",
- [225] = "<225>",
- [226] = "<226>",
- [227] = "<227>",
- [228] = "<228>",
- [229] = "<229>",
- [230] = "<230>",
- [231] = "<231>",
- [232] = "<232>",
- [233] = "<233>",
- [234] = "<234>",
- [235] = "<235>",
- [236] = "<236>",
- [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
- [INSTRUMENTED_POP_JUMP_IF_NONE] = "INSTRUMENTED_POP_JUMP_IF_NONE",
- [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE",
- [INSTRUMENTED_RESUME] = "INSTRUMENTED_RESUME",
- [INSTRUMENTED_CALL] = "INSTRUMENTED_CALL",
- [INSTRUMENTED_RETURN_VALUE] = "INSTRUMENTED_RETURN_VALUE",
- [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE",
- [INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX",
- [INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD",
- [INSTRUMENTED_JUMP_BACKWARD] = "INSTRUMENTED_JUMP_BACKWARD",
- [INSTRUMENTED_RETURN_CONST] = "INSTRUMENTED_RETURN_CONST",
- [INSTRUMENTED_FOR_ITER] = "INSTRUMENTED_FOR_ITER",
- [INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE",
- [INSTRUMENTED_POP_JUMP_IF_TRUE] = "INSTRUMENTED_POP_JUMP_IF_TRUE",
- [INSTRUMENTED_END_FOR] = "INSTRUMENTED_END_FOR",
- [INSTRUMENTED_END_SEND] = "INSTRUMENTED_END_SEND",
- [INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION",
- [INSTRUMENTED_LINE] = "INSTRUMENTED_LINE",
- [255] = "<255>",
- [SETUP_FINALLY] = "SETUP_FINALLY",
- [SETUP_CLEANUP] = "SETUP_CLEANUP",
- [SETUP_WITH] = "SETUP_WITH",
- [POP_BLOCK] = "POP_BLOCK",
- [JUMP] = "JUMP",
- [JUMP_NO_INTERRUPT] = "JUMP_NO_INTERRUPT",
- [LOAD_METHOD] = "LOAD_METHOD",
- [LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD",
- [LOAD_ZERO_SUPER_METHOD] = "LOAD_ZERO_SUPER_METHOD",
- [LOAD_ZERO_SUPER_ATTR] = "LOAD_ZERO_SUPER_ATTR",
- [STORE_FAST_MAYBE_NULL] = "STORE_FAST_MAYBE_NULL",
-};
-#endif
-
-#define EXTRA_CASES \
- case 169: \
- case 170: \
- case 177: \
- case 178: \
- case 179: \
- case 180: \
- case 181: \
- case 182: \
- case 183: \
- case 184: \
- case 185: \
- case 186: \
- case 187: \
- case 188: \
- case 189: \
- case 190: \
- case 191: \
- case 192: \
- case 193: \
- case 194: \
- case 195: \
- case 196: \
- case 197: \
- case 198: \
- case 199: \
- case 200: \
- case 201: \
- case 202: \
- case 203: \
- case 204: \
- case 205: \
- case 206: \
- case 207: \
- case 208: \
- case 209: \
- case 210: \
- case 211: \
- case 212: \
- case 213: \
- case 214: \
- case 215: \
- case 216: \
- case 217: \
- case 218: \
- case 219: \
- case 220: \
- case 221: \
- case 222: \
- case 223: \
- case 224: \
- case 225: \
- case 226: \
- case 227: \
- case 228: \
- case 229: \
- case 230: \
- case 231: \
- case 232: \
- case 233: \
- case 234: \
- case 235: \
- case 236: \
- case 255: \
- ;
-
-#ifdef __cplusplus
-}
-#endif
-#endif // !Py_INTERNAL_OPCODE_H
diff --git a/contrib/tools/python3/Include/internal/pycore_opcode_metadata.h b/contrib/tools/python3/Include/internal/pycore_opcode_metadata.h
new file mode 100644
index 00000000000..a3d31bcbc4a
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_opcode_metadata.h
@@ -0,0 +1,1922 @@
+// This file is generated by Tools/cases_generator/opcode_metadata_generator.py
+// from:
+// Python/bytecodes.c
+// Do not edit!
+
+#ifndef Py_CORE_OPCODE_METADATA_H
+#define Py_CORE_OPCODE_METADATA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include <stdbool.h> // bool
+#include "opcode_ids.h"
+
+
+#define IS_PSEUDO_INSTR(OP) ( \
+ ((OP) == LOAD_CLOSURE) || \
+ ((OP) == STORE_FAST_MAYBE_NULL) || \
+ ((OP) == LOAD_SUPER_METHOD) || \
+ ((OP) == LOAD_ZERO_SUPER_METHOD) || \
+ ((OP) == LOAD_ZERO_SUPER_ATTR) || \
+ ((OP) == LOAD_METHOD) || \
+ ((OP) == JUMP) || \
+ ((OP) == JUMP_NO_INTERRUPT) || \
+ ((OP) == SETUP_FINALLY) || \
+ ((OP) == SETUP_CLEANUP) || \
+ ((OP) == SETUP_WITH) || \
+ ((OP) == POP_BLOCK) || \
+ 0)
+
+#include "pycore_uop_ids.h"
+extern int _PyOpcode_num_popped(int opcode, int oparg);
+#ifdef NEED_OPCODE_METADATA
+int _PyOpcode_num_popped(int opcode, int oparg) {
+ switch(opcode) {
+ case BEFORE_ASYNC_WITH:
+ return 1;
+ case BEFORE_WITH:
+ return 1;
+ case BINARY_OP:
+ return 2;
+ case BINARY_OP_ADD_FLOAT:
+ return 2;
+ case BINARY_OP_ADD_INT:
+ return 2;
+ case BINARY_OP_ADD_UNICODE:
+ return 2;
+ case BINARY_OP_INPLACE_ADD_UNICODE:
+ return 2;
+ case BINARY_OP_MULTIPLY_FLOAT:
+ return 2;
+ case BINARY_OP_MULTIPLY_INT:
+ return 2;
+ case BINARY_OP_SUBTRACT_FLOAT:
+ return 2;
+ case BINARY_OP_SUBTRACT_INT:
+ return 2;
+ case BINARY_SLICE:
+ return 3;
+ case BINARY_SUBSCR:
+ return 2;
+ case BINARY_SUBSCR_DICT:
+ return 2;
+ case BINARY_SUBSCR_GETITEM:
+ return 2;
+ case BINARY_SUBSCR_LIST_INT:
+ return 2;
+ case BINARY_SUBSCR_STR_INT:
+ return 2;
+ case BINARY_SUBSCR_TUPLE_INT:
+ return 2;
+ case BUILD_CONST_KEY_MAP:
+ return 1 + oparg;
+ case BUILD_LIST:
+ return oparg;
+ case BUILD_MAP:
+ return oparg*2;
+ case BUILD_SET:
+ return oparg;
+ case BUILD_SLICE:
+ return 2 + ((oparg == 3) ? 1 : 0);
+ case BUILD_STRING:
+ return oparg;
+ case BUILD_TUPLE:
+ return oparg;
+ case CACHE:
+ return 0;
+ case CALL:
+ return 2 + oparg;
+ case CALL_ALLOC_AND_ENTER_INIT:
+ return 2 + oparg;
+ case CALL_BOUND_METHOD_EXACT_ARGS:
+ return 2 + oparg;
+ case CALL_BOUND_METHOD_GENERAL:
+ return 2 + oparg;
+ case CALL_BUILTIN_CLASS:
+ return 2 + oparg;
+ case CALL_BUILTIN_FAST:
+ return 2 + oparg;
+ case CALL_BUILTIN_FAST_WITH_KEYWORDS:
+ return 2 + oparg;
+ case CALL_BUILTIN_O:
+ return 2 + oparg;
+ case CALL_FUNCTION_EX:
+ return 3 + (oparg & 1);
+ case CALL_INTRINSIC_1:
+ return 1;
+ case CALL_INTRINSIC_2:
+ return 2;
+ case CALL_ISINSTANCE:
+ return 2 + oparg;
+ case CALL_KW:
+ return 3 + oparg;
+ case CALL_LEN:
+ return 2 + oparg;
+ case CALL_LIST_APPEND:
+ return 3;
+ case CALL_METHOD_DESCRIPTOR_FAST:
+ return 2 + oparg;
+ case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
+ return 2 + oparg;
+ case CALL_METHOD_DESCRIPTOR_NOARGS:
+ return 2 + oparg;
+ case CALL_METHOD_DESCRIPTOR_O:
+ return 2 + oparg;
+ case CALL_NON_PY_GENERAL:
+ return 2 + oparg;
+ case CALL_PY_EXACT_ARGS:
+ return 2 + oparg;
+ case CALL_PY_GENERAL:
+ return 2 + oparg;
+ case CALL_STR_1:
+ return 3;
+ case CALL_TUPLE_1:
+ return 3;
+ case CALL_TYPE_1:
+ return 3;
+ case CHECK_EG_MATCH:
+ return 2;
+ case CHECK_EXC_MATCH:
+ return 2;
+ case CLEANUP_THROW:
+ return 3;
+ case COMPARE_OP:
+ return 2;
+ case COMPARE_OP_FLOAT:
+ return 2;
+ case COMPARE_OP_INT:
+ return 2;
+ case COMPARE_OP_STR:
+ return 2;
+ case CONTAINS_OP:
+ return 2;
+ case CONTAINS_OP_DICT:
+ return 2;
+ case CONTAINS_OP_SET:
+ return 2;
+ case CONVERT_VALUE:
+ return 1;
+ case COPY:
+ return 1 + (oparg-1);
+ case COPY_FREE_VARS:
+ return 0;
+ case DELETE_ATTR:
+ return 1;
+ case DELETE_DEREF:
+ return 0;
+ case DELETE_FAST:
+ return 0;
+ case DELETE_GLOBAL:
+ return 0;
+ case DELETE_NAME:
+ return 0;
+ case DELETE_SUBSCR:
+ return 2;
+ case DICT_MERGE:
+ return 5 + (oparg - 1);
+ case DICT_UPDATE:
+ return 2 + (oparg - 1);
+ case END_ASYNC_FOR:
+ return 2;
+ case END_FOR:
+ return 1;
+ case END_SEND:
+ return 2;
+ case ENTER_EXECUTOR:
+ return 0;
+ case EXIT_INIT_CHECK:
+ return 1;
+ case EXTENDED_ARG:
+ return 0;
+ case FORMAT_SIMPLE:
+ return 1;
+ case FORMAT_WITH_SPEC:
+ return 2;
+ case FOR_ITER:
+ return 1;
+ case FOR_ITER_GEN:
+ return 1;
+ case FOR_ITER_LIST:
+ return 1;
+ case FOR_ITER_RANGE:
+ return 1;
+ case FOR_ITER_TUPLE:
+ return 1;
+ case GET_AITER:
+ return 1;
+ case GET_ANEXT:
+ return 1;
+ case GET_AWAITABLE:
+ return 1;
+ case GET_ITER:
+ return 1;
+ case GET_LEN:
+ return 1;
+ case GET_YIELD_FROM_ITER:
+ return 1;
+ case IMPORT_FROM:
+ return 1;
+ case IMPORT_NAME:
+ return 2;
+ case INSTRUMENTED_CALL:
+ return 0;
+ case INSTRUMENTED_CALL_FUNCTION_EX:
+ return 0;
+ case INSTRUMENTED_CALL_KW:
+ return 0;
+ case INSTRUMENTED_END_FOR:
+ return 2;
+ case INSTRUMENTED_END_SEND:
+ return 2;
+ case INSTRUMENTED_FOR_ITER:
+ return 0;
+ case INSTRUMENTED_INSTRUCTION:
+ return 0;
+ case INSTRUMENTED_JUMP_BACKWARD:
+ return 0;
+ case INSTRUMENTED_JUMP_FORWARD:
+ return 0;
+ case INSTRUMENTED_LOAD_SUPER_ATTR:
+ return 3;
+ case INSTRUMENTED_POP_JUMP_IF_FALSE:
+ return 0;
+ case INSTRUMENTED_POP_JUMP_IF_NONE:
+ return 0;
+ case INSTRUMENTED_POP_JUMP_IF_NOT_NONE:
+ return 0;
+ case INSTRUMENTED_POP_JUMP_IF_TRUE:
+ return 0;
+ case INSTRUMENTED_RESUME:
+ return 0;
+ case INSTRUMENTED_RETURN_CONST:
+ return 0;
+ case INSTRUMENTED_RETURN_VALUE:
+ return 1;
+ case INSTRUMENTED_YIELD_VALUE:
+ return 1;
+ case INTERPRETER_EXIT:
+ return 1;
+ case IS_OP:
+ return 2;
+ case JUMP_BACKWARD:
+ return 0;
+ case JUMP_BACKWARD_NO_INTERRUPT:
+ return 0;
+ case JUMP_FORWARD:
+ return 0;
+ case LIST_APPEND:
+ return 2 + (oparg-1);
+ case LIST_EXTEND:
+ return 2 + (oparg-1);
+ case LOAD_ASSERTION_ERROR:
+ return 0;
+ case LOAD_ATTR:
+ return 1;
+ case LOAD_ATTR_CLASS:
+ return 1;
+ case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
+ return 1;
+ case LOAD_ATTR_INSTANCE_VALUE:
+ return 1;
+ case LOAD_ATTR_METHOD_LAZY_DICT:
+ return 1;
+ case LOAD_ATTR_METHOD_NO_DICT:
+ return 1;
+ case LOAD_ATTR_METHOD_WITH_VALUES:
+ return 1;
+ case LOAD_ATTR_MODULE:
+ return 1;
+ case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
+ return 1;
+ case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
+ return 1;
+ case LOAD_ATTR_PROPERTY:
+ return 1;
+ case LOAD_ATTR_SLOT:
+ return 1;
+ case LOAD_ATTR_WITH_HINT:
+ return 1;
+ case LOAD_BUILD_CLASS:
+ return 0;
+ case LOAD_CONST:
+ return 0;
+ case LOAD_DEREF:
+ return 0;
+ case LOAD_FAST:
+ return 0;
+ case LOAD_FAST_AND_CLEAR:
+ return 0;
+ case LOAD_FAST_CHECK:
+ return 0;
+ case LOAD_FAST_LOAD_FAST:
+ return 0;
+ case LOAD_FROM_DICT_OR_DEREF:
+ return 1;
+ case LOAD_FROM_DICT_OR_GLOBALS:
+ return 1;
+ case LOAD_GLOBAL:
+ return 0;
+ case LOAD_GLOBAL_BUILTIN:
+ return 0;
+ case LOAD_GLOBAL_MODULE:
+ return 0;
+ case LOAD_LOCALS:
+ return 0;
+ case LOAD_NAME:
+ return 0;
+ case LOAD_SUPER_ATTR:
+ return 3;
+ case LOAD_SUPER_ATTR_ATTR:
+ return 3;
+ case LOAD_SUPER_ATTR_METHOD:
+ return 3;
+ case MAKE_CELL:
+ return 0;
+ case MAKE_FUNCTION:
+ return 1;
+ case MAP_ADD:
+ return 3 + (oparg - 1);
+ case MATCH_CLASS:
+ return 3;
+ case MATCH_KEYS:
+ return 2;
+ case MATCH_MAPPING:
+ return 1;
+ case MATCH_SEQUENCE:
+ return 1;
+ case NOP:
+ return 0;
+ case POP_EXCEPT:
+ return 1;
+ case POP_JUMP_IF_FALSE:
+ return 1;
+ case POP_JUMP_IF_NONE:
+ return 1;
+ case POP_JUMP_IF_NOT_NONE:
+ return 1;
+ case POP_JUMP_IF_TRUE:
+ return 1;
+ case POP_TOP:
+ return 1;
+ case PUSH_EXC_INFO:
+ return 1;
+ case PUSH_NULL:
+ return 0;
+ case RAISE_VARARGS:
+ return oparg;
+ case RERAISE:
+ return 1 + oparg;
+ case RESERVED:
+ return 0;
+ case RESUME:
+ return 0;
+ case RESUME_CHECK:
+ return 0;
+ case RETURN_CONST:
+ return 0;
+ case RETURN_GENERATOR:
+ return 0;
+ case RETURN_VALUE:
+ return 1;
+ case SEND:
+ return 2;
+ case SEND_GEN:
+ return 2;
+ case SETUP_ANNOTATIONS:
+ return 0;
+ case SET_ADD:
+ return 2 + (oparg-1);
+ case SET_FUNCTION_ATTRIBUTE:
+ return 2;
+ case SET_UPDATE:
+ return 2 + (oparg-1);
+ case STORE_ATTR:
+ return 2;
+ case STORE_ATTR_INSTANCE_VALUE:
+ return 2;
+ case STORE_ATTR_SLOT:
+ return 2;
+ case STORE_ATTR_WITH_HINT:
+ return 2;
+ case STORE_DEREF:
+ return 1;
+ case STORE_FAST:
+ return 1;
+ case STORE_FAST_LOAD_FAST:
+ return 1;
+ case STORE_FAST_STORE_FAST:
+ return 2;
+ case STORE_GLOBAL:
+ return 1;
+ case STORE_NAME:
+ return 1;
+ case STORE_SLICE:
+ return 4;
+ case STORE_SUBSCR:
+ return 3;
+ case STORE_SUBSCR_DICT:
+ return 3;
+ case STORE_SUBSCR_LIST_INT:
+ return 3;
+ case SWAP:
+ return 2 + (oparg-2);
+ case TO_BOOL:
+ return 1;
+ case TO_BOOL_ALWAYS_TRUE:
+ return 1;
+ case TO_BOOL_BOOL:
+ return 1;
+ case TO_BOOL_INT:
+ return 1;
+ case TO_BOOL_LIST:
+ return 1;
+ case TO_BOOL_NONE:
+ return 1;
+ case TO_BOOL_STR:
+ return 1;
+ case UNARY_INVERT:
+ return 1;
+ case UNARY_NEGATIVE:
+ return 1;
+ case UNARY_NOT:
+ return 1;
+ case UNPACK_EX:
+ return 1;
+ case UNPACK_SEQUENCE:
+ return 1;
+ case UNPACK_SEQUENCE_LIST:
+ return 1;
+ case UNPACK_SEQUENCE_TUPLE:
+ return 1;
+ case UNPACK_SEQUENCE_TWO_TUPLE:
+ return 1;
+ case WITH_EXCEPT_START:
+ return 4;
+ case YIELD_VALUE:
+ return 1;
+ default:
+ return -1;
+ }
+}
+
+#endif
+
+extern int _PyOpcode_num_pushed(int opcode, int oparg);
+#ifdef NEED_OPCODE_METADATA
+int _PyOpcode_num_pushed(int opcode, int oparg) {
+ switch(opcode) {
+ case BEFORE_ASYNC_WITH:
+ return 2;
+ case BEFORE_WITH:
+ return 2;
+ case BINARY_OP:
+ return 1;
+ case BINARY_OP_ADD_FLOAT:
+ return 1;
+ case BINARY_OP_ADD_INT:
+ return 1;
+ case BINARY_OP_ADD_UNICODE:
+ return 1;
+ case BINARY_OP_INPLACE_ADD_UNICODE:
+ return 0;
+ case BINARY_OP_MULTIPLY_FLOAT:
+ return 1;
+ case BINARY_OP_MULTIPLY_INT:
+ return 1;
+ case BINARY_OP_SUBTRACT_FLOAT:
+ return 1;
+ case BINARY_OP_SUBTRACT_INT:
+ return 1;
+ case BINARY_SLICE:
+ return 1;
+ case BINARY_SUBSCR:
+ return 1;
+ case BINARY_SUBSCR_DICT:
+ return 1;
+ case BINARY_SUBSCR_GETITEM:
+ return 1;
+ case BINARY_SUBSCR_LIST_INT:
+ return 1;
+ case BINARY_SUBSCR_STR_INT:
+ return 1;
+ case BINARY_SUBSCR_TUPLE_INT:
+ return 1;
+ case BUILD_CONST_KEY_MAP:
+ return 1;
+ case BUILD_LIST:
+ return 1;
+ case BUILD_MAP:
+ return 1;
+ case BUILD_SET:
+ return 1;
+ case BUILD_SLICE:
+ return 1;
+ case BUILD_STRING:
+ return 1;
+ case BUILD_TUPLE:
+ return 1;
+ case CACHE:
+ return 0;
+ case CALL:
+ return 1;
+ case CALL_ALLOC_AND_ENTER_INIT:
+ return 1;
+ case CALL_BOUND_METHOD_EXACT_ARGS:
+ return 0;
+ case CALL_BOUND_METHOD_GENERAL:
+ return 0;
+ case CALL_BUILTIN_CLASS:
+ return 1;
+ case CALL_BUILTIN_FAST:
+ return 1;
+ case CALL_BUILTIN_FAST_WITH_KEYWORDS:
+ return 1;
+ case CALL_BUILTIN_O:
+ return 1;
+ case CALL_FUNCTION_EX:
+ return 1;
+ case CALL_INTRINSIC_1:
+ return 1;
+ case CALL_INTRINSIC_2:
+ return 1;
+ case CALL_ISINSTANCE:
+ return 1;
+ case CALL_KW:
+ return 1;
+ case CALL_LEN:
+ return 1;
+ case CALL_LIST_APPEND:
+ return 1;
+ case CALL_METHOD_DESCRIPTOR_FAST:
+ return 1;
+ case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
+ return 1;
+ case CALL_METHOD_DESCRIPTOR_NOARGS:
+ return 1;
+ case CALL_METHOD_DESCRIPTOR_O:
+ return 1;
+ case CALL_NON_PY_GENERAL:
+ return 1;
+ case CALL_PY_EXACT_ARGS:
+ return 0;
+ case CALL_PY_GENERAL:
+ return 0;
+ case CALL_STR_1:
+ return 1;
+ case CALL_TUPLE_1:
+ return 1;
+ case CALL_TYPE_1:
+ return 1;
+ case CHECK_EG_MATCH:
+ return 2;
+ case CHECK_EXC_MATCH:
+ return 2;
+ case CLEANUP_THROW:
+ return 2;
+ case COMPARE_OP:
+ return 1;
+ case COMPARE_OP_FLOAT:
+ return 1;
+ case COMPARE_OP_INT:
+ return 1;
+ case COMPARE_OP_STR:
+ return 1;
+ case CONTAINS_OP:
+ return 1;
+ case CONTAINS_OP_DICT:
+ return 1;
+ case CONTAINS_OP_SET:
+ return 1;
+ case CONVERT_VALUE:
+ return 1;
+ case COPY:
+ return 2 + (oparg-1);
+ case COPY_FREE_VARS:
+ return 0;
+ case DELETE_ATTR:
+ return 0;
+ case DELETE_DEREF:
+ return 0;
+ case DELETE_FAST:
+ return 0;
+ case DELETE_GLOBAL:
+ return 0;
+ case DELETE_NAME:
+ return 0;
+ case DELETE_SUBSCR:
+ return 0;
+ case DICT_MERGE:
+ return 4 + (oparg - 1);
+ case DICT_UPDATE:
+ return 1 + (oparg - 1);
+ case END_ASYNC_FOR:
+ return 0;
+ case END_FOR:
+ return 0;
+ case END_SEND:
+ return 1;
+ case ENTER_EXECUTOR:
+ return 0;
+ case EXIT_INIT_CHECK:
+ return 0;
+ case EXTENDED_ARG:
+ return 0;
+ case FORMAT_SIMPLE:
+ return 1;
+ case FORMAT_WITH_SPEC:
+ return 1;
+ case FOR_ITER:
+ return 2;
+ case FOR_ITER_GEN:
+ return 1;
+ case FOR_ITER_LIST:
+ return 2;
+ case FOR_ITER_RANGE:
+ return 2;
+ case FOR_ITER_TUPLE:
+ return 2;
+ case GET_AITER:
+ return 1;
+ case GET_ANEXT:
+ return 2;
+ case GET_AWAITABLE:
+ return 1;
+ case GET_ITER:
+ return 1;
+ case GET_LEN:
+ return 2;
+ case GET_YIELD_FROM_ITER:
+ return 1;
+ case IMPORT_FROM:
+ return 2;
+ case IMPORT_NAME:
+ return 1;
+ case INSTRUMENTED_CALL:
+ return 0;
+ case INSTRUMENTED_CALL_FUNCTION_EX:
+ return 0;
+ case INSTRUMENTED_CALL_KW:
+ return 0;
+ case INSTRUMENTED_END_FOR:
+ return 1;
+ case INSTRUMENTED_END_SEND:
+ return 1;
+ case INSTRUMENTED_FOR_ITER:
+ return 0;
+ case INSTRUMENTED_INSTRUCTION:
+ return 0;
+ case INSTRUMENTED_JUMP_BACKWARD:
+ return 0;
+ case INSTRUMENTED_JUMP_FORWARD:
+ return 0;
+ case INSTRUMENTED_LOAD_SUPER_ATTR:
+ return 1 + (oparg & 1);
+ case INSTRUMENTED_POP_JUMP_IF_FALSE:
+ return 0;
+ case INSTRUMENTED_POP_JUMP_IF_NONE:
+ return 0;
+ case INSTRUMENTED_POP_JUMP_IF_NOT_NONE:
+ return 0;
+ case INSTRUMENTED_POP_JUMP_IF_TRUE:
+ return 0;
+ case INSTRUMENTED_RESUME:
+ return 0;
+ case INSTRUMENTED_RETURN_CONST:
+ return 0;
+ case INSTRUMENTED_RETURN_VALUE:
+ return 0;
+ case INSTRUMENTED_YIELD_VALUE:
+ return 1;
+ case INTERPRETER_EXIT:
+ return 0;
+ case IS_OP:
+ return 1;
+ case JUMP_BACKWARD:
+ return 0;
+ case JUMP_BACKWARD_NO_INTERRUPT:
+ return 0;
+ case JUMP_FORWARD:
+ return 0;
+ case LIST_APPEND:
+ return 1 + (oparg-1);
+ case LIST_EXTEND:
+ return 1 + (oparg-1);
+ case LOAD_ASSERTION_ERROR:
+ return 1;
+ case LOAD_ATTR:
+ return 1 + (oparg & 1);
+ case LOAD_ATTR_CLASS:
+ return 1 + (oparg & 1);
+ case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN:
+ return 1;
+ case LOAD_ATTR_INSTANCE_VALUE:
+ return 1 + (oparg & 1);
+ case LOAD_ATTR_METHOD_LAZY_DICT:
+ return 2;
+ case LOAD_ATTR_METHOD_NO_DICT:
+ return 2;
+ case LOAD_ATTR_METHOD_WITH_VALUES:
+ return 2;
+ case LOAD_ATTR_MODULE:
+ return 1 + (oparg & 1);
+ case LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
+ return 1;
+ case LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
+ return 1;
+ case LOAD_ATTR_PROPERTY:
+ return 1;
+ case LOAD_ATTR_SLOT:
+ return 1 + (oparg & 1);
+ case LOAD_ATTR_WITH_HINT:
+ return 1 + (oparg & 1);
+ case LOAD_BUILD_CLASS:
+ return 1;
+ case LOAD_CONST:
+ return 1;
+ case LOAD_DEREF:
+ return 1;
+ case LOAD_FAST:
+ return 1;
+ case LOAD_FAST_AND_CLEAR:
+ return 1;
+ case LOAD_FAST_CHECK:
+ return 1;
+ case LOAD_FAST_LOAD_FAST:
+ return 2;
+ case LOAD_FROM_DICT_OR_DEREF:
+ return 1;
+ case LOAD_FROM_DICT_OR_GLOBALS:
+ return 1;
+ case LOAD_GLOBAL:
+ return 1 + (oparg & 1);
+ case LOAD_GLOBAL_BUILTIN:
+ return 1 + (oparg & 1);
+ case LOAD_GLOBAL_MODULE:
+ return 1 + (oparg & 1);
+ case LOAD_LOCALS:
+ return 1;
+ case LOAD_NAME:
+ return 1;
+ case LOAD_SUPER_ATTR:
+ return 1 + (oparg & 1);
+ case LOAD_SUPER_ATTR_ATTR:
+ return 1;
+ case LOAD_SUPER_ATTR_METHOD:
+ return 2;
+ case MAKE_CELL:
+ return 0;
+ case MAKE_FUNCTION:
+ return 1;
+ case MAP_ADD:
+ return 1 + (oparg - 1);
+ case MATCH_CLASS:
+ return 1;
+ case MATCH_KEYS:
+ return 3;
+ case MATCH_MAPPING:
+ return 2;
+ case MATCH_SEQUENCE:
+ return 2;
+ case NOP:
+ return 0;
+ case POP_EXCEPT:
+ return 0;
+ case POP_JUMP_IF_FALSE:
+ return 0;
+ case POP_JUMP_IF_NONE:
+ return 0;
+ case POP_JUMP_IF_NOT_NONE:
+ return 0;
+ case POP_JUMP_IF_TRUE:
+ return 0;
+ case POP_TOP:
+ return 0;
+ case PUSH_EXC_INFO:
+ return 2;
+ case PUSH_NULL:
+ return 1;
+ case RAISE_VARARGS:
+ return 0;
+ case RERAISE:
+ return oparg;
+ case RESERVED:
+ return 0;
+ case RESUME:
+ return 0;
+ case RESUME_CHECK:
+ return 0;
+ case RETURN_CONST:
+ return 0;
+ case RETURN_GENERATOR:
+ return 1;
+ case RETURN_VALUE:
+ return 0;
+ case SEND:
+ return 2;
+ case SEND_GEN:
+ return 2;
+ case SETUP_ANNOTATIONS:
+ return 0;
+ case SET_ADD:
+ return 1 + (oparg-1);
+ case SET_FUNCTION_ATTRIBUTE:
+ return 1;
+ case SET_UPDATE:
+ return 1 + (oparg-1);
+ case STORE_ATTR:
+ return 0;
+ case STORE_ATTR_INSTANCE_VALUE:
+ return 0;
+ case STORE_ATTR_SLOT:
+ return 0;
+ case STORE_ATTR_WITH_HINT:
+ return 0;
+ case STORE_DEREF:
+ return 0;
+ case STORE_FAST:
+ return 0;
+ case STORE_FAST_LOAD_FAST:
+ return 1;
+ case STORE_FAST_STORE_FAST:
+ return 0;
+ case STORE_GLOBAL:
+ return 0;
+ case STORE_NAME:
+ return 0;
+ case STORE_SLICE:
+ return 0;
+ case STORE_SUBSCR:
+ return 0;
+ case STORE_SUBSCR_DICT:
+ return 0;
+ case STORE_SUBSCR_LIST_INT:
+ return 0;
+ case SWAP:
+ return 2 + (oparg-2);
+ case TO_BOOL:
+ return 1;
+ case TO_BOOL_ALWAYS_TRUE:
+ return 1;
+ case TO_BOOL_BOOL:
+ return 1;
+ case TO_BOOL_INT:
+ return 1;
+ case TO_BOOL_LIST:
+ return 1;
+ case TO_BOOL_NONE:
+ return 1;
+ case TO_BOOL_STR:
+ return 1;
+ case UNARY_INVERT:
+ return 1;
+ case UNARY_NEGATIVE:
+ return 1;
+ case UNARY_NOT:
+ return 1;
+ case UNPACK_EX:
+ return 1 + (oparg >> 8) + (oparg & 0xFF);
+ case UNPACK_SEQUENCE:
+ return oparg;
+ case UNPACK_SEQUENCE_LIST:
+ return oparg;
+ case UNPACK_SEQUENCE_TUPLE:
+ return oparg;
+ case UNPACK_SEQUENCE_TWO_TUPLE:
+ return 2;
+ case WITH_EXCEPT_START:
+ return 5;
+ case YIELD_VALUE:
+ return 1;
+ default:
+ return -1;
+ }
+}
+
+#endif
+
+enum InstructionFormat {
+ INSTR_FMT_IB = 1,
+ INSTR_FMT_IBC = 2,
+ INSTR_FMT_IBC00 = 3,
+ INSTR_FMT_IBC000 = 4,
+ INSTR_FMT_IBC00000000 = 5,
+ INSTR_FMT_IX = 6,
+ INSTR_FMT_IXC = 7,
+ INSTR_FMT_IXC00 = 8,
+ INSTR_FMT_IXC000 = 9,
+};
+
+#define IS_VALID_OPCODE(OP) \
+ (((OP) >= 0) && ((OP) < 268) && \
+ (_PyOpcode_opcode_metadata[(OP)].valid_entry))
+
+#define HAS_ARG_FLAG (1)
+#define HAS_CONST_FLAG (2)
+#define HAS_NAME_FLAG (4)
+#define HAS_JUMP_FLAG (8)
+#define HAS_FREE_FLAG (16)
+#define HAS_LOCAL_FLAG (32)
+#define HAS_EVAL_BREAK_FLAG (64)
+#define HAS_DEOPT_FLAG (128)
+#define HAS_ERROR_FLAG (256)
+#define HAS_ESCAPES_FLAG (512)
+#define HAS_EXIT_FLAG (1024)
+#define HAS_PURE_FLAG (2048)
+#define HAS_PASSTHROUGH_FLAG (4096)
+#define HAS_OPARG_AND_1_FLAG (8192)
+#define HAS_ERROR_NO_POP_FLAG (16384)
+#define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG))
+#define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG))
+#define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG))
+#define OPCODE_HAS_JUMP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_JUMP_FLAG))
+#define OPCODE_HAS_FREE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_FREE_FLAG))
+#define OPCODE_HAS_LOCAL(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_LOCAL_FLAG))
+#define OPCODE_HAS_EVAL_BREAK(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_EVAL_BREAK_FLAG))
+#define OPCODE_HAS_DEOPT(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_DEOPT_FLAG))
+#define OPCODE_HAS_ERROR(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_FLAG))
+#define OPCODE_HAS_ESCAPES(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ESCAPES_FLAG))
+#define OPCODE_HAS_EXIT(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_EXIT_FLAG))
+#define OPCODE_HAS_PURE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PURE_FLAG))
+#define OPCODE_HAS_PASSTHROUGH(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PASSTHROUGH_FLAG))
+#define OPCODE_HAS_OPARG_AND_1(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_OPARG_AND_1_FLAG))
+#define OPCODE_HAS_ERROR_NO_POP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_NO_POP_FLAG))
+
+#define OPARG_FULL 0
+#define OPARG_CACHE_1 1
+#define OPARG_CACHE_2 2
+#define OPARG_CACHE_4 4
+#define OPARG_TOP 5
+#define OPARG_BOTTOM 6
+#define OPARG_SAVE_RETURN_OFFSET 7
+#define OPARG_REPLACED 9
+
+struct opcode_metadata {
+ uint8_t valid_entry;
+ int8_t instr_format;
+ int16_t flags;
+};
+
+extern const struct opcode_metadata _PyOpcode_opcode_metadata[268];
+#ifdef NEED_OPCODE_METADATA
+const struct opcode_metadata _PyOpcode_opcode_metadata[268] = {
+ [BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [BEFORE_WITH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG },
+ [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
+ [BINARY_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
+ [BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
+ [BUILD_CONST_KEY_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BUILD_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [BUILD_MAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BUILD_SET] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [BUILD_SLICE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [BUILD_STRING] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [BUILD_TUPLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [CACHE] = { true, INSTR_FMT_IX, 0 },
+ [CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [CALL_BOUND_METHOD_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
+ [CALL_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_NON_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [CALL_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [CHECK_EG_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
+ [COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
+ [CONTAINS_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CONTAINS_OP_DICT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CONTAINS_OP_SET] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [CONVERT_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [COPY] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_PURE_FLAG },
+ [COPY_FREE_VARS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
+ [DELETE_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [DELETE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [DELETE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [DELETE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [DELETE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [DELETE_SUBSCR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [DICT_MERGE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [END_FOR] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [END_SEND] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
+ [EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
+ [FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG },
+ [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG },
+ [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG },
+ [GET_AITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [GET_ANEXT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [GET_AWAITABLE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [GET_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [IMPORT_FROM] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [IMPORT_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, 0 },
+ [INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
+ [INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
+ [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG },
+ [INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [INTERPRETER_EXIT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
+ [IS_OP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
+ [JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
+ [LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX, 0 },
+ [LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_PURE_FLAG },
+ [LOAD_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG },
+ [LOAD_FAST_AND_CLEAR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
+ [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [MATCH_KEYS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [MATCH_MAPPING] = { true, INSTR_FMT_IX, 0 },
+ [MATCH_SEQUENCE] = { true, INSTR_FMT_IX, 0 },
+ [NOP] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [POP_EXCEPT] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
+ [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_TOP] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [PUSH_EXC_INFO] = { true, INSTR_FMT_IX, 0 },
+ [PUSH_NULL] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [RAISE_VARARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [RESERVED] = { true, INSTR_FMT_IX, 0 },
+ [RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
+ [RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
+ [RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [RETURN_VALUE] = { true, INSTR_FMT_IX, 0 },
+ [SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
+ [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
+ [SET_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_ATTR] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000, HAS_EXIT_FLAG },
+ [STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [STORE_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [STORE_FAST_STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+ [STORE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_SUBSCR] = { true, INSTR_FMT_IXC, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_SUBSCR_DICT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [STORE_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC, HAS_DEOPT_FLAG },
+ [SWAP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_PURE_FLAG },
+ [TO_BOOL] = { true, INSTR_FMT_IXC00, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
+ [TO_BOOL_BOOL] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
+ [TO_BOOL_INT] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
+ [TO_BOOL_LIST] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
+ [TO_BOOL_NONE] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG },
+ [TO_BOOL_STR] = { true, INSTR_FMT_IXC00, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
+ [UNARY_INVERT] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [UNARY_NEGATIVE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [UNARY_NOT] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
+ [UNPACK_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
+ [WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
+ [JUMP] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [JUMP_NO_INTERRUPT] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [LOAD_CLOSURE] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG },
+ [LOAD_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_SUPER_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ZERO_SUPER_ATTR] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [LOAD_ZERO_SUPER_METHOD] = { true, -1, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [POP_BLOCK] = { true, -1, HAS_PURE_FLAG },
+ [SETUP_CLEANUP] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG },
+ [SETUP_FINALLY] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG },
+ [SETUP_WITH] = { true, -1, HAS_PURE_FLAG | HAS_ARG_FLAG },
+ [STORE_FAST_MAYBE_NULL] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
+};
+#endif
+
+#define MAX_UOP_PER_EXPANSION 9
+struct opcode_macro_expansion {
+ int nuops;
+ struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];
+};
+extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[256];
+
+#ifdef NEED_OPCODE_METADATA
+const struct opcode_macro_expansion
+_PyOpcode_macro_expansion[256] = {
+ [BINARY_OP] = { .nuops = 1, .uops = { { _BINARY_OP, 0, 0 } } },
+ [BINARY_OP_ADD_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_ADD_FLOAT, 0, 0 } } },
+ [BINARY_OP_ADD_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_ADD_INT, 0, 0 } } },
+ [BINARY_OP_ADD_UNICODE] = { .nuops = 2, .uops = { { _GUARD_BOTH_UNICODE, 0, 0 }, { _BINARY_OP_ADD_UNICODE, 0, 0 } } },
+ [BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, 0, 0 } } },
+ [BINARY_OP_MULTIPLY_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_MULTIPLY_INT, 0, 0 } } },
+ [BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, 0, 0 } } },
+ [BINARY_OP_SUBTRACT_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_SUBTRACT_INT, 0, 0 } } },
+ [BINARY_SLICE] = { .nuops = 1, .uops = { { _BINARY_SLICE, 0, 0 } } },
+ [BINARY_SUBSCR] = { .nuops = 1, .uops = { { _BINARY_SUBSCR, 0, 0 } } },
+ [BINARY_SUBSCR_DICT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_DICT, 0, 0 } } },
+ [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_LIST_INT, 0, 0 } } },
+ [BINARY_SUBSCR_STR_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_STR_INT, 0, 0 } } },
+ [BINARY_SUBSCR_TUPLE_INT] = { .nuops = 1, .uops = { { _BINARY_SUBSCR_TUPLE_INT, 0, 0 } } },
+ [BUILD_CONST_KEY_MAP] = { .nuops = 1, .uops = { { _BUILD_CONST_KEY_MAP, 0, 0 } } },
+ [BUILD_LIST] = { .nuops = 1, .uops = { { _BUILD_LIST, 0, 0 } } },
+ [BUILD_MAP] = { .nuops = 1, .uops = { { _BUILD_MAP, 0, 0 } } },
+ [BUILD_SLICE] = { .nuops = 1, .uops = { { _BUILD_SLICE, 0, 0 } } },
+ [BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, 0, 0 } } },
+ [BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, 0, 0 } } },
+ [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 9, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _CHECK_RECURSION_REMAINING, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
+ [CALL_BOUND_METHOD_GENERAL] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, 0, 0 }, { _CHECK_RECURSION_REMAINING, 0, 0 }, { _PY_FRAME_GENERAL, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
+ [CALL_BUILTIN_CLASS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_CLASS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_BUILTIN_FAST] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_BUILTIN_O] = { .nuops = 2, .uops = { { _CALL_BUILTIN_O, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_1, 0, 0 } } },
+ [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_2, 0, 0 } } },
+ [CALL_ISINSTANCE] = { .nuops = 1, .uops = { { _CALL_ISINSTANCE, 0, 0 } } },
+ [CALL_LEN] = { .nuops = 1, .uops = { { _CALL_LEN, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_O, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_NON_PY_GENERAL] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE, 0, 0 }, { _CALL_NON_PY_GENERAL, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_PY_EXACT_ARGS] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _CHECK_RECURSION_REMAINING, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
+ [CALL_PY_GENERAL] = { .nuops = 6, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_RECURSION_REMAINING, 0, 0 }, { _PY_FRAME_GENERAL, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
+ [CALL_STR_1] = { .nuops = 2, .uops = { { _CALL_STR_1, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_TUPLE_1] = { .nuops = 2, .uops = { { _CALL_TUPLE_1, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
+ [CALL_TYPE_1] = { .nuops = 1, .uops = { { _CALL_TYPE_1, 0, 0 } } },
+ [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { _CHECK_EG_MATCH, 0, 0 } } },
+ [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { _CHECK_EXC_MATCH, 0, 0 } } },
+ [COMPARE_OP] = { .nuops = 1, .uops = { { _COMPARE_OP, 0, 0 } } },
+ [COMPARE_OP_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _COMPARE_OP_FLOAT, 0, 0 } } },
+ [COMPARE_OP_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _COMPARE_OP_INT, 0, 0 } } },
+ [COMPARE_OP_STR] = { .nuops = 2, .uops = { { _GUARD_BOTH_UNICODE, 0, 0 }, { _COMPARE_OP_STR, 0, 0 } } },
+ [CONTAINS_OP] = { .nuops = 1, .uops = { { _CONTAINS_OP, 0, 0 } } },
+ [CONTAINS_OP_DICT] = { .nuops = 1, .uops = { { _CONTAINS_OP_DICT, 0, 0 } } },
+ [CONTAINS_OP_SET] = { .nuops = 1, .uops = { { _CONTAINS_OP_SET, 0, 0 } } },
+ [CONVERT_VALUE] = { .nuops = 1, .uops = { { _CONVERT_VALUE, 0, 0 } } },
+ [COPY] = { .nuops = 1, .uops = { { _COPY, 0, 0 } } },
+ [COPY_FREE_VARS] = { .nuops = 1, .uops = { { _COPY_FREE_VARS, 0, 0 } } },
+ [DELETE_ATTR] = { .nuops = 1, .uops = { { _DELETE_ATTR, 0, 0 } } },
+ [DELETE_DEREF] = { .nuops = 1, .uops = { { _DELETE_DEREF, 0, 0 } } },
+ [DELETE_FAST] = { .nuops = 1, .uops = { { _DELETE_FAST, 0, 0 } } },
+ [DELETE_GLOBAL] = { .nuops = 1, .uops = { { _DELETE_GLOBAL, 0, 0 } } },
+ [DELETE_NAME] = { .nuops = 1, .uops = { { _DELETE_NAME, 0, 0 } } },
+ [DELETE_SUBSCR] = { .nuops = 1, .uops = { { _DELETE_SUBSCR, 0, 0 } } },
+ [DICT_MERGE] = { .nuops = 1, .uops = { { _DICT_MERGE, 0, 0 } } },
+ [DICT_UPDATE] = { .nuops = 1, .uops = { { _DICT_UPDATE, 0, 0 } } },
+ [END_FOR] = { .nuops = 1, .uops = { { _POP_TOP, 0, 0 } } },
+ [END_SEND] = { .nuops = 1, .uops = { { _END_SEND, 0, 0 } } },
+ [EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { _EXIT_INIT_CHECK, 0, 0 } } },
+ [FORMAT_SIMPLE] = { .nuops = 1, .uops = { { _FORMAT_SIMPLE, 0, 0 } } },
+ [FORMAT_WITH_SPEC] = { .nuops = 1, .uops = { { _FORMAT_WITH_SPEC, 0, 0 } } },
+ [FOR_ITER] = { .nuops = 1, .uops = { { _FOR_ITER, 9, 0 } } },
+ [FOR_ITER_GEN] = { .nuops = 3, .uops = { { _CHECK_PEP_523, 0, 0 }, { _FOR_ITER_GEN_FRAME, 0, 0 }, { _PUSH_FRAME, 0, 0 } } },
+ [FOR_ITER_LIST] = { .nuops = 3, .uops = { { _ITER_CHECK_LIST, 0, 0 }, { _ITER_JUMP_LIST, 9, 1 }, { _ITER_NEXT_LIST, 0, 0 } } },
+ [FOR_ITER_RANGE] = { .nuops = 3, .uops = { { _ITER_CHECK_RANGE, 0, 0 }, { _ITER_JUMP_RANGE, 9, 1 }, { _ITER_NEXT_RANGE, 0, 0 } } },
+ [FOR_ITER_TUPLE] = { .nuops = 3, .uops = { { _ITER_CHECK_TUPLE, 0, 0 }, { _ITER_JUMP_TUPLE, 9, 1 }, { _ITER_NEXT_TUPLE, 0, 0 } } },
+ [GET_AITER] = { .nuops = 1, .uops = { { _GET_AITER, 0, 0 } } },
+ [GET_ANEXT] = { .nuops = 1, .uops = { { _GET_ANEXT, 0, 0 } } },
+ [GET_AWAITABLE] = { .nuops = 1, .uops = { { _GET_AWAITABLE, 0, 0 } } },
+ [GET_ITER] = { .nuops = 1, .uops = { { _GET_ITER, 0, 0 } } },
+ [GET_LEN] = { .nuops = 1, .uops = { { _GET_LEN, 0, 0 } } },
+ [GET_YIELD_FROM_ITER] = { .nuops = 1, .uops = { { _GET_YIELD_FROM_ITER, 0, 0 } } },
+ [IS_OP] = { .nuops = 1, .uops = { { _IS_OP, 0, 0 } } },
+ [LIST_APPEND] = { .nuops = 1, .uops = { { _LIST_APPEND, 0, 0 } } },
+ [LIST_EXTEND] = { .nuops = 1, .uops = { { _LIST_EXTEND, 0, 0 } } },
+ [LOAD_ASSERTION_ERROR] = { .nuops = 1, .uops = { { _LOAD_ASSERTION_ERROR, 0, 0 } } },
+ [LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, 0, 0 } } },
+ [LOAD_ATTR_CLASS] = { .nuops = 2, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 } } },
+ [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, 0, 0 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 } } },
+ [LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } },
+ [LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } },
+ [LOAD_ATTR_METHOD_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_METHOD_WITH_VALUES, 4, 5 } } },
+ [LOAD_ATTR_MODULE] = { .nuops = 2, .uops = { { _CHECK_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, 1, 3 } } },
+ [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } },
+ [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 4, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, 0, 0 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } },
+ [LOAD_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 } } },
+ [LOAD_ATTR_WITH_HINT] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_WITH_HINT, 0, 0 }, { _LOAD_ATTR_WITH_HINT, 1, 3 } } },
+ [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { _LOAD_BUILD_CLASS, 0, 0 } } },
+ [LOAD_CONST] = { .nuops = 1, .uops = { { _LOAD_CONST, 0, 0 } } },
+ [LOAD_DEREF] = { .nuops = 1, .uops = { { _LOAD_DEREF, 0, 0 } } },
+ [LOAD_FAST] = { .nuops = 1, .uops = { { _LOAD_FAST, 0, 0 } } },
+ [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { _LOAD_FAST_AND_CLEAR, 0, 0 } } },
+ [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { _LOAD_FAST_CHECK, 0, 0 } } },
+ [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _LOAD_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } },
+ [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_DEREF, 0, 0 } } },
+ [LOAD_GLOBAL] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } },
+ [LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION, 1, 2 }, { _LOAD_GLOBAL_BUILTINS, 1, 3 } } },
+ [LOAD_GLOBAL_MODULE] = { .nuops = 2, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _LOAD_GLOBAL_MODULE, 1, 3 } } },
+ [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } },
+ [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, 0, 0 } } },
+ [LOAD_SUPER_ATTR_METHOD] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_METHOD, 0, 0 } } },
+ [MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, 0, 0 } } },
+ [MAKE_FUNCTION] = { .nuops = 1, .uops = { { _MAKE_FUNCTION, 0, 0 } } },
+ [MAP_ADD] = { .nuops = 1, .uops = { { _MAP_ADD, 0, 0 } } },
+ [MATCH_CLASS] = { .nuops = 1, .uops = { { _MATCH_CLASS, 0, 0 } } },
+ [MATCH_KEYS] = { .nuops = 1, .uops = { { _MATCH_KEYS, 0, 0 } } },
+ [MATCH_MAPPING] = { .nuops = 1, .uops = { { _MATCH_MAPPING, 0, 0 } } },
+ [MATCH_SEQUENCE] = { .nuops = 1, .uops = { { _MATCH_SEQUENCE, 0, 0 } } },
+ [NOP] = { .nuops = 1, .uops = { { _NOP, 0, 0 } } },
+ [POP_EXCEPT] = { .nuops = 1, .uops = { { _POP_EXCEPT, 0, 0 } } },
+ [POP_JUMP_IF_FALSE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_FALSE, 9, 1 } } },
+ [POP_JUMP_IF_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_TRUE, 9, 1 } } },
+ [POP_JUMP_IF_NOT_NONE] = { .nuops = 2, .uops = { { _IS_NONE, 0, 0 }, { _POP_JUMP_IF_FALSE, 9, 1 } } },
+ [POP_JUMP_IF_TRUE] = { .nuops = 1, .uops = { { _POP_JUMP_IF_TRUE, 9, 1 } } },
+ [POP_TOP] = { .nuops = 1, .uops = { { _POP_TOP, 0, 0 } } },
+ [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { _PUSH_EXC_INFO, 0, 0 } } },
+ [PUSH_NULL] = { .nuops = 1, .uops = { { _PUSH_NULL, 0, 0 } } },
+ [RESUME_CHECK] = { .nuops = 1, .uops = { { _RESUME_CHECK, 0, 0 } } },
+ [RETURN_CONST] = { .nuops = 2, .uops = { { _LOAD_CONST, 0, 0 }, { _POP_FRAME, 0, 0 } } },
+ [RETURN_GENERATOR] = { .nuops = 1, .uops = { { _RETURN_GENERATOR, 0, 0 } } },
+ [RETURN_VALUE] = { .nuops = 1, .uops = { { _POP_FRAME, 0, 0 } } },
+ [SETUP_ANNOTATIONS] = { .nuops = 1, .uops = { { _SETUP_ANNOTATIONS, 0, 0 } } },
+ [SET_ADD] = { .nuops = 1, .uops = { { _SET_ADD, 0, 0 } } },
+ [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { _SET_FUNCTION_ATTRIBUTE, 0, 0 } } },
+ [SET_UPDATE] = { .nuops = 1, .uops = { { _SET_UPDATE, 0, 0 } } },
+ [STORE_ATTR] = { .nuops = 1, .uops = { { _STORE_ATTR, 0, 0 } } },
+ [STORE_ATTR_INSTANCE_VALUE] = { .nuops = 3, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_NO_DICT, 0, 0 }, { _STORE_ATTR_INSTANCE_VALUE, 1, 3 } } },
+ [STORE_ATTR_SLOT] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _STORE_ATTR_SLOT, 1, 3 } } },
+ [STORE_DEREF] = { .nuops = 1, .uops = { { _STORE_DEREF, 0, 0 } } },
+ [STORE_FAST] = { .nuops = 1, .uops = { { _STORE_FAST, 0, 0 } } },
+ [STORE_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } },
+ [STORE_FAST_STORE_FAST] = { .nuops = 2, .uops = { { _STORE_FAST, 5, 0 }, { _STORE_FAST, 6, 0 } } },
+ [STORE_GLOBAL] = { .nuops = 1, .uops = { { _STORE_GLOBAL, 0, 0 } } },
+ [STORE_NAME] = { .nuops = 1, .uops = { { _STORE_NAME, 0, 0 } } },
+ [STORE_SLICE] = { .nuops = 1, .uops = { { _STORE_SLICE, 0, 0 } } },
+ [STORE_SUBSCR] = { .nuops = 1, .uops = { { _STORE_SUBSCR, 0, 0 } } },
+ [STORE_SUBSCR_DICT] = { .nuops = 1, .uops = { { _STORE_SUBSCR_DICT, 0, 0 } } },
+ [STORE_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { _STORE_SUBSCR_LIST_INT, 0, 0 } } },
+ [SWAP] = { .nuops = 1, .uops = { { _SWAP, 0, 0 } } },
+ [TO_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL, 0, 0 } } },
+ [TO_BOOL_ALWAYS_TRUE] = { .nuops = 2, .uops = { { _GUARD_TYPE_VERSION, 2, 1 }, { _REPLACE_WITH_TRUE, 0, 0 } } },
+ [TO_BOOL_BOOL] = { .nuops = 1, .uops = { { _TO_BOOL_BOOL, 0, 0 } } },
+ [TO_BOOL_INT] = { .nuops = 1, .uops = { { _TO_BOOL_INT, 0, 0 } } },
+ [TO_BOOL_LIST] = { .nuops = 1, .uops = { { _TO_BOOL_LIST, 0, 0 } } },
+ [TO_BOOL_NONE] = { .nuops = 1, .uops = { { _TO_BOOL_NONE, 0, 0 } } },
+ [TO_BOOL_STR] = { .nuops = 1, .uops = { { _TO_BOOL_STR, 0, 0 } } },
+ [UNARY_INVERT] = { .nuops = 1, .uops = { { _UNARY_INVERT, 0, 0 } } },
+ [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { _UNARY_NEGATIVE, 0, 0 } } },
+ [UNARY_NOT] = { .nuops = 1, .uops = { { _UNARY_NOT, 0, 0 } } },
+ [UNPACK_EX] = { .nuops = 1, .uops = { { _UNPACK_EX, 0, 0 } } },
+ [UNPACK_SEQUENCE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE, 0, 0 } } },
+ [UNPACK_SEQUENCE_LIST] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_LIST, 0, 0 } } },
+ [UNPACK_SEQUENCE_TUPLE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_TUPLE, 0, 0 } } },
+ [UNPACK_SEQUENCE_TWO_TUPLE] = { .nuops = 1, .uops = { { _UNPACK_SEQUENCE_TWO_TUPLE, 0, 0 } } },
+ [WITH_EXCEPT_START] = { .nuops = 1, .uops = { { _WITH_EXCEPT_START, 0, 0 } } },
+ [YIELD_VALUE] = { .nuops = 1, .uops = { { _YIELD_VALUE, 0, 0 } } },
+};
+#endif // NEED_OPCODE_METADATA
+
+extern const char *_PyOpcode_OpName[268];
+#ifdef NEED_OPCODE_METADATA
+const char *_PyOpcode_OpName[268] = {
+ [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH",
+ [BEFORE_WITH] = "BEFORE_WITH",
+ [BINARY_OP] = "BINARY_OP",
+ [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT",
+ [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT",
+ [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE",
+ [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE",
+ [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT",
+ [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT",
+ [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT",
+ [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT",
+ [BINARY_SLICE] = "BINARY_SLICE",
+ [BINARY_SUBSCR] = "BINARY_SUBSCR",
+ [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT",
+ [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM",
+ [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT",
+ [BINARY_SUBSCR_STR_INT] = "BINARY_SUBSCR_STR_INT",
+ [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT",
+ [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP",
+ [BUILD_LIST] = "BUILD_LIST",
+ [BUILD_MAP] = "BUILD_MAP",
+ [BUILD_SET] = "BUILD_SET",
+ [BUILD_SLICE] = "BUILD_SLICE",
+ [BUILD_STRING] = "BUILD_STRING",
+ [BUILD_TUPLE] = "BUILD_TUPLE",
+ [CACHE] = "CACHE",
+ [CALL] = "CALL",
+ [CALL_ALLOC_AND_ENTER_INIT] = "CALL_ALLOC_AND_ENTER_INIT",
+ [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
+ [CALL_BOUND_METHOD_GENERAL] = "CALL_BOUND_METHOD_GENERAL",
+ [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
+ [CALL_BUILTIN_FAST] = "CALL_BUILTIN_FAST",
+ [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
+ [CALL_BUILTIN_O] = "CALL_BUILTIN_O",
+ [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
+ [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1",
+ [CALL_INTRINSIC_2] = "CALL_INTRINSIC_2",
+ [CALL_ISINSTANCE] = "CALL_ISINSTANCE",
+ [CALL_KW] = "CALL_KW",
+ [CALL_LEN] = "CALL_LEN",
+ [CALL_LIST_APPEND] = "CALL_LIST_APPEND",
+ [CALL_METHOD_DESCRIPTOR_FAST] = "CALL_METHOD_DESCRIPTOR_FAST",
+ [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
+ [CALL_METHOD_DESCRIPTOR_NOARGS] = "CALL_METHOD_DESCRIPTOR_NOARGS",
+ [CALL_METHOD_DESCRIPTOR_O] = "CALL_METHOD_DESCRIPTOR_O",
+ [CALL_NON_PY_GENERAL] = "CALL_NON_PY_GENERAL",
+ [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
+ [CALL_PY_GENERAL] = "CALL_PY_GENERAL",
+ [CALL_STR_1] = "CALL_STR_1",
+ [CALL_TUPLE_1] = "CALL_TUPLE_1",
+ [CALL_TYPE_1] = "CALL_TYPE_1",
+ [CHECK_EG_MATCH] = "CHECK_EG_MATCH",
+ [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH",
+ [CLEANUP_THROW] = "CLEANUP_THROW",
+ [COMPARE_OP] = "COMPARE_OP",
+ [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT",
+ [COMPARE_OP_INT] = "COMPARE_OP_INT",
+ [COMPARE_OP_STR] = "COMPARE_OP_STR",
+ [CONTAINS_OP] = "CONTAINS_OP",
+ [CONTAINS_OP_DICT] = "CONTAINS_OP_DICT",
+ [CONTAINS_OP_SET] = "CONTAINS_OP_SET",
+ [CONVERT_VALUE] = "CONVERT_VALUE",
+ [COPY] = "COPY",
+ [COPY_FREE_VARS] = "COPY_FREE_VARS",
+ [DELETE_ATTR] = "DELETE_ATTR",
+ [DELETE_DEREF] = "DELETE_DEREF",
+ [DELETE_FAST] = "DELETE_FAST",
+ [DELETE_GLOBAL] = "DELETE_GLOBAL",
+ [DELETE_NAME] = "DELETE_NAME",
+ [DELETE_SUBSCR] = "DELETE_SUBSCR",
+ [DICT_MERGE] = "DICT_MERGE",
+ [DICT_UPDATE] = "DICT_UPDATE",
+ [END_ASYNC_FOR] = "END_ASYNC_FOR",
+ [END_FOR] = "END_FOR",
+ [END_SEND] = "END_SEND",
+ [ENTER_EXECUTOR] = "ENTER_EXECUTOR",
+ [EXIT_INIT_CHECK] = "EXIT_INIT_CHECK",
+ [EXTENDED_ARG] = "EXTENDED_ARG",
+ [FORMAT_SIMPLE] = "FORMAT_SIMPLE",
+ [FORMAT_WITH_SPEC] = "FORMAT_WITH_SPEC",
+ [FOR_ITER] = "FOR_ITER",
+ [FOR_ITER_GEN] = "FOR_ITER_GEN",
+ [FOR_ITER_LIST] = "FOR_ITER_LIST",
+ [FOR_ITER_RANGE] = "FOR_ITER_RANGE",
+ [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE",
+ [GET_AITER] = "GET_AITER",
+ [GET_ANEXT] = "GET_ANEXT",
+ [GET_AWAITABLE] = "GET_AWAITABLE",
+ [GET_ITER] = "GET_ITER",
+ [GET_LEN] = "GET_LEN",
+ [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER",
+ [IMPORT_FROM] = "IMPORT_FROM",
+ [IMPORT_NAME] = "IMPORT_NAME",
+ [INSTRUMENTED_CALL] = "INSTRUMENTED_CALL",
+ [INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX",
+ [INSTRUMENTED_CALL_KW] = "INSTRUMENTED_CALL_KW",
+ [INSTRUMENTED_END_FOR] = "INSTRUMENTED_END_FOR",
+ [INSTRUMENTED_END_SEND] = "INSTRUMENTED_END_SEND",
+ [INSTRUMENTED_FOR_ITER] = "INSTRUMENTED_FOR_ITER",
+ [INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION",
+ [INSTRUMENTED_JUMP_BACKWARD] = "INSTRUMENTED_JUMP_BACKWARD",
+ [INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD",
+ [INSTRUMENTED_LINE] = "INSTRUMENTED_LINE",
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE",
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = "INSTRUMENTED_POP_JUMP_IF_NONE",
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE",
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = "INSTRUMENTED_POP_JUMP_IF_TRUE",
+ [INSTRUMENTED_RESUME] = "INSTRUMENTED_RESUME",
+ [INSTRUMENTED_RETURN_CONST] = "INSTRUMENTED_RETURN_CONST",
+ [INSTRUMENTED_RETURN_VALUE] = "INSTRUMENTED_RETURN_VALUE",
+ [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE",
+ [INTERPRETER_EXIT] = "INTERPRETER_EXIT",
+ [IS_OP] = "IS_OP",
+ [JUMP] = "JUMP",
+ [JUMP_BACKWARD] = "JUMP_BACKWARD",
+ [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT",
+ [JUMP_FORWARD] = "JUMP_FORWARD",
+ [JUMP_NO_INTERRUPT] = "JUMP_NO_INTERRUPT",
+ [LIST_APPEND] = "LIST_APPEND",
+ [LIST_EXTEND] = "LIST_EXTEND",
+ [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR",
+ [LOAD_ATTR] = "LOAD_ATTR",
+ [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
+ [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
+ [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
+ [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
+ [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
+ [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
+ [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
+ [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
+ [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
+ [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY",
+ [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT",
+ [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT",
+ [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS",
+ [LOAD_CLOSURE] = "LOAD_CLOSURE",
+ [LOAD_CONST] = "LOAD_CONST",
+ [LOAD_DEREF] = "LOAD_DEREF",
+ [LOAD_FAST] = "LOAD_FAST",
+ [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR",
+ [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK",
+ [LOAD_FAST_LOAD_FAST] = "LOAD_FAST_LOAD_FAST",
+ [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF",
+ [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS",
+ [LOAD_GLOBAL] = "LOAD_GLOBAL",
+ [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
+ [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
+ [LOAD_LOCALS] = "LOAD_LOCALS",
+ [LOAD_METHOD] = "LOAD_METHOD",
+ [LOAD_NAME] = "LOAD_NAME",
+ [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR",
+ [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR",
+ [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
+ [LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD",
+ [LOAD_ZERO_SUPER_ATTR] = "LOAD_ZERO_SUPER_ATTR",
+ [LOAD_ZERO_SUPER_METHOD] = "LOAD_ZERO_SUPER_METHOD",
+ [MAKE_CELL] = "MAKE_CELL",
+ [MAKE_FUNCTION] = "MAKE_FUNCTION",
+ [MAP_ADD] = "MAP_ADD",
+ [MATCH_CLASS] = "MATCH_CLASS",
+ [MATCH_KEYS] = "MATCH_KEYS",
+ [MATCH_MAPPING] = "MATCH_MAPPING",
+ [MATCH_SEQUENCE] = "MATCH_SEQUENCE",
+ [NOP] = "NOP",
+ [POP_BLOCK] = "POP_BLOCK",
+ [POP_EXCEPT] = "POP_EXCEPT",
+ [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
+ [POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE",
+ [POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE",
+ [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
+ [POP_TOP] = "POP_TOP",
+ [PUSH_EXC_INFO] = "PUSH_EXC_INFO",
+ [PUSH_NULL] = "PUSH_NULL",
+ [RAISE_VARARGS] = "RAISE_VARARGS",
+ [RERAISE] = "RERAISE",
+ [RESERVED] = "RESERVED",
+ [RESUME] = "RESUME",
+ [RESUME_CHECK] = "RESUME_CHECK",
+ [RETURN_CONST] = "RETURN_CONST",
+ [RETURN_GENERATOR] = "RETURN_GENERATOR",
+ [RETURN_VALUE] = "RETURN_VALUE",
+ [SEND] = "SEND",
+ [SEND_GEN] = "SEND_GEN",
+ [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
+ [SETUP_CLEANUP] = "SETUP_CLEANUP",
+ [SETUP_FINALLY] = "SETUP_FINALLY",
+ [SETUP_WITH] = "SETUP_WITH",
+ [SET_ADD] = "SET_ADD",
+ [SET_FUNCTION_ATTRIBUTE] = "SET_FUNCTION_ATTRIBUTE",
+ [SET_UPDATE] = "SET_UPDATE",
+ [STORE_ATTR] = "STORE_ATTR",
+ [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
+ [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
+ [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
+ [STORE_DEREF] = "STORE_DEREF",
+ [STORE_FAST] = "STORE_FAST",
+ [STORE_FAST_LOAD_FAST] = "STORE_FAST_LOAD_FAST",
+ [STORE_FAST_MAYBE_NULL] = "STORE_FAST_MAYBE_NULL",
+ [STORE_FAST_STORE_FAST] = "STORE_FAST_STORE_FAST",
+ [STORE_GLOBAL] = "STORE_GLOBAL",
+ [STORE_NAME] = "STORE_NAME",
+ [STORE_SLICE] = "STORE_SLICE",
+ [STORE_SUBSCR] = "STORE_SUBSCR",
+ [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
+ [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT",
+ [SWAP] = "SWAP",
+ [TO_BOOL] = "TO_BOOL",
+ [TO_BOOL_ALWAYS_TRUE] = "TO_BOOL_ALWAYS_TRUE",
+ [TO_BOOL_BOOL] = "TO_BOOL_BOOL",
+ [TO_BOOL_INT] = "TO_BOOL_INT",
+ [TO_BOOL_LIST] = "TO_BOOL_LIST",
+ [TO_BOOL_NONE] = "TO_BOOL_NONE",
+ [TO_BOOL_STR] = "TO_BOOL_STR",
+ [UNARY_INVERT] = "UNARY_INVERT",
+ [UNARY_NEGATIVE] = "UNARY_NEGATIVE",
+ [UNARY_NOT] = "UNARY_NOT",
+ [UNPACK_EX] = "UNPACK_EX",
+ [UNPACK_SEQUENCE] = "UNPACK_SEQUENCE",
+ [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST",
+ [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE",
+ [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
+ [WITH_EXCEPT_START] = "WITH_EXCEPT_START",
+ [YIELD_VALUE] = "YIELD_VALUE",
+};
+#endif
+
+extern const uint8_t _PyOpcode_Caches[256];
+#ifdef NEED_OPCODE_METADATA
+const uint8_t _PyOpcode_Caches[256] = {
+ [JUMP_BACKWARD] = 1,
+ [TO_BOOL] = 3,
+ [BINARY_SUBSCR] = 1,
+ [STORE_SUBSCR] = 1,
+ [SEND] = 1,
+ [UNPACK_SEQUENCE] = 1,
+ [STORE_ATTR] = 4,
+ [LOAD_GLOBAL] = 4,
+ [LOAD_SUPER_ATTR] = 1,
+ [LOAD_ATTR] = 9,
+ [COMPARE_OP] = 1,
+ [CONTAINS_OP] = 1,
+ [POP_JUMP_IF_TRUE] = 1,
+ [POP_JUMP_IF_FALSE] = 1,
+ [POP_JUMP_IF_NONE] = 1,
+ [POP_JUMP_IF_NOT_NONE] = 1,
+ [FOR_ITER] = 1,
+ [CALL] = 3,
+ [BINARY_OP] = 1,
+};
+#endif
+
+extern const uint8_t _PyOpcode_Deopt[256];
+#ifdef NEED_OPCODE_METADATA
+const uint8_t _PyOpcode_Deopt[256] = {
+ [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH,
+ [BEFORE_WITH] = BEFORE_WITH,
+ [BINARY_OP] = BINARY_OP,
+ [BINARY_OP_ADD_FLOAT] = BINARY_OP,
+ [BINARY_OP_ADD_INT] = BINARY_OP,
+ [BINARY_OP_ADD_UNICODE] = BINARY_OP,
+ [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP,
+ [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP,
+ [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
+ [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
+ [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
+ [BINARY_SLICE] = BINARY_SLICE,
+ [BINARY_SUBSCR] = BINARY_SUBSCR,
+ [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
+ [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
+ [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
+ [BINARY_SUBSCR_STR_INT] = BINARY_SUBSCR,
+ [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
+ [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
+ [BUILD_LIST] = BUILD_LIST,
+ [BUILD_MAP] = BUILD_MAP,
+ [BUILD_SET] = BUILD_SET,
+ [BUILD_SLICE] = BUILD_SLICE,
+ [BUILD_STRING] = BUILD_STRING,
+ [BUILD_TUPLE] = BUILD_TUPLE,
+ [CACHE] = CACHE,
+ [CALL] = CALL,
+ [CALL_ALLOC_AND_ENTER_INIT] = CALL,
+ [CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
+ [CALL_BOUND_METHOD_GENERAL] = CALL,
+ [CALL_BUILTIN_CLASS] = CALL,
+ [CALL_BUILTIN_FAST] = CALL,
+ [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
+ [CALL_BUILTIN_O] = CALL,
+ [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
+ [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
+ [CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
+ [CALL_ISINSTANCE] = CALL,
+ [CALL_KW] = CALL_KW,
+ [CALL_LEN] = CALL,
+ [CALL_LIST_APPEND] = CALL,
+ [CALL_METHOD_DESCRIPTOR_FAST] = CALL,
+ [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
+ [CALL_METHOD_DESCRIPTOR_NOARGS] = CALL,
+ [CALL_METHOD_DESCRIPTOR_O] = CALL,
+ [CALL_NON_PY_GENERAL] = CALL,
+ [CALL_PY_EXACT_ARGS] = CALL,
+ [CALL_PY_GENERAL] = CALL,
+ [CALL_STR_1] = CALL,
+ [CALL_TUPLE_1] = CALL,
+ [CALL_TYPE_1] = CALL,
+ [CHECK_EG_MATCH] = CHECK_EG_MATCH,
+ [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
+ [CLEANUP_THROW] = CLEANUP_THROW,
+ [COMPARE_OP] = COMPARE_OP,
+ [COMPARE_OP_FLOAT] = COMPARE_OP,
+ [COMPARE_OP_INT] = COMPARE_OP,
+ [COMPARE_OP_STR] = COMPARE_OP,
+ [CONTAINS_OP] = CONTAINS_OP,
+ [CONTAINS_OP_DICT] = CONTAINS_OP,
+ [CONTAINS_OP_SET] = CONTAINS_OP,
+ [CONVERT_VALUE] = CONVERT_VALUE,
+ [COPY] = COPY,
+ [COPY_FREE_VARS] = COPY_FREE_VARS,
+ [DELETE_ATTR] = DELETE_ATTR,
+ [DELETE_DEREF] = DELETE_DEREF,
+ [DELETE_FAST] = DELETE_FAST,
+ [DELETE_GLOBAL] = DELETE_GLOBAL,
+ [DELETE_NAME] = DELETE_NAME,
+ [DELETE_SUBSCR] = DELETE_SUBSCR,
+ [DICT_MERGE] = DICT_MERGE,
+ [DICT_UPDATE] = DICT_UPDATE,
+ [END_ASYNC_FOR] = END_ASYNC_FOR,
+ [END_FOR] = END_FOR,
+ [END_SEND] = END_SEND,
+ [ENTER_EXECUTOR] = ENTER_EXECUTOR,
+ [EXIT_INIT_CHECK] = EXIT_INIT_CHECK,
+ [EXTENDED_ARG] = EXTENDED_ARG,
+ [FORMAT_SIMPLE] = FORMAT_SIMPLE,
+ [FORMAT_WITH_SPEC] = FORMAT_WITH_SPEC,
+ [FOR_ITER] = FOR_ITER,
+ [FOR_ITER_GEN] = FOR_ITER,
+ [FOR_ITER_LIST] = FOR_ITER,
+ [FOR_ITER_RANGE] = FOR_ITER,
+ [FOR_ITER_TUPLE] = FOR_ITER,
+ [GET_AITER] = GET_AITER,
+ [GET_ANEXT] = GET_ANEXT,
+ [GET_AWAITABLE] = GET_AWAITABLE,
+ [GET_ITER] = GET_ITER,
+ [GET_LEN] = GET_LEN,
+ [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
+ [IMPORT_FROM] = IMPORT_FROM,
+ [IMPORT_NAME] = IMPORT_NAME,
+ [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
+ [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
+ [INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW,
+ [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
+ [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
+ [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
+ [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
+ [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
+ [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
+ [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
+ [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME,
+ [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
+ [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
+ [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
+ [INTERPRETER_EXIT] = INTERPRETER_EXIT,
+ [IS_OP] = IS_OP,
+ [JUMP_BACKWARD] = JUMP_BACKWARD,
+ [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
+ [JUMP_FORWARD] = JUMP_FORWARD,
+ [LIST_APPEND] = LIST_APPEND,
+ [LIST_EXTEND] = LIST_EXTEND,
+ [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
+ [LOAD_ATTR] = LOAD_ATTR,
+ [LOAD_ATTR_CLASS] = LOAD_ATTR,
+ [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
+ [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
+ [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
+ [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
+ [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
+ [LOAD_ATTR_MODULE] = LOAD_ATTR,
+ [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR,
+ [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR,
+ [LOAD_ATTR_PROPERTY] = LOAD_ATTR,
+ [LOAD_ATTR_SLOT] = LOAD_ATTR,
+ [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
+ [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
+ [LOAD_CONST] = LOAD_CONST,
+ [LOAD_DEREF] = LOAD_DEREF,
+ [LOAD_FAST] = LOAD_FAST,
+ [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR,
+ [LOAD_FAST_CHECK] = LOAD_FAST_CHECK,
+ [LOAD_FAST_LOAD_FAST] = LOAD_FAST_LOAD_FAST,
+ [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF,
+ [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS,
+ [LOAD_GLOBAL] = LOAD_GLOBAL,
+ [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
+ [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
+ [LOAD_LOCALS] = LOAD_LOCALS,
+ [LOAD_NAME] = LOAD_NAME,
+ [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
+ [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
+ [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
+ [MAKE_CELL] = MAKE_CELL,
+ [MAKE_FUNCTION] = MAKE_FUNCTION,
+ [MAP_ADD] = MAP_ADD,
+ [MATCH_CLASS] = MATCH_CLASS,
+ [MATCH_KEYS] = MATCH_KEYS,
+ [MATCH_MAPPING] = MATCH_MAPPING,
+ [MATCH_SEQUENCE] = MATCH_SEQUENCE,
+ [NOP] = NOP,
+ [POP_EXCEPT] = POP_EXCEPT,
+ [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
+ [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
+ [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
+ [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
+ [POP_TOP] = POP_TOP,
+ [PUSH_EXC_INFO] = PUSH_EXC_INFO,
+ [PUSH_NULL] = PUSH_NULL,
+ [RAISE_VARARGS] = RAISE_VARARGS,
+ [RERAISE] = RERAISE,
+ [RESERVED] = RESERVED,
+ [RESUME] = RESUME,
+ [RESUME_CHECK] = RESUME,
+ [RETURN_CONST] = RETURN_CONST,
+ [RETURN_GENERATOR] = RETURN_GENERATOR,
+ [RETURN_VALUE] = RETURN_VALUE,
+ [SEND] = SEND,
+ [SEND_GEN] = SEND,
+ [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
+ [SET_ADD] = SET_ADD,
+ [SET_FUNCTION_ATTRIBUTE] = SET_FUNCTION_ATTRIBUTE,
+ [SET_UPDATE] = SET_UPDATE,
+ [STORE_ATTR] = STORE_ATTR,
+ [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
+ [STORE_ATTR_SLOT] = STORE_ATTR,
+ [STORE_ATTR_WITH_HINT] = STORE_ATTR,
+ [STORE_DEREF] = STORE_DEREF,
+ [STORE_FAST] = STORE_FAST,
+ [STORE_FAST_LOAD_FAST] = STORE_FAST_LOAD_FAST,
+ [STORE_FAST_STORE_FAST] = STORE_FAST_STORE_FAST,
+ [STORE_GLOBAL] = STORE_GLOBAL,
+ [STORE_NAME] = STORE_NAME,
+ [STORE_SLICE] = STORE_SLICE,
+ [STORE_SUBSCR] = STORE_SUBSCR,
+ [STORE_SUBSCR_DICT] = STORE_SUBSCR,
+ [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR,
+ [SWAP] = SWAP,
+ [TO_BOOL] = TO_BOOL,
+ [TO_BOOL_ALWAYS_TRUE] = TO_BOOL,
+ [TO_BOOL_BOOL] = TO_BOOL,
+ [TO_BOOL_INT] = TO_BOOL,
+ [TO_BOOL_LIST] = TO_BOOL,
+ [TO_BOOL_NONE] = TO_BOOL,
+ [TO_BOOL_STR] = TO_BOOL,
+ [UNARY_INVERT] = UNARY_INVERT,
+ [UNARY_NEGATIVE] = UNARY_NEGATIVE,
+ [UNARY_NOT] = UNARY_NOT,
+ [UNPACK_EX] = UNPACK_EX,
+ [UNPACK_SEQUENCE] = UNPACK_SEQUENCE,
+ [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE,
+ [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE,
+ [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
+ [WITH_EXCEPT_START] = WITH_EXCEPT_START,
+ [YIELD_VALUE] = YIELD_VALUE,
+};
+
+#endif // NEED_OPCODE_METADATA
+
+#define EXTRA_CASES \
+ case 119: \
+ case 120: \
+ case 121: \
+ case 122: \
+ case 123: \
+ case 124: \
+ case 125: \
+ case 126: \
+ case 127: \
+ case 128: \
+ case 129: \
+ case 130: \
+ case 131: \
+ case 132: \
+ case 133: \
+ case 134: \
+ case 135: \
+ case 136: \
+ case 137: \
+ case 138: \
+ case 139: \
+ case 140: \
+ case 141: \
+ case 142: \
+ case 143: \
+ case 144: \
+ case 145: \
+ case 146: \
+ case 147: \
+ case 148: \
+ case 223: \
+ case 224: \
+ case 225: \
+ case 226: \
+ case 227: \
+ case 228: \
+ case 229: \
+ case 230: \
+ case 231: \
+ case 232: \
+ case 233: \
+ case 234: \
+ case 235: \
+ case 255: \
+ ;
+struct pseudo_targets {
+ uint8_t targets[3];
+};
+extern const struct pseudo_targets _PyOpcode_PseudoTargets[12];
+#ifdef NEED_OPCODE_METADATA
+const struct pseudo_targets _PyOpcode_PseudoTargets[12] = {
+ [LOAD_CLOSURE-256] = { { LOAD_FAST, 0, 0 } },
+ [STORE_FAST_MAYBE_NULL-256] = { { STORE_FAST, 0, 0 } },
+ [LOAD_SUPER_METHOD-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+ [LOAD_ZERO_SUPER_METHOD-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+ [LOAD_ZERO_SUPER_ATTR-256] = { { LOAD_SUPER_ATTR, 0, 0 } },
+ [LOAD_METHOD-256] = { { LOAD_ATTR, 0, 0 } },
+ [JUMP-256] = { { JUMP_FORWARD, JUMP_BACKWARD, 0 } },
+ [JUMP_NO_INTERRUPT-256] = { { JUMP_FORWARD, JUMP_BACKWARD_NO_INTERRUPT, 0 } },
+ [SETUP_FINALLY-256] = { { NOP, 0, 0 } },
+ [SETUP_CLEANUP-256] = { { NOP, 0, 0 } },
+ [SETUP_WITH-256] = { { NOP, 0, 0 } },
+ [POP_BLOCK-256] = { { NOP, 0, 0 } },
+};
+
+#endif // NEED_OPCODE_METADATA
+static inline bool
+is_pseudo_target(int pseudo, int target) {
+ if (pseudo < 256 || pseudo >= 268) {
+ return false;
+ }
+ for (int i = 0; _PyOpcode_PseudoTargets[pseudo-256].targets[i]; i++) {
+ if (_PyOpcode_PseudoTargets[pseudo-256].targets[i] == target) return true;
+ }
+ return false;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CORE_OPCODE_METADATA_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_opcode_utils.h b/contrib/tools/python3/Include/internal/pycore_opcode_utils.h
index 1d5ff988290..208bfb2f753 100644
--- a/contrib/tools/python3/Include/internal/pycore_opcode_utils.h
+++ b/contrib/tools/python3/Include/internal/pycore_opcode_utils.h
@@ -8,17 +8,13 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_opcode.h" // _PyOpcode_Jump
-
+#include "opcode_ids.h"
#define MAX_REAL_OPCODE 254
#define IS_WITHIN_OPCODE_RANGE(opcode) \
(((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \
- IS_PSEUDO_OPCODE(opcode))
-
-#define IS_JUMP_OPCODE(opcode) \
- is_bit_set_in_table(_PyOpcode_Jump, opcode)
+ IS_PSEUDO_INSTR(opcode))
#define IS_BLOCK_PUSH_OPCODE(opcode) \
((opcode) == SETUP_FINALLY || \
@@ -26,11 +22,11 @@ extern "C" {
(opcode) == SETUP_CLEANUP)
#define HAS_TARGET(opcode) \
- (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode))
+ (OPCODE_HAS_JUMP(opcode) || IS_BLOCK_PUSH_OPCODE(opcode))
/* opcodes that must be last in the basicblock */
#define IS_TERMINATOR_OPCODE(opcode) \
- (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode))
+ (OPCODE_HAS_JUMP(opcode) || IS_SCOPE_EXIT_OPCODE(opcode))
/* opcodes which are not emitted in codegen stage, only by the assembler */
#define IS_ASSEMBLER_OPCODE(opcode) \
@@ -55,36 +51,21 @@ extern "C" {
(opcode) == RAISE_VARARGS || \
(opcode) == RERAISE)
-#define IS_SUPERINSTRUCTION_OPCODE(opcode) \
- ((opcode) == LOAD_FAST__LOAD_FAST || \
- (opcode) == LOAD_FAST__LOAD_CONST || \
- (opcode) == LOAD_CONST__LOAD_FAST || \
- (opcode) == STORE_FAST__LOAD_FAST || \
- (opcode) == STORE_FAST__STORE_FAST)
-
-#define LOG_BITS_PER_INT 5
-#define MASK_LOW_LOG_BITS 31
-
-static inline int
-is_bit_set_in_table(const uint32_t *table, int bitindex) {
- /* Is the relevant bit set in the relevant word? */
- /* 512 bits fit into 9 32-bits words.
- * Word is indexed by (bitindex>>ln(size of int in bits)).
- * Bit within word is the low bits of bitindex.
- */
- if (bitindex >= 0 && bitindex < 512) {
- uint32_t word = table[bitindex >> LOG_BITS_PER_INT];
- return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1;
- }
- else {
- return 0;
- }
-}
+/* Flags used in the oparg for MAKE_FUNCTION */
+#define MAKE_FUNCTION_DEFAULTS 0x01
+#define MAKE_FUNCTION_KWDEFAULTS 0x02
+#define MAKE_FUNCTION_ANNOTATIONS 0x04
+#define MAKE_FUNCTION_CLOSURE 0x08
-#undef LOG_BITS_PER_INT
-#undef MASK_LOW_LOG_BITS
+/* Values used in the oparg for RESUME */
+#define RESUME_AT_FUNC_START 0
+#define RESUME_AFTER_YIELD 1
+#define RESUME_AFTER_YIELD_FROM 2
+#define RESUME_AFTER_AWAIT 3
+#define RESUME_OPARG_LOCATION_MASK 0x3
+#define RESUME_OPARG_DEPTH1_MASK 0x4
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_optimizer.h b/contrib/tools/python3/Include/internal/pycore_optimizer.h
new file mode 100644
index 00000000000..49aa67c6f3c
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_optimizer.h
@@ -0,0 +1,272 @@
+#ifndef Py_INTERNAL_OPTIMIZER_H
+#define Py_INTERNAL_OPTIMIZER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_uop_ids.h"
+#include <stdbool.h>
+
+
+typedef struct _PyExecutorLinkListNode {
+ struct _PyExecutorObject *next;
+ struct _PyExecutorObject *previous;
+} _PyExecutorLinkListNode;
+
+
+/* Bloom filter with m = 256
+ * https://en.wikipedia.org/wiki/Bloom_filter */
+#define BLOOM_FILTER_WORDS 8
+
+typedef struct _bloom_filter {
+ uint32_t bits[BLOOM_FILTER_WORDS];
+} _PyBloomFilter;
+
+typedef struct {
+ uint8_t opcode;
+ uint8_t oparg;
+ uint8_t valid;
+ uint8_t linked;
+ int index; // Index of ENTER_EXECUTOR (if code isn't NULL, below).
+ _PyBloomFilter bloom;
+ _PyExecutorLinkListNode links;
+ PyCodeObject *code; // Weak (NULL if no corresponding ENTER_EXECUTOR).
+} _PyVMData;
+
+#define UOP_FORMAT_TARGET 0
+#define UOP_FORMAT_EXIT 1
+#define UOP_FORMAT_JUMP 2
+#define UOP_FORMAT_UNUSED 3
+
+/* Depending on the format,
+ * the 32 bits between the oparg and operand are:
+ * UOP_FORMAT_TARGET:
+ * uint32_t target;
+ * UOP_FORMAT_EXIT
+ * uint16_t exit_index;
+ * uint16_t error_target;
+ * UOP_FORMAT_JUMP
+ * uint16_t jump_target;
+ * uint16_t error_target;
+ */
+typedef struct {
+ uint16_t opcode:14;
+ uint16_t format:2;
+ uint16_t oparg;
+ union {
+ uint32_t target;
+ struct {
+ union {
+ uint16_t exit_index;
+ uint16_t jump_target;
+ };
+ uint16_t error_target;
+ };
+ };
+ uint64_t operand; // A cache entry
+} _PyUOpInstruction;
+
+static inline uint32_t uop_get_target(const _PyUOpInstruction *inst)
+{
+ assert(inst->format == UOP_FORMAT_TARGET);
+ return inst->target;
+}
+
+static inline uint16_t uop_get_exit_index(const _PyUOpInstruction *inst)
+{
+ assert(inst->format == UOP_FORMAT_EXIT);
+ return inst->exit_index;
+}
+
+static inline uint16_t uop_get_jump_target(const _PyUOpInstruction *inst)
+{
+ assert(inst->format == UOP_FORMAT_JUMP);
+ return inst->jump_target;
+}
+
+static inline uint16_t uop_get_error_target(const _PyUOpInstruction *inst)
+{
+ assert(inst->format != UOP_FORMAT_TARGET);
+ return inst->error_target;
+}
+
+typedef struct _exit_data {
+ uint32_t target;
+ _Py_BackoffCounter temperature;
+ const struct _PyExecutorObject *executor;
+} _PyExitData;
+
+typedef struct _PyExecutorObject {
+ PyObject_VAR_HEAD
+ const _PyUOpInstruction *trace;
+ _PyVMData vm_data; /* Used by the VM, but opaque to the optimizer */
+ uint32_t exit_count;
+ uint32_t code_size;
+ size_t jit_size;
+ void *jit_code;
+ void *jit_side_entry;
+ _PyExitData exits[1];
+} _PyExecutorObject;
+
+typedef struct _PyOptimizerObject _PyOptimizerObject;
+
+/* Should return > 0 if a new executor is created. O if no executor is produced and < 0 if an error occurred. */
+typedef int (*optimize_func)(
+ _PyOptimizerObject* self, struct _PyInterpreterFrame *frame,
+ _Py_CODEUNIT *instr, _PyExecutorObject **exec_ptr,
+ int curr_stackentries);
+
+struct _PyOptimizerObject {
+ PyObject_HEAD
+ optimize_func optimize;
+ /* Data needed by the optimizer goes here, but is opaque to the VM */
+};
+
+/** Test support **/
+typedef struct {
+ _PyOptimizerObject base;
+ int64_t count;
+} _PyCounterOptimizerObject;
+
+_PyOptimizerObject *_Py_SetOptimizer(PyInterpreterState *interp, _PyOptimizerObject* optimizer);
+
+PyAPI_FUNC(int) _Py_SetTier2Optimizer(_PyOptimizerObject* optimizer);
+
+PyAPI_FUNC(_PyOptimizerObject *) _Py_GetOptimizer(void);
+
+PyAPI_FUNC(_PyExecutorObject *) _Py_GetExecutor(PyCodeObject *code, int offset);
+
+void _Py_ExecutorInit(_PyExecutorObject *, const _PyBloomFilter *);
+void _Py_ExecutorDetach(_PyExecutorObject *);
+void _Py_BloomFilter_Init(_PyBloomFilter *);
+void _Py_BloomFilter_Add(_PyBloomFilter *bloom, void *obj);
+PyAPI_FUNC(void) _Py_Executor_DependsOn(_PyExecutorObject *executor, void *obj);
+/* For testing */
+PyAPI_FUNC(PyObject *) _PyOptimizer_NewCounter(void);
+PyAPI_FUNC(PyObject *) _PyOptimizer_NewUOpOptimizer(void);
+
+#define _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS 3
+#define _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS 6
+
+#ifdef _Py_TIER2
+PyAPI_FUNC(void) _Py_Executors_InvalidateDependency(PyInterpreterState *interp, void *obj, int is_invalidation);
+PyAPI_FUNC(void) _Py_Executors_InvalidateAll(PyInterpreterState *interp, int is_invalidation);
+#else
+# define _Py_Executors_InvalidateDependency(A, B, C) ((void)0)
+# define _Py_Executors_InvalidateAll(A, B) ((void)0)
+#endif
+
+
+// This is the length of the trace we project initially.
+#define UOP_MAX_TRACE_LENGTH 800
+
+#define TRACE_STACK_SIZE 5
+
+int _Py_uop_analyze_and_optimize(struct _PyInterpreterFrame *frame,
+ _PyUOpInstruction *trace, int trace_len, int curr_stackentries,
+ _PyBloomFilter *dependencies);
+
+extern PyTypeObject _PyCounterExecutor_Type;
+extern PyTypeObject _PyCounterOptimizer_Type;
+extern PyTypeObject _PyDefaultOptimizer_Type;
+extern PyTypeObject _PyUOpExecutor_Type;
+extern PyTypeObject _PyUOpOptimizer_Type;
+
+/* Symbols */
+/* See explanation in optimizer_symbols.c */
+
+struct _Py_UopsSymbol {
+ int flags; // 0 bits: Top; 2 or more bits: Bottom
+ PyTypeObject *typ; // Borrowed reference
+ PyObject *const_val; // Owned reference (!)
+};
+
+// Holds locals, stack, locals, stack ... co_consts (in that order)
+#define MAX_ABSTRACT_INTERP_SIZE 4096
+
+#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * 5)
+
+// Need extras for root frame and for overflow frame (see TRACE_STACK_PUSH())
+#define MAX_ABSTRACT_FRAME_DEPTH (TRACE_STACK_SIZE + 2)
+
+typedef struct _Py_UopsSymbol _Py_UopsSymbol;
+
+struct _Py_UOpsAbstractFrame {
+ // Max stacklen
+ int stack_len;
+ int locals_len;
+
+ _Py_UopsSymbol **stack_pointer;
+ _Py_UopsSymbol **stack;
+ _Py_UopsSymbol **locals;
+};
+
+typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
+
+typedef struct ty_arena {
+ int ty_curr_number;
+ int ty_max_number;
+ _Py_UopsSymbol arena[TY_ARENA_SIZE];
+} ty_arena;
+
+struct _Py_UOpsContext {
+ PyObject_HEAD
+ // The current "executing" frame.
+ _Py_UOpsAbstractFrame *frame;
+ _Py_UOpsAbstractFrame frames[MAX_ABSTRACT_FRAME_DEPTH];
+ int curr_frame_depth;
+
+ // Arena for the symbolic types.
+ ty_arena t_arena;
+
+ _Py_UopsSymbol **n_consumed;
+ _Py_UopsSymbol **limit;
+ _Py_UopsSymbol *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
+};
+
+typedef struct _Py_UOpsContext _Py_UOpsContext;
+
+extern bool _Py_uop_sym_is_null(_Py_UopsSymbol *sym);
+extern bool _Py_uop_sym_is_not_null(_Py_UopsSymbol *sym);
+extern bool _Py_uop_sym_is_const(_Py_UopsSymbol *sym);
+extern PyObject *_Py_uop_sym_get_const(_Py_UopsSymbol *sym);
+extern _Py_UopsSymbol *_Py_uop_sym_new_unknown(_Py_UOpsContext *ctx);
+extern _Py_UopsSymbol *_Py_uop_sym_new_not_null(_Py_UOpsContext *ctx);
+extern _Py_UopsSymbol *_Py_uop_sym_new_type(
+ _Py_UOpsContext *ctx, PyTypeObject *typ);
+extern _Py_UopsSymbol *_Py_uop_sym_new_const(_Py_UOpsContext *ctx, PyObject *const_val);
+extern _Py_UopsSymbol *_Py_uop_sym_new_null(_Py_UOpsContext *ctx);
+extern bool _Py_uop_sym_has_type(_Py_UopsSymbol *sym);
+extern bool _Py_uop_sym_matches_type(_Py_UopsSymbol *sym, PyTypeObject *typ);
+extern bool _Py_uop_sym_set_null(_Py_UopsSymbol *sym);
+extern bool _Py_uop_sym_set_non_null(_Py_UopsSymbol *sym);
+extern bool _Py_uop_sym_set_type(_Py_UopsSymbol *sym, PyTypeObject *typ);
+extern bool _Py_uop_sym_set_const(_Py_UopsSymbol *sym, PyObject *const_val);
+extern bool _Py_uop_sym_is_bottom(_Py_UopsSymbol *sym);
+extern int _Py_uop_sym_truthiness(_Py_UopsSymbol *sym);
+extern PyTypeObject *_Py_uop_sym_get_type(_Py_UopsSymbol *sym);
+
+
+extern int _Py_uop_abstractcontext_init(_Py_UOpsContext *ctx);
+extern void _Py_uop_abstractcontext_fini(_Py_UOpsContext *ctx);
+
+extern _Py_UOpsAbstractFrame *_Py_uop_frame_new(
+ _Py_UOpsContext *ctx,
+ PyCodeObject *co,
+ int curr_stackentries,
+ _Py_UopsSymbol **args,
+ int arg_len);
+extern int _Py_uop_frame_pop(_Py_UOpsContext *ctx);
+
+PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored);
+
+PyAPI_FUNC(int) _PyOptimizer_Optimize(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *start, PyObject **stack_pointer, _PyExecutorObject **exec_ptr);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_OPTIMIZER_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_parking_lot.h b/contrib/tools/python3/Include/internal/pycore_parking_lot.h
new file mode 100644
index 00000000000..8c9260e2636
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_parking_lot.h
@@ -0,0 +1,97 @@
+// ParkingLot is an internal API for building efficient synchronization
+// primitives like mutexes and events.
+//
+// The API and name is inspired by WebKit's WTF::ParkingLot, which in turn
+// is inspired Linux's futex API.
+// See https://webkit.org/blog/6161/locking-in-webkit/.
+//
+// The core functionality is an atomic "compare-and-sleep" operation along with
+// an atomic "wake-up" operation.
+
+#ifndef Py_INTERNAL_PARKING_LOT_H
+#define Py_INTERNAL_PARKING_LOT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+enum {
+ // The thread was unparked by another thread.
+ Py_PARK_OK = 0,
+
+ // The value of `address` did not match `expected`.
+ Py_PARK_AGAIN = -1,
+
+ // The thread was unparked due to a timeout.
+ Py_PARK_TIMEOUT = -2,
+
+ // The thread was interrupted by a signal.
+ Py_PARK_INTR = -3,
+};
+
+// Checks that `*address == *expected` and puts the thread to sleep until an
+// unpark operation is called on the same `address`. Otherwise, the function
+// returns `Py_PARK_AGAIN`. The comparison behaves like memcmp, but is
+// performed atomically with respect to unpark operations.
+//
+// The `address_size` argument is the size of the data pointed to by the
+// `address` and `expected` pointers (i.e., sizeof(*address)). It must be
+// 1, 2, 4, or 8.
+//
+// The `timeout_ns` argument specifies the maximum amount of time to wait, with
+// -1 indicating an infinite wait.
+//
+// `park_arg`, which can be NULL, is passed to the unpark operation.
+//
+// If `detach` is true, then the thread will detach/release the GIL while
+// waiting.
+//
+// Example usage:
+//
+// if (_Py_atomic_compare_exchange_uint8(address, &expected, new_value)) {
+// int res = _PyParkingLot_Park(address, &new_value, sizeof(*address),
+// timeout_ns, NULL, 1);
+// ...
+// }
+PyAPI_FUNC(int)
+_PyParkingLot_Park(const void *address, const void *expected,
+ size_t address_size, PyTime_t timeout_ns,
+ void *park_arg, int detach);
+
+// Callback for _PyParkingLot_Unpark:
+//
+// `arg` is the data of the same name provided to the _PyParkingLot_Unpark()
+// call.
+// `park_arg` is the data provided to _PyParkingLot_Park() call or NULL if
+// no waiting thread was found.
+// `has_more_waiters` is true if there are more threads waiting on the same
+// address. May be true in cases where threads are waiting on a different
+// address that map to the same internal bucket.
+typedef void _Py_unpark_fn_t(void *arg, void *park_arg, int has_more_waiters);
+
+// Unparks a single thread waiting on `address`.
+//
+// Note that fn() is called regardless of whether a thread was unparked. If
+// no threads are waiting on `address` then the `park_arg` argument to fn()
+// will be NULL.
+//
+// Example usage:
+// void callback(void *arg, void *park_arg, int has_more_waiters);
+// _PyParkingLot_Unpark(address, &callback, arg);
+PyAPI_FUNC(void)
+_PyParkingLot_Unpark(const void *address, _Py_unpark_fn_t *fn, void *arg);
+
+// Unparks all threads waiting on `address`.
+PyAPI_FUNC(void) _PyParkingLot_UnparkAll(const void *address);
+
+// Resets the parking lot state after a fork. Forgets all parked threads.
+PyAPI_FUNC(void) _PyParkingLot_AfterFork(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_PARKING_LOT_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_parser.h b/contrib/tools/python3/Include/internal/pycore_parser.h
index dd51b92801a..b16084aaa15 100644
--- a/contrib/tools/python3/Include/internal/pycore_parser.h
+++ b/contrib/tools/python3/Include/internal/pycore_parser.h
@@ -21,6 +21,9 @@ extern "C" {
struct _parser_runtime_state {
#ifdef Py_DEBUG
long memo_statistics[_PYPEGEN_NSTATISTICS];
+#ifdef Py_GIL_DISABLED
+ PyMutex mutex;
+#endif
#else
int _not_used;
#endif
@@ -28,8 +31,10 @@ struct _parser_runtime_state {
};
_Py_DECLARE_STR(empty, "")
+#if defined(Py_DEBUG) && defined(Py_GIL_DISABLED)
#define _parser_runtime_state_INIT \
{ \
+ .mutex = {0}, \
.dummy_name = { \
.kind = Name_kind, \
.v.Name.id = &_Py_STR(empty), \
@@ -40,6 +45,20 @@ _Py_DECLARE_STR(empty, "")
.end_col_offset = 0, \
}, \
}
+#else
+#define _parser_runtime_state_INIT \
+ { \
+ .dummy_name = { \
+ .kind = Name_kind, \
+ .v.Name.id = &_Py_STR(empty), \
+ .v.Name.ctx = Load, \
+ .lineno = 1, \
+ .col_offset = 0, \
+ .end_lineno = 1, \
+ .end_col_offset = 0, \
+ }, \
+ }
+#endif
extern struct _mod* _PyParser_ASTFromString(
const char *str,
@@ -58,7 +77,17 @@ extern struct _mod* _PyParser_ASTFromFile(
PyCompilerFlags *flags,
int *errcode,
PyArena *arena);
-
+extern struct _mod* _PyParser_InteractiveASTFromFile(
+ FILE *fp,
+ PyObject *filename_ob,
+ const char *enc,
+ int mode,
+ const char *ps1,
+ const char *ps2,
+ PyCompilerFlags *flags,
+ int *errcode,
+ PyObject **interactive_src,
+ PyArena *arena);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_pathconfig.h b/contrib/tools/python3/Include/internal/pycore_pathconfig.h
index b8deaa0c3eb..a1ce1b19a00 100644
--- a/contrib/tools/python3/Include/internal/pycore_pathconfig.h
+++ b/contrib/tools/python3/Include/internal/pycore_pathconfig.h
@@ -8,7 +8,9 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(void) _PyPathConfig_ClearGlobal(void);
+
extern PyStatus _PyPathConfig_ReadGlobal(PyConfig *config);
extern PyStatus _PyPathConfig_UpdateGlobal(const PyConfig *config);
extern const wchar_t * _PyPathConfig_GetGlobalModuleSearchPath(void);
diff --git a/contrib/tools/python3/Include/internal/pycore_pyarena.h b/contrib/tools/python3/Include/internal/pycore_pyarena.h
index d78972a88ca..1f07479fb2c 100644
--- a/contrib/tools/python3/Include/internal/pycore_pyarena.h
+++ b/contrib/tools/python3/Include/internal/pycore_pyarena.h
@@ -1,5 +1,4 @@
-/* An arena-like memory interface for the compiler.
- */
+// An arena-like memory interface for the compiler.
#ifndef Py_INTERNAL_PYARENA_H
#define Py_INTERNAL_PYARENA_H
@@ -13,49 +12,54 @@ extern "C" {
typedef struct _arena PyArena;
-/* _PyArena_New() and _PyArena_Free() create a new arena and free it,
- respectively. Once an arena has been created, it can be used
- to allocate memory via _PyArena_Malloc(). Pointers to PyObject can
- also be registered with the arena via _PyArena_AddPyObject(), and the
- arena will ensure that the PyObjects stay alive at least until
- _PyArena_Free() is called. When an arena is freed, all the memory it
- allocated is freed, the arena releases internal references to registered
- PyObject*, and none of its pointers are valid.
- XXX (tim) What does "none of its pointers are valid" mean? Does it
- XXX mean that pointers previously obtained via _PyArena_Malloc() are
- XXX no longer valid? (That's clearly true, but not sure that's what
- XXX the text is trying to say.)
-
- _PyArena_New() returns an arena pointer. On error, it
- returns a negative number and sets an exception.
- XXX (tim): Not true. On error, _PyArena_New() actually returns NULL,
- XXX and looks like it may or may not set an exception (e.g., if the
- XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on
- XXX and an exception is set; OTOH, if the internal
- XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but
- XXX an exception is not set in that case).
-*/
+// _PyArena_New() and _PyArena_Free() create a new arena and free it,
+// respectively. Once an arena has been created, it can be used
+// to allocate memory via _PyArena_Malloc(). Pointers to PyObject can
+// also be registered with the arena via _PyArena_AddPyObject(), and the
+// arena will ensure that the PyObjects stay alive at least until
+// _PyArena_Free() is called. When an arena is freed, all the memory it
+// allocated is freed, the arena releases internal references to registered
+// PyObject*, and none of its pointers are valid.
+// XXX (tim) What does "none of its pointers are valid" mean? Does it
+// XXX mean that pointers previously obtained via _PyArena_Malloc() are
+// XXX no longer valid? (That's clearly true, but not sure that's what
+// XXX the text is trying to say.)
+//
+// _PyArena_New() returns an arena pointer. On error, it
+// returns a negative number and sets an exception.
+// XXX (tim): Not true. On error, _PyArena_New() actually returns NULL,
+// XXX and looks like it may or may not set an exception (e.g., if the
+// XXX internal PyList_New(0) returns NULL, _PyArena_New() passes that on
+// XXX and an exception is set; OTOH, if the internal
+// XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but
+// XXX an exception is not set in that case).
+//
+// Export for test_peg_generator
PyAPI_FUNC(PyArena*) _PyArena_New(void);
+
+// Export for test_peg_generator
PyAPI_FUNC(void) _PyArena_Free(PyArena *);
-/* Mostly like malloc(), return the address of a block of memory spanning
- * `size` bytes, or return NULL (without setting an exception) if enough
- * new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with
- * size=0 does not guarantee to return a unique pointer (the pointer
- * returned may equal one or more other pointers obtained from
- * _PyArena_Malloc()).
- * Note that pointers obtained via _PyArena_Malloc() must never be passed to
- * the system free() or realloc(), or to any of Python's similar memory-
- * management functions. _PyArena_Malloc()-obtained pointers remain valid
- * until _PyArena_Free(ar) is called, at which point all pointers obtained
- * from the arena `ar` become invalid simultaneously.
- */
+// Mostly like malloc(), return the address of a block of memory spanning
+// `size` bytes, or return NULL (without setting an exception) if enough
+// new memory can't be obtained. Unlike malloc(0), _PyArena_Malloc() with
+// size=0 does not guarantee to return a unique pointer (the pointer
+// returned may equal one or more other pointers obtained from
+// _PyArena_Malloc()).
+// Note that pointers obtained via _PyArena_Malloc() must never be passed to
+// the system free() or realloc(), or to any of Python's similar memory-
+// management functions. _PyArena_Malloc()-obtained pointers remain valid
+// until _PyArena_Free(ar) is called, at which point all pointers obtained
+// from the arena `ar` become invalid simultaneously.
+//
+// Export for test_peg_generator
PyAPI_FUNC(void*) _PyArena_Malloc(PyArena *, size_t size);
-/* This routine isn't a proper arena allocation routine. It takes
- * a PyObject* and records it so that it can be DECREFed when the
- * arena is freed.
- */
+// This routine isn't a proper arena allocation routine. It takes
+// a PyObject* and records it so that it can be DECREFed when the
+// arena is freed.
+//
+// Export for test_peg_generator
PyAPI_FUNC(int) _PyArena_AddPyObject(PyArena *, PyObject *);
#ifdef __cplusplus
diff --git a/contrib/tools/python3/Include/internal/pycore_pyatomic_ft_wrappers.h b/contrib/tools/python3/Include/internal/pycore_pyatomic_ft_wrappers.h
new file mode 100644
index 00000000000..d755d03a5fa
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_pyatomic_ft_wrappers.h
@@ -0,0 +1,165 @@
+// This header file provides wrappers around the atomic operations found in
+// `pyatomic.h` that are only atomic in free-threaded builds.
+//
+// These are intended to be used in places where atomics are required in
+// free-threaded builds, but not in the default build, and we don't want to
+// introduce the potential performance overhead of an atomic operation in the
+// default build.
+//
+// All usages of these macros should be replaced with unconditionally atomic or
+// non-atomic versions, and this file should be removed, once the dust settles
+// on free threading.
+#ifndef Py_ATOMIC_FT_WRAPPERS_H
+#define Py_ATOMIC_FT_WRAPPERS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#error "this header requires Py_BUILD_CORE define"
+#endif
+
+#ifdef Py_GIL_DISABLED
+#define FT_ATOMIC_LOAD_PTR(value) _Py_atomic_load_ptr(&value)
+#define FT_ATOMIC_STORE_PTR(value, new_value) _Py_atomic_store_ptr(&value, new_value)
+#define FT_ATOMIC_LOAD_SSIZE(value) _Py_atomic_load_ssize(&value)
+#define FT_ATOMIC_LOAD_SSIZE_ACQUIRE(value) \
+ _Py_atomic_load_ssize_acquire(&value)
+#define FT_ATOMIC_LOAD_SSIZE_RELAXED(value) \
+ _Py_atomic_load_ssize_relaxed(&value)
+#define FT_ATOMIC_STORE_PTR(value, new_value) \
+ _Py_atomic_store_ptr(&value, new_value)
+#define FT_ATOMIC_LOAD_PTR_ACQUIRE(value) \
+ _Py_atomic_load_ptr_acquire(&value)
+#define FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(value) \
+ _Py_atomic_load_uintptr_acquire(&value)
+#define FT_ATOMIC_LOAD_PTR_RELAXED(value) \
+ _Py_atomic_load_ptr_relaxed(&value)
+#define FT_ATOMIC_LOAD_UINT8(value) \
+ _Py_atomic_load_uint8(&value)
+#define FT_ATOMIC_STORE_UINT8(value, new_value) \
+ _Py_atomic_store_uint8(&value, new_value)
+#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) \
+ _Py_atomic_load_uint8_relaxed(&value)
+#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) \
+ _Py_atomic_load_uint16_relaxed(&value)
+#define FT_ATOMIC_LOAD_UINT32_RELAXED(value) \
+ _Py_atomic_load_uint32_relaxed(&value)
+#define FT_ATOMIC_LOAD_ULONG_RELAXED(value) \
+ _Py_atomic_load_ulong_relaxed(&value)
+#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) \
+ _Py_atomic_store_ptr_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) \
+ _Py_atomic_store_ptr_release(&value, new_value)
+#define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) \
+ _Py_atomic_store_uintptr_release(&value, new_value)
+#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) \
+ _Py_atomic_store_ssize_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) \
+ _Py_atomic_store_uint8_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) \
+ _Py_atomic_store_uint16_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_UINT32_RELAXED(value, new_value) \
+ _Py_atomic_store_uint32_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_CHAR_RELAXED(value, new_value) \
+ _Py_atomic_store_char_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_CHAR_RELAXED(value) \
+ _Py_atomic_load_char_relaxed(&value)
+#define FT_ATOMIC_STORE_UCHAR_RELAXED(value, new_value) \
+ _Py_atomic_store_uchar_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_UCHAR_RELAXED(value) \
+ _Py_atomic_load_uchar_relaxed(&value)
+#define FT_ATOMIC_STORE_SHORT_RELAXED(value, new_value) \
+ _Py_atomic_store_short_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_SHORT_RELAXED(value) \
+ _Py_atomic_load_short_relaxed(&value)
+#define FT_ATOMIC_STORE_USHORT_RELAXED(value, new_value) \
+ _Py_atomic_store_ushort_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_USHORT_RELAXED(value) \
+ _Py_atomic_load_ushort_relaxed(&value)
+#define FT_ATOMIC_STORE_INT_RELAXED(value, new_value) \
+ _Py_atomic_store_int_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_INT_RELAXED(value) \
+ _Py_atomic_load_int_relaxed(&value)
+#define FT_ATOMIC_STORE_UINT_RELAXED(value, new_value) \
+ _Py_atomic_store_uint_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_UINT_RELAXED(value) \
+ _Py_atomic_load_uint_relaxed(&value)
+#define FT_ATOMIC_STORE_LONG_RELAXED(value, new_value) \
+ _Py_atomic_store_long_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_LONG_RELAXED(value) \
+ _Py_atomic_load_long_relaxed(&value)
+#define FT_ATOMIC_STORE_ULONG_RELAXED(value, new_value) \
+ _Py_atomic_store_ulong_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) \
+ _Py_atomic_store_ssize_relaxed(&value, new_value)
+#define FT_ATOMIC_STORE_FLOAT_RELAXED(value, new_value) \
+ _Py_atomic_store_float_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_FLOAT_RELAXED(value) \
+ _Py_atomic_load_float_relaxed(&value)
+#define FT_ATOMIC_STORE_DOUBLE_RELAXED(value, new_value) \
+ _Py_atomic_store_double_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_DOUBLE_RELAXED(value) \
+ _Py_atomic_load_double_relaxed(&value)
+#define FT_ATOMIC_STORE_LLONG_RELAXED(value, new_value) \
+ _Py_atomic_store_llong_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_LLONG_RELAXED(value) \
+ _Py_atomic_load_llong_relaxed(&value)
+#define FT_ATOMIC_STORE_ULLONG_RELAXED(value, new_value) \
+ _Py_atomic_store_ullong_relaxed(&value, new_value)
+#define FT_ATOMIC_LOAD_ULLONG_RELAXED(value) \
+ _Py_atomic_load_ullong_relaxed(&value)
+
+#else
+#define FT_ATOMIC_LOAD_PTR(value) value
+#define FT_ATOMIC_STORE_PTR(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_SSIZE(value) value
+#define FT_ATOMIC_LOAD_SSIZE_ACQUIRE(value) value
+#define FT_ATOMIC_LOAD_SSIZE_RELAXED(value) value
+#define FT_ATOMIC_LOAD_PTR_ACQUIRE(value) value
+#define FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(value) value
+#define FT_ATOMIC_LOAD_PTR_RELAXED(value) value
+#define FT_ATOMIC_LOAD_UINT8(value) value
+#define FT_ATOMIC_STORE_UINT8(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value
+#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value
+#define FT_ATOMIC_LOAD_UINT32_RELAXED(value) value
+#define FT_ATOMIC_LOAD_ULONG_RELAXED(value) value
+#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_UINT16_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_UINT32_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_CHAR_RELAXED(value) value
+#define FT_ATOMIC_STORE_CHAR_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_UCHAR_RELAXED(value) value
+#define FT_ATOMIC_STORE_UCHAR_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_SHORT_RELAXED(value) value
+#define FT_ATOMIC_STORE_SHORT_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_USHORT_RELAXED(value) value
+#define FT_ATOMIC_STORE_USHORT_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_INT_RELAXED(value) value
+#define FT_ATOMIC_STORE_INT_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_UINT_RELAXED(value) value
+#define FT_ATOMIC_STORE_UINT_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_LONG_RELAXED(value) value
+#define FT_ATOMIC_STORE_LONG_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_ULONG_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_FLOAT_RELAXED(value) value
+#define FT_ATOMIC_STORE_FLOAT_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_DOUBLE_RELAXED(value) value
+#define FT_ATOMIC_STORE_DOUBLE_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_LLONG_RELAXED(value) value
+#define FT_ATOMIC_STORE_LLONG_RELAXED(value, new_value) value = new_value
+#define FT_ATOMIC_LOAD_ULLONG_RELAXED(value) value
+#define FT_ATOMIC_STORE_ULLONG_RELAXED(value, new_value) value = new_value
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_ATOMIC_FT_WRAPPERS_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_pybuffer.h b/contrib/tools/python3/Include/internal/pycore_pybuffer.h
new file mode 100644
index 00000000000..9439d2bd770
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_pybuffer.h
@@ -0,0 +1,21 @@
+#ifndef Py_INTERNAL_PYBUFFER_H
+#define Py_INTERNAL_PYBUFFER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+
+// Exported for the _interpchannels module.
+PyAPI_FUNC(int) _PyBuffer_ReleaseInInterpreter(
+ PyInterpreterState *interp, Py_buffer *view);
+PyAPI_FUNC(int) _PyBuffer_ReleaseInInterpreterAndRawFree(
+ PyInterpreterState *interp, Py_buffer *view);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_PYBUFFER_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_pyerrors.h b/contrib/tools/python3/Include/internal/pycore_pyerrors.h
index dab41405b92..615cc23ec93 100644
--- a/contrib/tools/python3/Include/internal/pycore_pyerrors.h
+++ b/contrib/tools/python3/Include/internal/pycore_pyerrors.h
@@ -9,6 +9,59 @@ extern "C" {
#endif
+/* Error handling definitions */
+
+extern _PyErr_StackItem* _PyErr_GetTopmostException(PyThreadState *tstate);
+extern PyObject* _PyErr_GetHandledException(PyThreadState *);
+extern void _PyErr_SetHandledException(PyThreadState *, PyObject *);
+extern void _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, PyObject **);
+
+// Export for '_testinternalcapi' shared extension
+PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *);
+
+
+// Like PyErr_Format(), but saves current exception as __context__ and
+// __cause__.
+// Export for '_sqlite3' shared extension.
+PyAPI_FUNC(PyObject*) _PyErr_FormatFromCause(
+ PyObject *exception,
+ const char *format, /* ASCII-encoded string */
+ ...
+ );
+
+extern int _PyException_AddNote(
+ PyObject *exc,
+ PyObject *note);
+
+extern int _PyErr_CheckSignals(void);
+
+/* Support for adding program text to SyntaxErrors */
+
+// Export for test_peg_generator
+PyAPI_FUNC(PyObject*) _PyErr_ProgramDecodedTextObject(
+ PyObject *filename,
+ int lineno,
+ const char* encoding);
+
+extern PyObject* _PyUnicodeTranslateError_Create(
+ PyObject *object,
+ Py_ssize_t start,
+ Py_ssize_t end,
+ const char *reason /* UTF-8 encoded string */
+ );
+
+extern void _Py_NO_RETURN _Py_FatalErrorFormat(
+ const char *func,
+ const char *format,
+ ...);
+
+extern PyObject* _PyErr_SetImportErrorWithNameFrom(
+ PyObject *,
+ PyObject *,
+ PyObject *,
+ PyObject *);
+
+
/* runtime lifecycle */
extern PyStatus _PyErr_InitTypes(PyInterpreterState *);
@@ -31,44 +84,41 @@ static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state)
Py_CLEAR(exc_state->exc_value);
}
-PyAPI_FUNC(PyObject*) _PyErr_StackItemToExcInfoTuple(
+extern PyObject* _PyErr_StackItemToExcInfoTuple(
_PyErr_StackItem *err_info);
-PyAPI_FUNC(void) _PyErr_Fetch(
+extern void _PyErr_Fetch(
PyThreadState *tstate,
PyObject **type,
PyObject **value,
PyObject **traceback);
-extern PyObject *
-_PyErr_GetRaisedException(PyThreadState *tstate);
+extern PyObject* _PyErr_GetRaisedException(PyThreadState *tstate);
PyAPI_FUNC(int) _PyErr_ExceptionMatches(
PyThreadState *tstate,
PyObject *exc);
-void
-_PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc);
+extern void _PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc);
-PyAPI_FUNC(void) _PyErr_Restore(
+extern void _PyErr_Restore(
PyThreadState *tstate,
PyObject *type,
PyObject *value,
PyObject *traceback);
-PyAPI_FUNC(void) _PyErr_SetObject(
+extern void _PyErr_SetObject(
PyThreadState *tstate,
PyObject *type,
PyObject *value);
-PyAPI_FUNC(void) _PyErr_ChainStackItem(
- _PyErr_StackItem *exc_info);
+extern void _PyErr_ChainStackItem(void);
PyAPI_FUNC(void) _PyErr_Clear(PyThreadState *tstate);
-PyAPI_FUNC(void) _PyErr_SetNone(PyThreadState *tstate, PyObject *exception);
+extern void _PyErr_SetNone(PyThreadState *tstate, PyObject *exception);
-PyAPI_FUNC(PyObject *) _PyErr_NoMemory(PyThreadState *tstate);
+extern PyObject* _PyErr_NoMemory(PyThreadState *tstate);
PyAPI_FUNC(void) _PyErr_SetString(
PyThreadState *tstate,
@@ -87,42 +137,53 @@ PyAPI_FUNC(void) _PyErr_SetLocaleString(
PyObject *exception,
const char *string);
-PyAPI_FUNC(PyObject *) _PyErr_Format(
+PyAPI_FUNC(PyObject*) _PyErr_Format(
PyThreadState *tstate,
PyObject *exception,
const char *format,
...);
-PyAPI_FUNC(void) _PyErr_NormalizeException(
+extern void _PyErr_NormalizeException(
PyThreadState *tstate,
PyObject **exc,
PyObject **val,
PyObject **tb);
-PyAPI_FUNC(PyObject *) _PyErr_FormatFromCauseTstate(
+extern PyObject* _PyErr_FormatFromCauseTstate(
PyThreadState *tstate,
PyObject *exception,
const char *format,
...);
-PyAPI_FUNC(PyObject *) _PyExc_CreateExceptionGroup(
+extern PyObject* _PyExc_CreateExceptionGroup(
const char *msg,
PyObject *excs);
-PyAPI_FUNC(PyObject *) _PyExc_PrepReraiseStar(
+extern PyObject* _PyExc_PrepReraiseStar(
PyObject *orig,
PyObject *excs);
-PyAPI_FUNC(int) _PyErr_CheckSignalsTstate(PyThreadState *tstate);
-
-PyAPI_FUNC(void) _Py_DumpExtensionModules(int fd, PyInterpreterState *interp);
+extern int _PyErr_CheckSignalsTstate(PyThreadState *tstate);
+extern void _Py_DumpExtensionModules(int fd, PyInterpreterState *interp);
+extern PyObject* _Py_CalculateSuggestions(PyObject *dir, PyObject *name);
extern PyObject* _Py_Offer_Suggestions(PyObject* exception);
+
+// Export for '_testinternalcapi' shared extension
PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b,
Py_ssize_t max_cost);
void _PyErr_FormatNote(const char *format, ...);
+/* Context manipulation (PEP 3134) */
+
+Py_DEPRECATED(3.12) extern void _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *);
+
+// implementation detail for the codeop module.
+// Exported for test.test_peg_generator.test_c_parser
+PyAPI_DATA(PyTypeObject) _PyExc_IncompleteInputError;
+#define PyExc_IncompleteInputError ((PyObject *)(&_PyExc_IncompleteInputError))
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_pyhash.h b/contrib/tools/python3/Include/internal/pycore_pyhash.h
index 34dfa537712..0ce08900e96 100644
--- a/contrib/tools/python3/Include/internal/pycore_pyhash.h
+++ b/contrib/tools/python3/Include/internal/pycore_pyhash.h
@@ -1,10 +1,78 @@
-#ifndef Py_INTERNAL_HASH_H
-#define Py_INTERNAL_HASH_H
+#ifndef Py_INTERNAL_PYHASH_H
+#define Py_INTERNAL_PYHASH_H
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
+// Similar to Py_HashPointer(), but don't replace -1 with -2.
+static inline Py_hash_t
+_Py_HashPointerRaw(const void *ptr)
+{
+ uintptr_t x = (uintptr_t)ptr;
+ Py_BUILD_ASSERT(sizeof(x) == sizeof(ptr));
+
+ // Bottom 3 or 4 bits are likely to be 0; rotate x by 4 to the right
+ // to avoid excessive hash collisions for dicts and sets.
+ x = (x >> 4) | (x << (8 * sizeof(uintptr_t) - 4));
+
+ Py_BUILD_ASSERT(sizeof(x) == sizeof(Py_hash_t));
+ return (Py_hash_t)x;
+}
+
+// Export for '_datetime' shared extension
+PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t);
+
+/* Hash secret
+ *
+ * memory layout on 64 bit systems
+ * cccccccc cccccccc cccccccc uc -- unsigned char[24]
+ * pppppppp ssssssss ........ fnv -- two Py_hash_t
+ * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t
+ * ........ ........ ssssssss djbx33a -- 16 bytes padding + one Py_hash_t
+ * ........ ........ eeeeeeee pyexpat XML hash salt
+ *
+ * memory layout on 32 bit systems
+ * cccccccc cccccccc cccccccc uc
+ * ppppssss ........ ........ fnv -- two Py_hash_t
+ * k0k0k0k0 k1k1k1k1 ........ siphash -- two uint64_t (*)
+ * ........ ........ ssss.... djbx33a -- 16 bytes padding + one Py_hash_t
+ * ........ ........ eeee.... pyexpat XML hash salt
+ *
+ * (*) The siphash member may not be available on 32 bit platforms without
+ * an unsigned int64 data type.
+ */
+typedef union {
+ /* ensure 24 bytes */
+ unsigned char uc[24];
+ /* two Py_hash_t for FNV */
+ struct {
+ Py_hash_t prefix;
+ Py_hash_t suffix;
+ } fnv;
+ /* two uint64 for SipHash24 */
+ struct {
+ uint64_t k0;
+ uint64_t k1;
+ } siphash;
+ /* a different (!) Py_hash_t for small string optimization */
+ struct {
+ unsigned char padding[16];
+ Py_hash_t suffix;
+ } djbx33a;
+ struct {
+ unsigned char padding[16];
+ Py_hash_t hashsalt;
+ } expat;
+} _Py_HashSecret_t;
+
+// Export for '_elementtree' shared extension
+PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret;
+
+#ifdef Py_DEBUG
+extern int _Py_HashSecret_Initialized;
+#endif
+
struct pyhash_runtime_state {
struct {
@@ -34,7 +102,6 @@ struct pyhash_runtime_state {
}
-uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t);
-
+extern uint64_t _Py_KeyedHash(uint64_t key, const void *src, Py_ssize_t src_sz);
-#endif // Py_INTERNAL_HASH_H
+#endif // !Py_INTERNAL_PYHASH_H
diff --git a/contrib/tools/python3/Include/internal/pycore_pylifecycle.h b/contrib/tools/python3/Include/internal/pycore_pylifecycle.h
index 7cd998a704c..f426ae0e103 100644
--- a/contrib/tools/python3/Include/internal/pycore_pylifecycle.h
+++ b/contrib/tools/python3/Include/internal/pycore_pylifecycle.h
@@ -23,9 +23,7 @@ extern PyStatus _PyUnicode_InitEncodings(PyThreadState *tstate);
extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void);
#endif
-PyAPI_FUNC(void) _Py_ClearStandardStreamEncoding(void);
-
-PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc);
+extern int _Py_IsLocaleCoercionTarget(const char *ctype_loc);
/* Various one-time initializers */
@@ -42,10 +40,8 @@ extern void _PySys_FiniTypes(PyInterpreterState *interp);
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);
-extern PyStatus _PyTime_Init(void);
extern PyStatus _PyGC_Init(PyInterpreterState *interp);
extern PyStatus _PyAtExit_Init(PyInterpreterState *interp);
-extern int _Py_Deepfreeze_Init(void);
/* Various internal finalizers */
@@ -61,38 +57,79 @@ extern void _PyWarnings_Fini(PyInterpreterState *interp);
extern void _PyAST_Fini(PyInterpreterState *interp);
extern void _PyAtExit_Fini(PyInterpreterState *interp);
extern void _PyThread_FiniType(PyInterpreterState *interp);
-extern void _Py_Deepfreeze_Fini(void);
extern void _PyArg_Fini(void);
extern void _Py_FinalizeAllocatedBlocks(_PyRuntimeState *);
extern PyStatus _PyGILState_Init(PyInterpreterState *interp);
-extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate);
+extern void _PyGILState_SetTstate(PyThreadState *tstate);
extern void _PyGILState_Fini(PyInterpreterState *interp);
-PyAPI_FUNC(void) _PyGC_DumpShutdownStats(PyInterpreterState *interp);
+extern void _PyGC_DumpShutdownStats(PyInterpreterState *interp);
-PyAPI_FUNC(PyStatus) _Py_PreInitializeFromPyArgv(
+extern PyStatus _Py_PreInitializeFromPyArgv(
const PyPreConfig *src_config,
const struct _PyArgv *args);
-PyAPI_FUNC(PyStatus) _Py_PreInitializeFromConfig(
+extern PyStatus _Py_PreInitializeFromConfig(
const PyConfig *config,
const struct _PyArgv *args);
-PyAPI_FUNC(wchar_t *) _Py_GetStdlibDir(void);
+extern wchar_t * _Py_GetStdlibDir(void);
-PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p);
+extern int _Py_HandleSystemExit(int *exitcode_p);
-PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable);
+extern PyObject* _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable);
-PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate);
-PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception,
+extern void _PyErr_Print(PyThreadState *tstate);
+extern void _PyErr_Display(PyObject *file, PyObject *exception,
PyObject *value, PyObject *tb);
-PyAPI_FUNC(void) _PyErr_DisplayException(PyObject *file, PyObject *exc);
+extern void _PyErr_DisplayException(PyObject *file, PyObject *exc);
-PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(PyThreadState *tstate);
+extern void _PyThreadState_DeleteCurrent(PyThreadState *tstate);
extern void _PyAtExit_Call(PyInterpreterState *interp);
+extern int _Py_IsCoreInitialized(void);
+
+extern int _Py_FdIsInteractive(FILE *fp, PyObject *filename);
+
+extern const char* _Py_gitidentifier(void);
+extern const char* _Py_gitversion(void);
+
+// Export for '_asyncio' shared extension
+PyAPI_FUNC(int) _Py_IsInterpreterFinalizing(PyInterpreterState *interp);
+
+/* Random */
+extern int _PyOS_URandom(void *buffer, Py_ssize_t size);
+
+// Export for '_random' shared extension
+PyAPI_FUNC(int) _PyOS_URandomNonblock(void *buffer, Py_ssize_t size);
+
+/* Legacy locale support */
+extern int _Py_CoerceLegacyLocale(int warn);
+extern int _Py_LegacyLocaleDetected(int warn);
+
+// Export for 'readline' shared extension
+PyAPI_FUNC(char*) _Py_SetLocaleFromEnv(int category);
+
+// Export for special main.c string compiling with source tracebacks
+int _PyRun_SimpleStringFlagsWithName(const char *command, const char* name, PyCompilerFlags *flags);
+
+
+/* interpreter config */
+
+// Export for _testinternalcapi shared extension
+PyAPI_FUNC(int) _PyInterpreterConfig_InitFromState(
+ PyInterpreterConfig *,
+ PyInterpreterState *);
+PyAPI_FUNC(PyObject *) _PyInterpreterConfig_AsDict(PyInterpreterConfig *);
+PyAPI_FUNC(int) _PyInterpreterConfig_InitFromDict(
+ PyInterpreterConfig *,
+ PyObject *);
+PyAPI_FUNC(int) _PyInterpreterConfig_UpdateFromDict(
+ PyInterpreterConfig *,
+ PyObject *);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_pymem.h b/contrib/tools/python3/Include/internal/pycore_pymem.h
index 81a707a0a5d..76d58d1d251 100644
--- a/contrib/tools/python3/Include/internal/pycore_pymem.h
+++ b/contrib/tools/python3/Include/internal/pycore_pymem.h
@@ -1,5 +1,9 @@
#ifndef Py_INTERNAL_PYMEM_H
#define Py_INTERNAL_PYMEM_H
+
+#include "pycore_llist.h" // struct llist_node
+#include "pycore_lock.h" // PyMutex
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -8,8 +12,20 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pymem.h" // PyMemAllocatorName
+// Try to get the allocators name set by _PyMem_SetupAllocators().
+// Return NULL if unknown.
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void);
+
+// strdup() using PyMem_RawMalloc()
+extern char* _PyMem_RawStrdup(const char *str);
+// strdup() using PyMem_Malloc().
+// Export for '_pickle ' shared extension.
+PyAPI_FUNC(char*) _PyMem_Strdup(const char *str);
+
+// wcsdup() using PyMem_RawMalloc()
+extern wchar_t* _PyMem_RawWcsdup(const wchar_t *str);
typedef struct {
/* We tag each block with an API ID in order to tag API violations */
@@ -18,7 +34,7 @@ typedef struct {
} debug_alloc_api_t;
struct _pymem_allocators {
- PyThread_type_lock mutex;
+ PyMutex mutex;
struct {
PyMemAllocatorEx raw;
PyMemAllocatorEx mem;
@@ -29,14 +45,20 @@ struct _pymem_allocators {
debug_alloc_api_t mem;
debug_alloc_api_t obj;
} debug;
+ int is_debug_enabled;
PyObjectArenaAllocator obj_arena;
};
+struct _Py_mem_interp_free_queue {
+ int has_work; // true if the queue is not empty
+ PyMutex mutex; // protects the queue
+ struct llist_node head; // queue of _mem_work_chunk items
+};
/* Set the memory allocator of the specified domain to the default.
Save the old allocator into *old_alloc if it's non-NULL.
Return on success, or return -1 if the domain is unknown. */
-PyAPI_FUNC(int) _PyMem_SetDefaultAllocator(
+extern int _PyMem_SetDefaultAllocator(
PyMemAllocatorDomain domain,
PyMemAllocatorEx *old_alloc);
@@ -49,7 +71,7 @@ PyAPI_FUNC(int) _PyMem_SetDefaultAllocator(
- PYMEM_FORBIDDENBYTE: untouchable bytes at each end of a block
Byte patterns 0xCB, 0xDB and 0xFB have been replaced with 0xCD, 0xDD and
- 0xFD to use the same values than Windows CRT debug malloc() and free().
+ 0xFD to use the same values as Windows CRT debug malloc() and free().
If modified, _PyMem_IsPtrFreed() should be updated as well. */
#define PYMEM_CLEANBYTE 0xCD
#define PYMEM_DEADBYTE 0xDD
@@ -68,31 +90,72 @@ static inline int _PyMem_IsPtrFreed(const void *ptr)
{
uintptr_t value = (uintptr_t)ptr;
#if SIZEOF_VOID_P == 8
- return (value == 0
+ return (value <= 0xff // NULL, 0x1, 0x2, ..., 0xff
|| value == (uintptr_t)0xCDCDCDCDCDCDCDCD
|| value == (uintptr_t)0xDDDDDDDDDDDDDDDD
- || value == (uintptr_t)0xFDFDFDFDFDFDFDFD);
+ || value == (uintptr_t)0xFDFDFDFDFDFDFDFD
+ || value >= (uintptr_t)0xFFFFFFFFFFFFFF00); // -0xff, ..., -2, -1
#elif SIZEOF_VOID_P == 4
- return (value == 0
+ return (value <= 0xff
|| value == (uintptr_t)0xCDCDCDCD
|| value == (uintptr_t)0xDDDDDDDD
- || value == (uintptr_t)0xFDFDFDFD);
+ || value == (uintptr_t)0xFDFDFDFD
+ || value >= (uintptr_t)0xFFFFFF00);
#else
# error "unknown pointer size"
#endif
}
-PyAPI_FUNC(int) _PyMem_GetAllocatorName(
+// Similar to _PyMem_IsPtrFreed() but expects an 'unsigned long' instead of a
+// pointer.
+static inline int _PyMem_IsULongFreed(unsigned long value)
+{
+#if SIZEOF_LONG == 8
+ return (value == 0
+ || value == (unsigned long)0xCDCDCDCDCDCDCDCD
+ || value == (unsigned long)0xDDDDDDDDDDDDDDDD
+ || value == (unsigned long)0xFDFDFDFDFDFDFDFD
+ || value == (unsigned long)0xFFFFFFFFFFFFFFFF);
+#elif SIZEOF_LONG == 4
+ return (value == 0
+ || value == (unsigned long)0xCDCDCDCD
+ || value == (unsigned long)0xDDDDDDDD
+ || value == (unsigned long)0xFDFDFDFD
+ || value == (unsigned long)0xFFFFFFFF);
+#else
+# error "unknown long size"
+#endif
+}
+
+extern int _PyMem_GetAllocatorName(
const char *name,
PyMemAllocatorName *allocator);
/* Configure the Python memory allocators.
Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators.
PYMEM_ALLOCATOR_NOT_SET does nothing. */
-PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator);
+extern int _PyMem_SetupAllocators(PyMemAllocatorName allocator);
+
+/* Is the debug allocator enabled? */
+extern int _PyMem_DebugEnabled(void);
+
+// Enqueue a pointer to be freed possibly after some delay.
+extern void _PyMem_FreeDelayed(void *ptr, size_t size);
+
+// Enqueue an object to be freed possibly after some delay
+extern void _PyObject_FreeDelayed(void *ptr);
+
+// Periodically process delayed free requests.
+extern void _PyMem_ProcessDelayed(PyThreadState *tstate);
+
+// Abandon all thread-local delayed free requests and push them to the
+// interpreter's queue.
+extern void _PyMem_AbandonDelayed(PyThreadState *tstate);
+// On interpreter shutdown, frees all delayed free requests.
+extern void _PyMem_FiniDelayed(PyInterpreterState *interp);
#ifdef __cplusplus
}
#endif
-#endif /* !Py_INTERNAL_PYMEM_H */
+#endif // !Py_INTERNAL_PYMEM_H
diff --git a/contrib/tools/python3/Include/internal/pycore_pymem_init.h b/contrib/tools/python3/Include/internal/pycore_pymem_init.h
index 78232738cb0..c593edc86d9 100644
--- a/contrib/tools/python3/Include/internal/pycore_pymem_init.h
+++ b/contrib/tools/python3/Include/internal/pycore_pymem_init.h
@@ -8,8 +8,6 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_pymem.h"
-
/********************************/
/* the allocators' initializers */
@@ -20,17 +18,30 @@ extern void * _PyMem_RawRealloc(void *, void *, size_t);
extern void _PyMem_RawFree(void *, void *);
#define PYRAW_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree}
-#ifdef WITH_PYMALLOC
+#ifdef Py_GIL_DISABLED
+// Py_GIL_DISABLED requires mimalloc
+extern void* _PyObject_MiMalloc(void *, size_t);
+extern void* _PyObject_MiCalloc(void *, size_t, size_t);
+extern void _PyObject_MiFree(void *, void *);
+extern void* _PyObject_MiRealloc(void *, void *, size_t);
+# define PYOBJ_ALLOC {NULL, _PyObject_MiMalloc, _PyObject_MiCalloc, _PyObject_MiRealloc, _PyObject_MiFree}
+extern void* _PyMem_MiMalloc(void *, size_t);
+extern void* _PyMem_MiCalloc(void *, size_t, size_t);
+extern void _PyMem_MiFree(void *, void *);
+extern void* _PyMem_MiRealloc(void *, void *, size_t);
+# define PYMEM_ALLOC {NULL, _PyMem_MiMalloc, _PyMem_MiCalloc, _PyMem_MiRealloc, _PyMem_MiFree}
+#elif defined(WITH_PYMALLOC)
extern void* _PyObject_Malloc(void *, size_t);
extern void* _PyObject_Calloc(void *, size_t, size_t);
extern void _PyObject_Free(void *, void *);
extern void* _PyObject_Realloc(void *, void *, size_t);
# define PYOBJ_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free}
+# define PYMEM_ALLOC PYOBJ_ALLOC
#else
# define PYOBJ_ALLOC PYRAW_ALLOC
+# define PYMEM_ALLOC PYOBJ_ALLOC
#endif // WITH_PYMALLOC
-#define PYMEM_ALLOC PYOBJ_ALLOC
extern void* _PyMem_DebugRawMalloc(void *, size_t);
extern void* _PyMem_DebugRawCalloc(void *, size_t, size_t);
@@ -59,6 +70,7 @@ extern void _PyMem_ArenaFree(void *, void *, size_t);
PYDBGMEM_ALLOC(runtime), \
PYDBGOBJ_ALLOC(runtime), \
}
+# define _pymem_is_debug_enabled_INIT 1
#else
# define _pymem_allocators_standard_INIT(runtime) \
{ \
@@ -66,6 +78,7 @@ extern void _PyMem_ArenaFree(void *, void *, size_t);
PYMEM_ALLOC, \
PYOBJ_ALLOC, \
}
+# define _pymem_is_debug_enabled_INIT 0
#endif
#define _pymem_allocators_debug_INIT \
@@ -79,6 +92,11 @@ extern void _PyMem_ArenaFree(void *, void *, size_t);
{ NULL, _PyMem_ArenaAlloc, _PyMem_ArenaFree }
+#define _Py_mem_free_queue_INIT(queue) \
+ { \
+ .head = LLIST_INIT(queue.head), \
+ }
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_pystate.h b/contrib/tools/python3/Include/internal/pycore_pystate.h
index fba08ae5523..b0e72523f58 100644
--- a/contrib/tools/python3/Include/internal/pycore_pystate.h
+++ b/contrib/tools/python3/Include/internal/pycore_pystate.h
@@ -8,7 +8,40 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_runtime.h" /* PyRuntimeState */
+#include "pycore_freelist.h" // _PyFreeListState
+#include "pycore_runtime.h" // _PyRuntime
+#include "pycore_tstate.h" // _PyThreadStateImpl
+
+
+// Values for PyThreadState.state. A thread must be in the "attached" state
+// before calling most Python APIs. If the GIL is enabled, then "attached"
+// implies that the thread holds the GIL and "detached" implies that the
+// thread does not hold the GIL (or is in the process of releasing it). In
+// `--disable-gil` builds, multiple threads may be "attached" to the same
+// interpreter at the same time. Only the "bound" thread may perform the
+// transitions between "attached" and "detached" on its own PyThreadState.
+//
+// The "suspended" state is used to implement stop-the-world pauses, such as
+// for cyclic garbage collection. It is only used in `--disable-gil` builds.
+// The "suspended" state is similar to the "detached" state in that in both
+// states the thread is not allowed to call most Python APIs. However, unlike
+// the "detached" state, a thread may not transition itself out from the
+// "suspended" state. Only the thread performing a stop-the-world pause may
+// transition a thread from the "suspended" state back to the "detached" state.
+//
+// State transition diagram:
+//
+// (bound thread) (stop-the-world thread)
+// [attached] <-> [detached] <-> [suspended]
+// | ^
+// +---------------------------->---------------------------+
+// (bound thread)
+//
+// The (bound thread) and (stop-the-world thread) labels indicate which thread
+// is allowed to perform the transition.
+#define _Py_THREAD_DETACHED 0
+#define _Py_THREAD_ATTACHED 1
+#define _Py_THREAD_SUSPENDED 2
/* Check if the current thread is the main thread.
@@ -44,10 +77,17 @@ _Py_IsMainInterpreterFinalizing(PyInterpreterState *interp)
interp == &_PyRuntime._main_interpreter);
}
-// Export for _xxsubinterpreters module.
+// Export for _interpreters module.
+PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *);
+
+// Export for _interpreters module.
PyAPI_FUNC(int) _PyInterpreterState_SetRunningMain(PyInterpreterState *);
PyAPI_FUNC(void) _PyInterpreterState_SetNotRunningMain(PyInterpreterState *);
PyAPI_FUNC(int) _PyInterpreterState_IsRunningMain(PyInterpreterState *);
+PyAPI_FUNC(int) _PyInterpreterState_FailIfRunningMain(PyInterpreterState *);
+
+extern int _PyThreadState_IsRunningMain(PyThreadState *);
+extern void _PyInterpreterState_ReinitRunningMain(PyThreadState *);
static inline const PyConfig *
@@ -75,13 +115,16 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp)
#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE)
extern _Py_thread_local PyThreadState *_Py_tss_tstate;
#endif
-PyAPI_DATA(PyThreadState *) _PyThreadState_GetCurrent(void);
#ifndef NDEBUG
extern int _PyThreadState_CheckConsistency(PyThreadState *tstate);
#endif
-extern int _PyThreadState_MustExit(PyThreadState *tstate);
+int _PyThreadState_MustExit(PyThreadState *tstate);
+
+// Export for most shared extensions, used via _PyThreadState_GET() static
+// inline function.
+PyAPI_FUNC(PyThreadState *) _PyThreadState_GetCurrent(void);
/* Get the current Python thread state.
@@ -89,7 +132,7 @@ extern int _PyThreadState_MustExit(PyThreadState *tstate);
The caller must hold the GIL.
- See also PyThreadState_Get() and _PyThreadState_UncheckedGet(). */
+ See also PyThreadState_Get() and PyThreadState_GetUnchecked(). */
static inline PyThreadState*
_PyThreadState_GET(void)
{
@@ -100,6 +143,44 @@ _PyThreadState_GET(void)
#endif
}
+// Attaches the current thread to the interpreter.
+//
+// This may block while acquiring the GIL (if the GIL is enabled) or while
+// waiting for a stop-the-world pause (if the GIL is disabled).
+//
+// High-level code should generally call PyEval_RestoreThread() instead, which
+// calls this function.
+extern void _PyThreadState_Attach(PyThreadState *tstate);
+
+// Detaches the current thread from the interpreter.
+//
+// High-level code should generally call PyEval_SaveThread() instead, which
+// calls this function.
+extern void _PyThreadState_Detach(PyThreadState *tstate);
+
+// Detaches the current thread to the "suspended" state if a stop-the-world
+// pause is in progress.
+//
+// If there is no stop-the-world pause in progress, then the thread switches
+// to the "detached" state.
+extern void _PyThreadState_Suspend(PyThreadState *tstate);
+
+// Perform a stop-the-world pause for all threads in the all interpreters.
+//
+// Threads in the "attached" state are paused and transitioned to the "GC"
+// state. Threads in the "detached" state switch to the "GC" state, preventing
+// them from reattaching until the stop-the-world pause is complete.
+//
+// NOTE: This is a no-op outside of Py_GIL_DISABLED builds.
+extern void _PyEval_StopTheWorldAll(_PyRuntimeState *runtime);
+extern void _PyEval_StartTheWorldAll(_PyRuntimeState *runtime);
+
+// Perform a stop-the-world pause for threads in the specified interpreter.
+//
+// NOTE: This is a no-op outside of Py_GIL_DISABLED builds.
+extern void _PyEval_StopTheWorld(PyInterpreterState *interp);
+extern void _PyEval_StartTheWorld(PyInterpreterState *interp);
+
static inline void
_Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
@@ -123,7 +204,7 @@ _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
The caller must hold the GIL.
- See also _PyInterpreterState_Get()
+ See also PyInterpreterState_Get()
and _PyGILState_GetInterpreterStateUnsafe(). */
static inline PyInterpreterState* _PyInterpreterState_GET(void) {
PyThreadState *tstate = _PyThreadState_GET();
@@ -136,43 +217,81 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) {
// PyThreadState functions
-PyAPI_FUNC(PyThreadState *) _PyThreadState_New(PyInterpreterState *interp);
-PyAPI_FUNC(void) _PyThreadState_Bind(PyThreadState *tstate);
-// We keep this around exclusively for stable ABI compatibility.
-PyAPI_FUNC(void) _PyThreadState_Init(
- PyThreadState *tstate);
-PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
+// Export for _testinternalcapi
+PyAPI_FUNC(PyThreadState *) _PyThreadState_New(
+ PyInterpreterState *interp,
+ int whence);
+extern void _PyThreadState_Bind(PyThreadState *tstate);
+PyAPI_FUNC(PyThreadState *) _PyThreadState_NewBound(
+ PyInterpreterState *interp,
+ int whence);
+extern PyThreadState * _PyThreadState_RemoveExcept(PyThreadState *tstate);
+extern void _PyThreadState_DeleteList(PyThreadState *list);
+extern void _PyThreadState_ClearMimallocHeaps(PyThreadState *tstate);
+
+// Export for '_testinternalcapi' shared extension
+PyAPI_FUNC(PyObject*) _PyThreadState_GetDict(PyThreadState *tstate);
+
+/* The implementation of sys._current_exceptions() Returns a dict mapping
+ thread id to that thread's current exception.
+*/
+extern PyObject* _PyThread_CurrentExceptions(void);
/* Other */
-PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
+extern PyThreadState * _PyThreadState_Swap(
_PyRuntimeState *runtime,
PyThreadState *newts);
-PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
+extern PyStatus _PyInterpreterState_Enable(_PyRuntimeState *runtime);
#ifdef HAVE_FORK
extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
extern void _PySignal_AfterFork(void);
#endif
-PyAPI_FUNC(int) _PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *);
-
-
+// Export for the stable ABI
PyAPI_FUNC(int) _PyState_AddModule(
PyThreadState *tstate,
PyObject* module,
PyModuleDef* def);
-PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate);
+extern int _PyOS_InterruptOccurred(PyThreadState *tstate);
#define HEAD_LOCK(runtime) \
- PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK)
+ PyMutex_LockFlags(&(runtime)->interpreters.mutex, _Py_LOCK_DONT_DETACH)
#define HEAD_UNLOCK(runtime) \
- PyThread_release_lock((runtime)->interpreters.mutex)
+ PyMutex_Unlock(&(runtime)->interpreters.mutex)
+
+// Get the configuration of the current interpreter.
+// The caller must hold the GIL.
+// Export for test_peg_generator.
+PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void);
+
+// Get the single PyInterpreterState used by this process' GILState
+// implementation.
+//
+// This function doesn't check for error. Return NULL before _PyGILState_Init()
+// is called and after _PyGILState_Fini() is called.
+//
+// See also PyInterpreterState_Get() and _PyInterpreterState_GET().
+extern PyInterpreterState* _PyGILState_GetInterpreterStateUnsafe(void);
+
+static inline struct _Py_object_freelists* _Py_object_freelists_GET(void)
+{
+ PyThreadState *tstate = _PyThreadState_GET();
+#ifdef Py_DEBUG
+ _Py_EnsureTstateNotNULL(tstate);
+#endif
+#ifdef Py_GIL_DISABLED
+ return &((_PyThreadStateImpl*)tstate)->freelists;
+#else
+ return &tstate->interp->object_state.freelists;
+#endif
+}
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_pystats.h b/contrib/tools/python3/Include/internal/pycore_pystats.h
new file mode 100644
index 00000000000..f8af398a560
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_pystats.h
@@ -0,0 +1,21 @@
+#ifndef Py_INTERNAL_PYSTATS_H
+#define Py_INTERNAL_PYSTATS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#ifdef Py_STATS
+extern void _Py_StatsOn(void);
+extern void _Py_StatsOff(void);
+extern void _Py_StatsClear(void);
+extern int _Py_PrintSpecializationStats(int to_file);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_PYSTATS_H
diff --git a/contrib/tools/python3/Include/internal/pycore_pythonrun.h b/contrib/tools/python3/Include/internal/pycore_pythonrun.h
new file mode 100644
index 00000000000..0bfc5704dc4
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_pythonrun.h
@@ -0,0 +1,39 @@
+#ifndef Py_INTERNAL_PYTHONRUN_H
+#define Py_INTERNAL_PYTHONRUN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+extern int _PyRun_SimpleFileObject(
+ FILE *fp,
+ PyObject *filename,
+ int closeit,
+ PyCompilerFlags *flags);
+
+extern int _PyRun_AnyFileObject(
+ FILE *fp,
+ PyObject *filename,
+ int closeit,
+ PyCompilerFlags *flags);
+
+extern int _PyRun_InteractiveLoopObject(
+ FILE *fp,
+ PyObject *filename,
+ PyCompilerFlags *flags);
+
+extern const char* _Py_SourceAsString(
+ PyObject *cmd,
+ const char *funcname,
+ const char *what,
+ PyCompilerFlags *cf,
+ PyObject **cmd_copy);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_PYTHONRUN_H
+
diff --git a/contrib/tools/python3/Include/internal/pycore_pythread.h b/contrib/tools/python3/Include/internal/pycore_pythread.h
index f53921494c1..bc389a05e94 100644
--- a/contrib/tools/python3/Include/internal/pycore_pythread.h
+++ b/contrib/tools/python3/Include/internal/pycore_pythread.h
@@ -8,42 +8,47 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "dynamic_annotations.h" // _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX
+#include "pycore_llist.h" // struct llist_node
-#ifndef _POSIX_THREADS
-/* This means pthreads are not implemented in libc headers, hence the macro
- not present in unistd.h. But they still can be implemented as an external
- library (e.g. gnu pth in pthread emulation) */
-# ifdef HAVE_PTHREAD_H
-# include <pthread.h> /* _POSIX_THREADS */
-# endif
-# ifndef _POSIX_THREADS
-/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
- enough of the Posix threads package is implemented to support python
- threads.
+// Get _POSIX_THREADS and _POSIX_SEMAPHORES macros if available
+#if (defined(HAVE_UNISTD_H) && !defined(_POSIX_THREADS) \
+ && !defined(_POSIX_SEMAPHORES))
+# include <unistd.h> // _POSIX_THREADS, _POSIX_SEMAPHORES
+#endif
+#if (defined(HAVE_PTHREAD_H) && !defined(_POSIX_THREADS) \
+ && !defined(_POSIX_SEMAPHORES))
+ // This means pthreads are not implemented in libc headers, hence the macro
+ // not present in <unistd.h>. But they still can be implemented as an
+ // external library (e.g. gnu pth in pthread emulation)
+# include <pthread.h> // _POSIX_THREADS, _POSIX_SEMAPHORES
+#endif
+#if !defined(_POSIX_THREADS) && defined(__hpux) && defined(_SC_THREADS)
+ // Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
+ // enough of the POSIX threads package is implemented to support Python
+ // threads.
+ //
+ // This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
+ // a check of __ia64 to verify that we're running on an ia64 system instead
+ // of a pa-risc system.
+# define _POSIX_THREADS
+#endif
- This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
- a check of __ia64 to verify that we're running on an ia64 system instead
- of a pa-risc system.
-*/
-# ifdef __hpux
-# ifdef _SC_THREADS
-# define _POSIX_THREADS
-# endif
-# endif
-# endif /* _POSIX_THREADS */
-#endif /* _POSIX_THREADS */
#if defined(_POSIX_THREADS) || defined(HAVE_PTHREAD_STUBS)
-# define _USE_PTHREADS
+# define _USE_PTHREADS
#endif
#if defined(_USE_PTHREADS) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
// monotonic is supported statically. It doesn't mean it works on runtime.
-# define CONDATTR_MONOTONIC
+# define CONDATTR_MONOTONIC
#endif
#if defined(HAVE_PTHREAD_STUBS)
+#include "cpython/pthread_stubs.h" // PTHREAD_KEYS_MAX
+#include <stdbool.h> // bool
+
// pthread_key
struct py_stub_tls_entry {
bool in_use;
@@ -72,8 +77,94 @@ struct _pythread_runtime_state {
struct py_stub_tls_entry tls_entries[PTHREAD_KEYS_MAX];
} stubs;
#endif
+
+ // Linked list of ThreadHandles
+ struct llist_node handles;
};
+#define _pythread_RUNTIME_INIT(pythread) \
+ { \
+ .handles = LLIST_INIT(pythread.handles), \
+ }
+
+#ifdef HAVE_FORK
+/* Private function to reinitialize a lock at fork in the child process.
+ Reset the lock to the unlocked state.
+ Return 0 on success, return -1 on error. */
+extern int _PyThread_at_fork_reinit(PyThread_type_lock *lock);
+extern void _PyThread_AfterFork(struct _pythread_runtime_state *state);
+#endif /* HAVE_FORK */
+
+
+// unset: -1 seconds, in nanoseconds
+#define PyThread_UNSET_TIMEOUT ((PyTime_t)(-1 * 1000 * 1000 * 1000))
+
+// Exported for the _interpchannels module.
+PyAPI_FUNC(int) PyThread_ParseTimeoutArg(
+ PyObject *arg,
+ int blocking,
+ PY_TIMEOUT_T *timeout);
+
+/* Helper to acquire an interruptible lock with a timeout. If the lock acquire
+ * is interrupted, signal handlers are run, and if they raise an exception,
+ * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
+ * are returned, depending on whether the lock can be acquired within the
+ * timeout.
+ */
+// Exported for the _interpchannels module.
+PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed_with_retries(
+ PyThread_type_lock,
+ PY_TIMEOUT_T microseconds);
+
+typedef unsigned long long PyThread_ident_t;
+typedef Py_uintptr_t PyThread_handle_t;
+
+#define PY_FORMAT_THREAD_IDENT_T "llu"
+#define Py_PARSE_THREAD_IDENT_T "K"
+
+PyAPI_FUNC(PyThread_ident_t) PyThread_get_thread_ident_ex(void);
+
+/* Thread joining APIs.
+ *
+ * These APIs have a strict contract:
+ * - Either PyThread_join_thread or PyThread_detach_thread must be called
+ * exactly once with the given handle.
+ * - Calling neither PyThread_join_thread nor PyThread_detach_thread results
+ * in a resource leak until the end of the process.
+ * - Any other usage, such as calling both PyThread_join_thread and
+ * PyThread_detach_thread, or calling them more than once (including
+ * simultaneously), results in undefined behavior.
+ */
+PyAPI_FUNC(int) PyThread_start_joinable_thread(void (*func)(void *),
+ void *arg,
+ PyThread_ident_t* ident,
+ PyThread_handle_t* handle);
+/*
+ * Join a thread started with `PyThread_start_joinable_thread`.
+ * This function cannot be interrupted. It returns 0 on success,
+ * a non-zero value on failure.
+ */
+PyAPI_FUNC(int) PyThread_join_thread(PyThread_handle_t);
+/*
+ * Detach a thread started with `PyThread_start_joinable_thread`, such
+ * that its resources are relased as soon as it exits.
+ * This function cannot be interrupted. It returns 0 on success,
+ * a non-zero value on failure.
+ */
+PyAPI_FUNC(int) PyThread_detach_thread(PyThread_handle_t);
+/*
+ * Hangs the thread indefinitely without exiting it.
+ *
+ * gh-87135: There is no safe way to exit a thread other than returning
+ * normally from its start function. This is used during finalization in lieu
+ * of actually exiting the thread. Since the program is expected to terminate
+ * soon anyway, it does not matter if the thread stack stays around until then.
+ *
+ * This is unfortunate for embedders who may not be terminating their process
+ * when they're done with the interpreter, but our C API design does not allow
+ * for safely exiting threads attempting to re-enter Python post finalization.
+ */
+void _Py_NO_RETURN PyThread_hang_thread(void);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_qsbr.h b/contrib/tools/python3/Include/internal/pycore_qsbr.h
new file mode 100644
index 00000000000..84e9d98dd21
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_qsbr.h
@@ -0,0 +1,173 @@
+// The QSBR APIs (quiescent state-based reclamation) provide a mechanism for
+// the free-threaded build to safely reclaim memory when there may be
+// concurrent accesses.
+//
+// Many operations in the free-threaded build are protected by locks. However,
+// in some cases, we want to allow reads to happen concurrently with updates.
+// In this case, we need to delay freeing ("reclaiming") any memory that may be
+// concurrently accessed by a reader. The QSBR APIs provide a way to do this.
+#ifndef Py_INTERNAL_QSBR_H
+#define Py_INTERNAL_QSBR_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "pycore_lock.h" // PyMutex
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+// The shared write sequence is always odd and incremented by two. Detached
+// threads are indicated by a read sequence of zero. This avoids collisions
+// between the offline state and any valid sequence number even if the
+// sequences numbers wrap around.
+#define QSBR_OFFLINE 0
+#define QSBR_INITIAL 1
+#define QSBR_INCR 2
+
+// Wrap-around safe comparison. This is a holdover from the FreeBSD
+// implementation, which uses 32-bit sequence numbers. We currently use 64-bit
+// sequence numbers, so wrap-around is unlikely.
+#define QSBR_LT(a, b) ((int64_t)((a)-(b)) < 0)
+#define QSBR_LEQ(a, b) ((int64_t)((a)-(b)) <= 0)
+
+struct _qsbr_shared;
+struct _PyThreadStateImpl; // forward declare to avoid circular dependency
+
+// Per-thread state
+struct _qsbr_thread_state {
+ // Last observed write sequence (or 0 if detached)
+ uint64_t seq;
+
+ // Shared (per-interpreter) QSBR state
+ struct _qsbr_shared *shared;
+
+ // Thread state (or NULL)
+ PyThreadState *tstate;
+
+ // Number of held items added by this thread since the last write sequence
+ // advance
+ int deferred_count;
+
+ // Estimate for the amount of memory that is held by this thread since
+ // the last write sequence advance
+ size_t deferred_memory;
+
+ // Amount of memory in mimalloc pages deferred from collection. When
+ // deferred, they are prevented from being used for a different size class
+ // and in a different thread.
+ size_t deferred_page_memory;
+
+ // True if the deferred memory frees should be processed.
+ bool should_process;
+
+ // Is this thread state allocated?
+ bool allocated;
+ struct _qsbr_thread_state *freelist_next;
+};
+
+// Padding to avoid false sharing
+struct _qsbr_pad {
+ struct _qsbr_thread_state qsbr;
+ char __padding[64 - sizeof(struct _qsbr_thread_state)];
+};
+
+// Per-interpreter state
+struct _qsbr_shared {
+ // Write sequence: always odd, incremented by two
+ uint64_t wr_seq;
+
+ // Minimum observed read sequence of all QSBR thread states
+ uint64_t rd_seq;
+
+ // Array of QSBR thread states.
+ struct _qsbr_pad *array;
+ Py_ssize_t size;
+
+ // Freelist of unused _qsbr_thread_states (protected by mutex)
+ PyMutex mutex;
+ struct _qsbr_thread_state *freelist;
+};
+
+static inline uint64_t
+_Py_qsbr_shared_current(struct _qsbr_shared *shared)
+{
+ return _Py_atomic_load_uint64_acquire(&shared->wr_seq);
+}
+
+// Reports a quiescent state: the caller no longer holds any pointer to shared
+// data not protected by locks or reference counts.
+static inline void
+_Py_qsbr_quiescent_state(struct _qsbr_thread_state *qsbr)
+{
+ uint64_t seq = _Py_qsbr_shared_current(qsbr->shared);
+ _Py_atomic_store_uint64_release(&qsbr->seq, seq);
+}
+
+// Have the read sequences advanced to the given goal? Like `_Py_qsbr_poll()`,
+// but does not perform a scan of threads.
+static inline bool
+_Py_qbsr_goal_reached(struct _qsbr_thread_state *qsbr, uint64_t goal)
+{
+ uint64_t rd_seq = _Py_atomic_load_uint64(&qsbr->shared->rd_seq);
+ return QSBR_LEQ(goal, rd_seq);
+}
+
+// Advance the write sequence and return the new goal. This should be called
+// after data is removed. The returned goal is used with `_Py_qsbr_poll()` to
+// determine when it is safe to reclaim (free) the memory.
+extern uint64_t
+_Py_qsbr_advance(struct _qsbr_shared *shared);
+
+// Return the next value for the write sequence (current plus the increment).
+extern uint64_t
+_Py_qsbr_shared_next(struct _qsbr_shared *shared);
+
+// Return true if deferred memory frees held by QSBR should be processed to
+// determine if they can be safely freed.
+static inline bool
+_Py_qsbr_should_process(struct _qsbr_thread_state *qsbr)
+{
+ return qsbr->should_process;
+}
+
+// Have the read sequences advanced to the given goal? If this returns true,
+// it safe to reclaim any memory tagged with the goal (or earlier goal).
+extern bool
+_Py_qsbr_poll(struct _qsbr_thread_state *qsbr, uint64_t goal);
+
+// Called when thread attaches to interpreter
+extern void
+_Py_qsbr_attach(struct _qsbr_thread_state *qsbr);
+
+// Called when thread detaches from interpreter
+extern void
+_Py_qsbr_detach(struct _qsbr_thread_state *qsbr);
+
+// Reserves (allocates) a QSBR state and returns its index.
+extern Py_ssize_t
+_Py_qsbr_reserve(PyInterpreterState *interp);
+
+// Associates a PyThreadState with the QSBR state at the given index
+extern void
+_Py_qsbr_register(struct _PyThreadStateImpl *tstate,
+ PyInterpreterState *interp, Py_ssize_t index);
+
+// Disassociates a PyThreadState from the QSBR state and frees the QSBR state.
+extern void
+_Py_qsbr_unregister(PyThreadState *tstate);
+
+extern void
+_Py_qsbr_fini(PyInterpreterState *interp);
+
+extern void
+_Py_qsbr_after_fork(struct _PyThreadStateImpl *tstate);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_QSBR_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_runtime.h b/contrib/tools/python3/Include/internal/pycore_runtime.h
index 99c4b0760bf..ed028944d18 100644
--- a/contrib/tools/python3/Include/internal/pycore_runtime.h
+++ b/contrib/tools/python3/Include/internal/pycore_runtime.h
@@ -8,27 +8,24 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_atexit.h" // struct atexit_runtime_state
-#include "pycore_atomic.h" /* _Py_atomic_address */
+#include "pycore_atexit.h" // struct _atexit_runtime_state
#include "pycore_ceval_state.h" // struct _ceval_runtime_state
-#include "pycore_floatobject.h" // struct _Py_float_runtime_state
+#include "pycore_crossinterp.h" // struct _xidregistry
#include "pycore_faulthandler.h" // struct _faulthandler_runtime_state
-#include "pycore_global_objects.h" // struct _Py_global_objects
+#include "pycore_floatobject.h" // struct _Py_float_runtime_state
#include "pycore_import.h" // struct _import_runtime_state
#include "pycore_interp.h" // PyInterpreterState
#include "pycore_object_state.h" // struct _py_object_runtime_state
#include "pycore_parser.h" // struct _parser_runtime_state
-#include "pycore_pymem.h" // struct _pymem_allocators
#include "pycore_pyhash.h" // struct pyhash_runtime_state
+#include "pycore_pymem.h" // struct _pymem_allocators
#include "pycore_pythread.h" // struct _pythread_runtime_state
#include "pycore_signal.h" // struct _signals_runtime_state
-#include "pycore_time.h" // struct _time_runtime_state
#include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state
-#include "pycore_typeobject.h" // struct types_runtime_state
-#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids
+#include "pycore_typeobject.h" // struct _types_runtime_state
+#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_state
struct _getargs_runtime_state {
- PyThread_type_lock mutex;
struct _PyArg_Parser *static_parsers;
};
@@ -47,18 +44,182 @@ struct _gilstate_runtime_state {
/* Runtime audit hook state */
+#define _Py_Debug_Cookie "xdebugpy"
+
+#ifdef Py_GIL_DISABLED
+# define _Py_Debug_gilruntimestate_enabled offsetof(struct _gil_runtime_state, enabled)
+# define _Py_Debug_Free_Threaded 1
+#else
+# define _Py_Debug_gilruntimestate_enabled 0
+# define _Py_Debug_Free_Threaded 0
+#endif
typedef struct _Py_AuditHookEntry {
struct _Py_AuditHookEntry *next;
Py_AuditHookFunction hookCFunction;
void *userData;
} _Py_AuditHookEntry;
+typedef struct _Py_DebugOffsets {
+ char cookie[8] _Py_NONSTRING;
+ uint64_t version;
+ uint64_t free_threaded;
+ // Runtime state offset;
+ struct _runtime_state {
+ uint64_t size;
+ uint64_t finalizing;
+ uint64_t interpreters_head;
+ } runtime_state;
+
+ // Interpreter state offset;
+ struct _interpreter_state {
+ uint64_t size;
+ uint64_t id;
+ uint64_t next;
+ uint64_t threads_head;
+ uint64_t gc;
+ uint64_t imports_modules;
+ uint64_t sysdict;
+ uint64_t builtins;
+ uint64_t ceval_gil;
+ uint64_t gil_runtime_state;
+ uint64_t gil_runtime_state_enabled;
+ uint64_t gil_runtime_state_locked;
+ uint64_t gil_runtime_state_holder;
+ } interpreter_state;
+
+ // Thread state offset;
+ struct _thread_state{
+ uint64_t size;
+ uint64_t prev;
+ uint64_t next;
+ uint64_t interp;
+ uint64_t current_frame;
+ uint64_t thread_id;
+ uint64_t native_thread_id;
+ uint64_t datastack_chunk;
+ uint64_t status;
+ } thread_state;
+
+ // InterpreterFrame offset;
+ struct _interpreter_frame {
+ uint64_t size;
+ uint64_t previous;
+ uint64_t executable;
+ uint64_t instr_ptr;
+ uint64_t localsplus;
+ uint64_t owner;
+ } interpreter_frame;
+
+ // Code object offset;
+ struct _code_object {
+ uint64_t size;
+ uint64_t filename;
+ uint64_t name;
+ uint64_t qualname;
+ uint64_t linetable;
+ uint64_t firstlineno;
+ uint64_t argcount;
+ uint64_t localsplusnames;
+ uint64_t localspluskinds;
+ uint64_t co_code_adaptive;
+ } code_object;
+
+ // PyObject offset;
+ struct _pyobject {
+ uint64_t size;
+ uint64_t ob_type;
+ } pyobject;
+
+ // PyTypeObject object offset;
+ struct _type_object {
+ uint64_t size;
+ uint64_t tp_name;
+ uint64_t tp_repr;
+ uint64_t tp_flags;
+ } type_object;
+
+ // PyTuple object offset;
+ struct _tuple_object {
+ uint64_t size;
+ uint64_t ob_item;
+ uint64_t ob_size;
+ } tuple_object;
+
+ // PyList object offset;
+ struct _list_object {
+ uint64_t size;
+ uint64_t ob_item;
+ uint64_t ob_size;
+ } list_object;
+
+ // PyDict object offset;
+ struct _dict_object {
+ uint64_t size;
+ uint64_t ma_keys;
+ uint64_t ma_values;
+ } dict_object;
+
+ // PyFloat object offset;
+ struct _float_object {
+ uint64_t size;
+ uint64_t ob_fval;
+ } float_object;
+
+ // PyLong object offset;
+ struct _long_object {
+ uint64_t size;
+ uint64_t lv_tag;
+ uint64_t ob_digit;
+ } long_object;
+
+ // PyBytes object offset;
+ struct _bytes_object {
+ uint64_t size;
+ uint64_t ob_size;
+ uint64_t ob_sval;
+ } bytes_object;
+
+ // Unicode object offset;
+ struct _unicode_object {
+ uint64_t size;
+ uint64_t state;
+ uint64_t length;
+ uint64_t asciiobject_size;
+ } unicode_object;
+
+ // GC runtime state offset;
+ struct _gc {
+ uint64_t size;
+ uint64_t collecting;
+ } gc;
+} _Py_DebugOffsets;
+
+/* Reference tracer state */
+struct _reftracer_runtime_state {
+ PyRefTracer tracer_func;
+ void* tracer_data;
+};
+
/* Full Python runtime state */
/* _PyRuntimeState holds the global state for the CPython runtime.
That data is exposed in the internal API as a static variable (_PyRuntime).
*/
typedef struct pyruntimestate {
+ /* This field must be first to facilitate locating it by out of process
+ * debuggers. Out of process debuggers will use the offsets contained in this
+ * field to be able to locate other fields in several interpreter structures
+ * in a way that doesn't require them to know the exact layout of those
+ * structures.
+ *
+ * IMPORTANT:
+ * This struct is **NOT** backwards compatible between minor version of the
+ * interpreter and the members, order of members and size can change between
+ * minor versions. This struct is only guaranteed to be stable between patch
+ * versions for a given minor version of the interpreter.
+ */
+ _Py_DebugOffsets debug_offsets;
+
/* Has been initialized to a safe state.
In order to be effective, this must be set to 0 during or right
@@ -82,10 +243,12 @@ typedef struct pyruntimestate {
Use _PyRuntimeState_GetFinalizing() and _PyRuntimeState_SetFinalizing()
to access it, don't access it directly. */
- _Py_atomic_address _finalizing;
+ PyThreadState *_finalizing;
+ /* The ID of the OS thread in which we are finalizing. */
+ unsigned long _finalizing_id;
struct pyinterpreters {
- PyThread_type_lock mutex;
+ PyMutex mutex;
/* The linked list of interpreters, newest first. */
PyInterpreterState *head;
/* The runtime's initial interpreter, which has a special role
@@ -103,20 +266,22 @@ typedef struct pyruntimestate {
int64_t next_id;
} interpreters;
+ /* Platform-specific identifier and PyThreadState, respectively, for the
+ main thread in the main interpreter. */
unsigned long main_thread;
+ PyThreadState *main_tstate;
/* ---------- IMPORTANT ---------------------------
The fields above this line are declared as early as
possible to facilitate out-of-process observability
tools. */
- // XXX Remove this field once we have a tp_* slot.
- struct _xidregistry xidregistry;
+ /* cross-interpreter data and utils */
+ struct _xi_runtime_state xi;
struct _pymem_allocators allocators;
struct _obmalloc_global_state obmalloc;
struct pyhash_runtime_state pyhash_state;
- struct _time_runtime_state time;
struct _pythread_runtime_state threads;
struct _signals_runtime_state signals;
@@ -139,6 +304,14 @@ typedef struct pyruntimestate {
struct _fileutils_state fileutils;
struct _faulthandler_runtime_state faulthandler;
struct _tracemalloc_runtime_state tracemalloc;
+ struct _reftracer_runtime_state ref_tracer;
+
+ // The rwmutex is used to prevent overlapping global and per-interpreter
+ // stop-the-world events. Global stop-the-world events lock the mutex
+ // exclusively (as a "writer"), while per-interpreter stop-the-world events
+ // lock it non-exclusively (as "readers").
+ _PyRWMutex stoptheworld_mutex;
+ struct _stoptheworld_state stoptheworld;
PyPreConfig preconfig;
@@ -147,7 +320,7 @@ typedef struct pyruntimestate {
Py_OpenCodeHookFunction open_code_hook;
void *open_code_userdata;
struct {
- PyThread_type_lock mutex;
+ PyMutex mutex;
_Py_AuditHookEntry *head;
} audit_hooks;
@@ -157,16 +330,8 @@ typedef struct pyruntimestate {
struct _types_runtime_state types;
/* All the objects that are shared by the runtime's interpreters. */
- struct _Py_static_objects static_objects;
struct _Py_cached_objects cached_objects;
-
- /* The ID of the OS thread in which we are finalizing.
- We use _Py_atomic_address instead of adding a new _Py_atomic_ulong. */
- _Py_atomic_address _finalizing_id;
- /* The value to use for sys.path[0] in new subinterpreters.
- Normally this would be part of the PyConfig struct. However,
- we cannot add it there in 3.12 since that's an ABI change. */
- wchar_t *sys_path_0;
+ struct _Py_static_objects static_objects;
/* The following fields are here to avoid allocation during init.
The data is exposed through _PyRuntimeState pointer fields.
@@ -182,17 +347,27 @@ typedef struct pyruntimestate {
a pointer type.
*/
- /* PyInterpreterState.interpreters.main */
+ /* _PyRuntimeState.interpreters.main */
PyInterpreterState _main_interpreter;
+
+#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
+ // Used in "Python/emscripten_trampoline.c" to choose between type
+ // reflection trampoline and EM_JS trampoline.
+ bool wasm_type_reflection_available;
+#endif
+
} _PyRuntimeState;
/* other API */
+// Export _PyRuntime for shared extensions which use it in static inline
+// functions for best performance, like _Py_IsMainThread() or _Py_ID().
+// It's also made accessible for debuggers and profilers.
PyAPI_DATA(_PyRuntimeState) _PyRuntime;
-PyAPI_FUNC(PyStatus) _PyRuntimeState_Init(_PyRuntimeState *runtime);
-PyAPI_FUNC(void) _PyRuntimeState_Fini(_PyRuntimeState *runtime);
+extern PyStatus _PyRuntimeState_Init(_PyRuntimeState *runtime);
+extern void _PyRuntimeState_Fini(_PyRuntimeState *runtime);
#ifdef HAVE_FORK
extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
@@ -200,32 +375,32 @@ extern PyStatus _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime);
/* Initialize _PyRuntimeState.
Return NULL on success, or return an error message on failure. */
-PyAPI_FUNC(PyStatus) _PyRuntime_Initialize(void);
+extern PyStatus _PyRuntime_Initialize(void);
-PyAPI_FUNC(void) _PyRuntime_Finalize(void);
+extern void _PyRuntime_Finalize(void);
static inline PyThreadState*
_PyRuntimeState_GetFinalizing(_PyRuntimeState *runtime) {
- return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->_finalizing);
+ return (PyThreadState*)_Py_atomic_load_ptr_relaxed(&runtime->_finalizing);
}
static inline unsigned long
_PyRuntimeState_GetFinalizingID(_PyRuntimeState *runtime) {
- return (unsigned long)_Py_atomic_load_relaxed(&runtime->_finalizing_id);
+ return _Py_atomic_load_ulong_relaxed(&runtime->_finalizing_id);
}
static inline void
_PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
- _Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
+ _Py_atomic_store_ptr_relaxed(&runtime->_finalizing, tstate);
if (tstate == NULL) {
- _Py_atomic_store_relaxed(&runtime->_finalizing_id, 0);
+ _Py_atomic_store_ulong_relaxed(&runtime->_finalizing_id, 0);
}
else {
// XXX Re-enable this assert once gh-109860 is fixed.
//assert(tstate->thread_id == PyThread_get_thread_ident());
- _Py_atomic_store_relaxed(&runtime->_finalizing_id,
- (uintptr_t)tstate->thread_id);
+ _Py_atomic_store_ulong_relaxed(&runtime->_finalizing_id,
+ tstate->thread_id);
}
}
diff --git a/contrib/tools/python3/Include/internal/pycore_runtime_init.h b/contrib/tools/python3/Include/internal/pycore_runtime_init.h
index ad90ea680a5..7eef9edc0aa 100644
--- a/contrib/tools/python3/Include/internal/pycore_runtime_init.h
+++ b/contrib/tools/python3/Include/internal/pycore_runtime_init.h
@@ -8,11 +8,19 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_long.h"
-#include "pycore_object.h"
-#include "pycore_parser.h"
-#include "pycore_pymem_init.h"
-#include "pycore_obmalloc_init.h"
+#include "pycore_ceval_state.h" // _PyEval_RUNTIME_PERF_INIT
+#include "pycore_faulthandler.h" // _faulthandler_runtime_state_INIT
+#include "pycore_floatobject.h" // _py_float_format_unknown
+#include "pycore_object.h" // _PyObject_HEAD_INIT
+#include "pycore_obmalloc_init.h" // _obmalloc_global_state_INIT
+#include "pycore_parser.h" // _parser_runtime_state_INIT
+#include "pycore_pyhash.h" // pyhash_state_INIT
+#include "pycore_pymem_init.h" // _pymem_allocators_standard_INIT
+#include "pycore_pythread.h" // _pythread_RUNTIME_INIT
+#include "pycore_qsbr.h" // QSBR_INITIAL
+#include "pycore_runtime_init_generated.h" // _Py_bytes_characters_INIT
+#include "pycore_signal.h" // _signals_RUNTIME_INIT
+#include "pycore_tracemalloc.h" // _tracemalloc_runtime_state_INIT
extern PyTypeObject _PyExc_MemoryError;
@@ -21,27 +29,142 @@ extern PyTypeObject _PyExc_MemoryError;
/* The static initializers defined here should only be used
in the runtime init code (in pystate.c and pylifecycle.c). */
-
-#define _PyRuntimeState_INIT(runtime) \
+#define _PyRuntimeState_INIT(runtime, debug_cookie) \
{ \
+ .debug_offsets = { \
+ .cookie = debug_cookie, \
+ .version = PY_VERSION_HEX, \
+ .free_threaded = _Py_Debug_Free_Threaded, \
+ .runtime_state = { \
+ .size = sizeof(_PyRuntimeState), \
+ .finalizing = offsetof(_PyRuntimeState, _finalizing), \
+ .interpreters_head = offsetof(_PyRuntimeState, interpreters.head), \
+ }, \
+ .interpreter_state = { \
+ .size = sizeof(PyInterpreterState), \
+ .id = offsetof(PyInterpreterState, id), \
+ .next = offsetof(PyInterpreterState, next), \
+ .threads_head = offsetof(PyInterpreterState, threads.head), \
+ .gc = offsetof(PyInterpreterState, gc), \
+ .imports_modules = offsetof(PyInterpreterState, imports.modules), \
+ .sysdict = offsetof(PyInterpreterState, sysdict), \
+ .builtins = offsetof(PyInterpreterState, builtins), \
+ .ceval_gil = offsetof(PyInterpreterState, ceval.gil), \
+ .gil_runtime_state = offsetof(PyInterpreterState, _gil), \
+ .gil_runtime_state_enabled = _Py_Debug_gilruntimestate_enabled, \
+ .gil_runtime_state_locked = offsetof(PyInterpreterState, _gil.locked), \
+ .gil_runtime_state_holder = offsetof(PyInterpreterState, _gil.last_holder), \
+ }, \
+ .thread_state = { \
+ .size = sizeof(PyThreadState), \
+ .prev = offsetof(PyThreadState, prev), \
+ .next = offsetof(PyThreadState, next), \
+ .interp = offsetof(PyThreadState, interp), \
+ .current_frame = offsetof(PyThreadState, current_frame), \
+ .thread_id = offsetof(PyThreadState, thread_id), \
+ .native_thread_id = offsetof(PyThreadState, native_thread_id), \
+ .datastack_chunk = offsetof(PyThreadState, datastack_chunk), \
+ .status = offsetof(PyThreadState, _status), \
+ }, \
+ .interpreter_frame = { \
+ .size = sizeof(_PyInterpreterFrame), \
+ .previous = offsetof(_PyInterpreterFrame, previous), \
+ .executable = offsetof(_PyInterpreterFrame, f_executable), \
+ .instr_ptr = offsetof(_PyInterpreterFrame, instr_ptr), \
+ .localsplus = offsetof(_PyInterpreterFrame, localsplus), \
+ .owner = offsetof(_PyInterpreterFrame, owner), \
+ }, \
+ .code_object = { \
+ .size = sizeof(PyCodeObject), \
+ .filename = offsetof(PyCodeObject, co_filename), \
+ .name = offsetof(PyCodeObject, co_name), \
+ .qualname = offsetof(PyCodeObject, co_qualname), \
+ .linetable = offsetof(PyCodeObject, co_linetable), \
+ .firstlineno = offsetof(PyCodeObject, co_firstlineno), \
+ .argcount = offsetof(PyCodeObject, co_argcount), \
+ .localsplusnames = offsetof(PyCodeObject, co_localsplusnames), \
+ .localspluskinds = offsetof(PyCodeObject, co_localspluskinds), \
+ .co_code_adaptive = offsetof(PyCodeObject, co_code_adaptive), \
+ }, \
+ .pyobject = { \
+ .size = sizeof(PyObject), \
+ .ob_type = offsetof(PyObject, ob_type), \
+ }, \
+ .type_object = { \
+ .size = sizeof(PyTypeObject), \
+ .tp_name = offsetof(PyTypeObject, tp_name), \
+ .tp_repr = offsetof(PyTypeObject, tp_repr), \
+ .tp_flags = offsetof(PyTypeObject, tp_flags), \
+ }, \
+ .tuple_object = { \
+ .size = sizeof(PyTupleObject), \
+ .ob_item = offsetof(PyTupleObject, ob_item), \
+ .ob_size = offsetof(PyTupleObject, ob_base.ob_size), \
+ }, \
+ .list_object = { \
+ .size = sizeof(PyListObject), \
+ .ob_item = offsetof(PyListObject, ob_item), \
+ .ob_size = offsetof(PyListObject, ob_base.ob_size), \
+ }, \
+ .dict_object = { \
+ .size = sizeof(PyDictObject), \
+ .ma_keys = offsetof(PyDictObject, ma_keys), \
+ .ma_values = offsetof(PyDictObject, ma_values), \
+ }, \
+ .float_object = { \
+ .size = sizeof(PyFloatObject), \
+ .ob_fval = offsetof(PyFloatObject, ob_fval), \
+ }, \
+ .long_object = { \
+ .size = sizeof(PyLongObject), \
+ .lv_tag = offsetof(PyLongObject, long_value.lv_tag), \
+ .ob_digit = offsetof(PyLongObject, long_value.ob_digit), \
+ }, \
+ .bytes_object = { \
+ .size = sizeof(PyBytesObject), \
+ .ob_size = offsetof(PyBytesObject, ob_base.ob_size), \
+ .ob_sval = offsetof(PyBytesObject, ob_sval), \
+ }, \
+ .unicode_object = { \
+ .size = sizeof(PyUnicodeObject), \
+ .state = offsetof(PyUnicodeObject, _base._base.state), \
+ .length = offsetof(PyUnicodeObject, _base._base.length), \
+ .asciiobject_size = sizeof(PyASCIIObject), \
+ }, \
+ .gc = { \
+ .size = sizeof(struct _gc_runtime_state), \
+ .collecting = offsetof(struct _gc_runtime_state, collecting), \
+ }, \
+ }, \
.allocators = { \
.standard = _pymem_allocators_standard_INIT(runtime), \
.debug = _pymem_allocators_debug_INIT, \
.obj_arena = _pymem_allocators_obj_arena_INIT, \
+ .is_debug_enabled = _pymem_is_debug_enabled_INIT, \
}, \
.obmalloc = _obmalloc_global_state_INIT, \
.pyhash_state = pyhash_state_INIT, \
+ .threads = _pythread_RUNTIME_INIT(runtime.threads), \
.signals = _signals_RUNTIME_INIT, \
.interpreters = { \
/* This prevents interpreters from getting created \
until _PyInterpreterState_Enable() is called. */ \
.next_id = -1, \
}, \
+ .xi = { \
+ .registry = { \
+ .global = 1, \
+ }, \
+ }, \
/* A TSS key must be initialized with Py_tss_NEEDS_INIT \
in accordance with the specification. */ \
.autoTSSkey = Py_tss_NEEDS_INIT, \
.parser = _parser_runtime_state_INIT, \
.ceval = { \
+ .pending_mainthread = { \
+ .max = MAXPENDINGCALLS_MAIN, \
+ .maxloop = MAXPENDINGCALLSLOOP_MAIN, \
+ }, \
.perf = _PyEval_RUNTIME_PERF_INIT, \
}, \
.gilstate = { \
@@ -52,6 +175,13 @@ extern PyTypeObject _PyExc_MemoryError;
}, \
.faulthandler = _faulthandler_runtime_state_INIT, \
.tracemalloc = _tracemalloc_runtime_state_INIT, \
+ .ref_tracer = { \
+ .tracer_func = NULL, \
+ .tracer_data = NULL, \
+ }, \
+ .stoptheworld = { \
+ .is_global = 1, \
+ }, \
.float_state = { \
.float_format = _py_float_format_unknown, \
.double_format = _py_float_format_unknown, \
@@ -71,13 +201,13 @@ extern PyTypeObject _PyExc_MemoryError;
.latin1 = _Py_str_latin1_INIT, \
}, \
.tuple_empty = { \
- .ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0) \
+ .ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0), \
}, \
.hamt_bitmap_node_empty = { \
- .ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0) \
+ .ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0), \
}, \
.context_token_missing = { \
- .ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type) \
+ .ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type), \
}, \
}, \
}, \
@@ -87,23 +217,31 @@ extern PyTypeObject _PyExc_MemoryError;
#define _PyInterpreterState_INIT(INTERP) \
{ \
.id_refcount = -1, \
+ ._whence = _PyInterpreterState_WHENCE_NOTSET, \
.imports = IMPORTS_INIT, \
- .obmalloc = _obmalloc_state_INIT(INTERP.obmalloc), \
.ceval = { \
.recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \
+ .pending = { \
+ .max = MAXPENDINGCALLS, \
+ .maxloop = MAXPENDINGCALLSLOOP, \
+ }, \
}, \
.gc = { \
.enabled = 1, \
.generations = { \
/* .head is set in _PyGC_InitState(). */ \
- { .threshold = 700, }, \
+ { .threshold = 2000, }, \
{ .threshold = 10, }, \
{ .threshold = 10, }, \
}, \
}, \
- .object_state = _py_object_state_INIT(INTERP), \
+ .qsbr = { \
+ .wr_seq = QSBR_INITIAL, \
+ .rd_seq = QSBR_INITIAL, \
+ }, \
.dtoa = _dtoa_state_INIT(&(INTERP)), \
.dict_state = _dict_state_INIT, \
+ .mem_free_queue = _Py_mem_free_queue_INIT(INTERP.mem_free_queue), \
.func_state = { \
.next_version = 1, \
}, \
@@ -114,33 +252,36 @@ extern PyTypeObject _PyExc_MemoryError;
.singletons = { \
._not_used = 1, \
.hamt_empty = { \
- .ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type) \
+ .ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type), \
.h_root = (PyHamtNode*)&_Py_SINGLETON(hamt_bitmap_node_empty), \
}, \
.last_resort_memory_error = { \
- _PyObject_HEAD_INIT(&_PyExc_MemoryError) \
+ _PyObject_HEAD_INIT(&_PyExc_MemoryError), \
.args = (PyObject*)&_Py_SINGLETON(tuple_empty) \
}, \
}, \
}, \
- ._initial_thread = _PyThreadState_INIT, \
+ ._initial_thread = _PyThreadStateImpl_INIT, \
+ }
+
+#define _PyThreadStateImpl_INIT \
+ { \
+ .base = _PyThreadState_INIT, \
}
#define _PyThreadState_INIT \
{ \
+ ._whence = _PyThreadState_WHENCE_NOTSET, \
.py_recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \
.context_ver = 1, \
}
-# define _py_object_state_INIT(INTERP) \
- { 0 }
-
// global objects
#define _PyBytes_SIMPLE_INIT(CH, LEN) \
{ \
- _PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)) \
+ _PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)), \
.ob_shash = -1, \
.ob_sval = { (CH) }, \
}
@@ -151,7 +292,7 @@ extern PyTypeObject _PyExc_MemoryError;
#define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \
{ \
- .ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type) \
+ .ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type), \
.length = sizeof(LITERAL) - 1, \
.hash = -1, \
.state = { \
diff --git a/contrib/tools/python3/Include/internal/pycore_runtime_init_generated.h b/contrib/tools/python3/Include/internal/pycore_runtime_init_generated.h
index 460a6c79730..19a6b9b1537 100644
--- a/contrib/tools/python3/Include/internal/pycore_runtime_init_generated.h
+++ b/contrib/tools/python3/Include/internal/pycore_runtime_init_generated.h
@@ -8,6 +8,9 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_long.h" // _PyLong_DIGIT_INIT()
+
+
/* The following is auto-generated by Tools/build/generate_global_objects.py. */
#define _Py_small_ints_INIT { \
_PyLong_DIGIT_INIT(-5), \
@@ -539,6 +542,7 @@ extern "C" {
INIT_STR(anon_lambda, "<lambda>"), \
INIT_STR(anon_listcomp, "<listcomp>"), \
INIT_STR(anon_module, "<module>"), \
+ INIT_STR(anon_null, "<NULL>"), \
INIT_STR(anon_setcomp, "<setcomp>"), \
INIT_STR(anon_string, "<string>"), \
INIT_STR(anon_unknown, "<unknown>"), \
@@ -552,7 +556,7 @@ extern "C" {
INIT_STR(json_decoder, "json.decoder"), \
INIT_STR(kwdefaults, ".kwdefaults"), \
INIT_STR(list_err, "list index out of range"), \
- INIT_STR(shim_name, "<shim>"), \
+ INIT_STR(str_replace_inf, "1e309"), \
INIT_STR(type_params, ".type_params"), \
INIT_STR(utf_8, "utf-8"), \
}
@@ -581,7 +585,6 @@ extern "C" {
INIT_ID(__anext__), \
INIT_ID(__annotations__), \
INIT_ID(__args__), \
- INIT_ID(__asyncio_running_event_loop__), \
INIT_ID(__await__), \
INIT_ID(__bases__), \
INIT_ID(__bool__), \
@@ -613,6 +616,7 @@ extern "C" {
INIT_ID(__eq__), \
INIT_ID(__exit__), \
INIT_ID(__file__), \
+ INIT_ID(__firstlineno__), \
INIT_ID(__float__), \
INIT_ID(__floordiv__), \
INIT_ID(__format__), \
@@ -658,6 +662,7 @@ extern "C" {
INIT_ID(__lshift__), \
INIT_ID(__lt__), \
INIT_ID(__main__), \
+ INIT_ID(__match_args__), \
INIT_ID(__matmul__), \
INIT_ID(__missing__), \
INIT_ID(__mod__), \
@@ -712,6 +717,7 @@ extern "C" {
INIT_ID(__slotnames__), \
INIT_ID(__slots__), \
INIT_ID(__spec__), \
+ INIT_ID(__static_attributes__), \
INIT_ID(__str__), \
INIT_ID(__sub__), \
INIT_ID(__subclasscheck__), \
@@ -730,6 +736,7 @@ extern "C" {
INIT_ID(_abc_impl), \
INIT_ID(_abstract_), \
INIT_ID(_active), \
+ INIT_ID(_align_), \
INIT_ID(_annotation), \
INIT_ID(_anonymous_), \
INIT_ID(_argtypes_), \
@@ -740,6 +747,7 @@ extern "C" {
INIT_ID(_check_retval_), \
INIT_ID(_dealloc_warn), \
INIT_ID(_feature_version), \
+ INIT_ID(_field_types), \
INIT_ID(_fields_), \
INIT_ID(_finalizing), \
INIT_ID(_find_and_load), \
@@ -761,6 +769,7 @@ extern "C" {
INIT_ID(_showwarnmsg), \
INIT_ID(_shutdown), \
INIT_ID(_slotnames), \
+ INIT_ID(_strptime), \
INIT_ID(_strptime_datetime), \
INIT_ID(_swappedbytes_), \
INIT_ID(_type_), \
@@ -769,12 +778,14 @@ extern "C" {
INIT_ID(_xoptions), \
INIT_ID(abs_tol), \
INIT_ID(access), \
+ INIT_ID(aclose), \
INIT_ID(add), \
INIT_ID(add_done_callback), \
INIT_ID(after_in_child), \
INIT_ID(after_in_parent), \
INIT_ID(aggregate_class), \
INIT_ID(alias), \
+ INIT_ID(allow_code), \
INIT_ID(append), \
INIT_ID(arg), \
INIT_ID(argdefs), \
@@ -782,7 +793,9 @@ extern "C" {
INIT_ID(arguments), \
INIT_ID(argv), \
INIT_ID(as_integer_ratio), \
+ INIT_ID(asend), \
INIT_ID(ast), \
+ INIT_ID(athrow), \
INIT_ID(attribute), \
INIT_ID(authorizer_callback), \
INIT_ID(autocommit), \
@@ -806,12 +819,14 @@ extern "C" {
INIT_ID(c_call), \
INIT_ID(c_exception), \
INIT_ID(c_return), \
+ INIT_ID(cached_datetime_module), \
INIT_ID(cached_statements), \
INIT_ID(cadata), \
INIT_ID(cafile), \
INIT_ID(call), \
INIT_ID(call_exception_handler), \
INIT_ID(call_soon), \
+ INIT_ID(callback), \
INIT_ID(cancel), \
INIT_ID(capath), \
INIT_ID(category), \
@@ -842,6 +857,7 @@ extern "C" {
INIT_ID(co_stacksize), \
INIT_ID(co_varnames), \
INIT_ID(code), \
+ INIT_ID(col_offset), \
INIT_ID(command), \
INIT_ID(comment_factory), \
INIT_ID(compile_mode), \
@@ -857,12 +873,14 @@ extern "C" {
INIT_ID(cwd), \
INIT_ID(data), \
INIT_ID(database), \
+ INIT_ID(day), \
INIT_ID(decode), \
INIT_ID(decoder), \
INIT_ID(default), \
INIT_ID(defaultaction), \
INIT_ID(delete), \
INIT_ID(depth), \
+ INIT_ID(desired_access), \
INIT_ID(detect_types), \
INIT_ID(deterministic), \
INIT_ID(device), \
@@ -881,13 +899,13 @@ extern "C" {
INIT_ID(dont_inherit), \
INIT_ID(dst), \
INIT_ID(dst_dir_fd), \
- INIT_ID(duration), \
INIT_ID(eager_start), \
INIT_ID(effective_ids), \
INIT_ID(element_factory), \
INIT_ID(encode), \
INIT_ID(encoding), \
INIT_ID(end), \
+ INIT_ID(end_col_offset), \
INIT_ID(end_lineno), \
INIT_ID(end_offset), \
INIT_ID(endpos), \
@@ -919,15 +937,16 @@ extern "C" {
INIT_ID(fileno), \
INIT_ID(filepath), \
INIT_ID(fillvalue), \
+ INIT_ID(filter), \
INIT_ID(filters), \
INIT_ID(final), \
INIT_ID(find_class), \
INIT_ID(fix_imports), \
INIT_ID(flags), \
INIT_ID(flush), \
+ INIT_ID(fold), \
INIT_ID(follow_symlinks), \
INIT_ID(format), \
- INIT_ID(frequency), \
INIT_ID(from_param), \
INIT_ID(fromlist), \
INIT_ID(fromtimestamp), \
@@ -949,13 +968,16 @@ extern "C" {
INIT_ID(groupindex), \
INIT_ID(groups), \
INIT_ID(handle), \
+ INIT_ID(handle_seq), \
+ INIT_ID(has_location), \
INIT_ID(hash_name), \
INIT_ID(header), \
INIT_ID(headers), \
INIT_ID(hi), \
INIT_ID(hook), \
- INIT_ID(id), \
+ INIT_ID(hour), \
INIT_ID(ident), \
+ INIT_ID(identity_hint), \
INIT_ID(ignore), \
INIT_ID(imag), \
INIT_ID(importlib), \
@@ -964,9 +986,12 @@ extern "C" {
INIT_ID(indexgroup), \
INIT_ID(inf), \
INIT_ID(infer_variance), \
+ INIT_ID(inherit_handle), \
INIT_ID(inheritable), \
INIT_ID(initial), \
INIT_ID(initial_bytes), \
+ INIT_ID(initial_owner), \
+ INIT_ID(initial_state), \
INIT_ID(initial_value), \
INIT_ID(initval), \
INIT_ID(inner_size), \
@@ -976,6 +1001,7 @@ extern "C" {
INIT_ID(instructions), \
INIT_ID(intern), \
INIT_ID(intersection), \
+ INIT_ID(interval), \
INIT_ID(is_running), \
INIT_ID(isatty), \
INIT_ID(isinstance), \
@@ -997,6 +1023,8 @@ extern "C" {
INIT_ID(kw), \
INIT_ID(kw1), \
INIT_ID(kw2), \
+ INIT_ID(kwdefaults), \
+ INIT_ID(label), \
INIT_ID(lambda), \
INIT_ID(last), \
INIT_ID(last_exc), \
@@ -1020,11 +1048,13 @@ extern "C" {
INIT_ID(locals), \
INIT_ID(logoption), \
INIT_ID(loop), \
+ INIT_ID(manual_reset), \
INIT_ID(mapping), \
INIT_ID(match), \
INIT_ID(max_length), \
INIT_ID(maxdigits), \
INIT_ID(maxevents), \
+ INIT_ID(maxlen), \
INIT_ID(maxmem), \
INIT_ID(maxsplit), \
INIT_ID(maxvalue), \
@@ -1034,13 +1064,18 @@ extern "C" {
INIT_ID(metaclass), \
INIT_ID(metadata), \
INIT_ID(method), \
+ INIT_ID(microsecond), \
+ INIT_ID(milliseconds), \
+ INIT_ID(minute), \
INIT_ID(mod), \
INIT_ID(mode), \
INIT_ID(module), \
INIT_ID(module_globals), \
INIT_ID(modules), \
+ INIT_ID(month), \
INIT_ID(mro), \
INIT_ID(msg), \
+ INIT_ID(mutex), \
INIT_ID(mycmp), \
INIT_ID(n_arg), \
INIT_ID(n_fields), \
@@ -1052,6 +1087,7 @@ extern "C" {
INIT_ID(namespaces), \
INIT_ID(narg), \
INIT_ID(ndigits), \
+ INIT_ID(nested), \
INIT_ID(new_file_name), \
INIT_ID(new_limit), \
INIT_ID(newline), \
@@ -1139,6 +1175,8 @@ extern "C" {
INIT_ID(salt), \
INIT_ID(sched_priority), \
INIT_ID(scheduler), \
+ INIT_ID(second), \
+ INIT_ID(security_attributes), \
INIT_ID(seek), \
INIT_ID(seekable), \
INIT_ID(selectors), \
@@ -1164,7 +1202,6 @@ extern "C" {
INIT_ID(sleep), \
INIT_ID(sock), \
INIT_ID(sort), \
- INIT_ID(sound), \
INIT_ID(source), \
INIT_ID(source_traceback), \
INIT_ID(spam), \
@@ -1217,6 +1254,7 @@ extern "C" {
INIT_ID(type), \
INIT_ID(type_params), \
INIT_ID(tz), \
+ INIT_ID(tzinfo), \
INIT_ID(tzname), \
INIT_ID(uid), \
INIT_ID(unlink), \
@@ -1227,6 +1265,8 @@ extern "C" {
INIT_ID(values), \
INIT_ID(version), \
INIT_ID(volume), \
+ INIT_ID(wait_all), \
+ INIT_ID(warn_on_full_buffer), \
INIT_ID(warnings), \
INIT_ID(warnoptions), \
INIT_ID(wbits), \
diff --git a/contrib/tools/python3/Include/internal/pycore_semaphore.h b/contrib/tools/python3/Include/internal/pycore_semaphore.h
new file mode 100644
index 00000000000..26953838460
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_semaphore.h
@@ -0,0 +1,67 @@
+// The _PySemaphore API a simplified cross-platform semaphore used to implement
+// wakeup/sleep.
+#ifndef Py_INTERNAL_SEMAPHORE_H
+#define Py_INTERNAL_SEMAPHORE_H
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_pythread.h" // _POSIX_SEMAPHORES
+
+#ifdef MS_WINDOWS
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+#elif defined(HAVE_PTHREAD_H)
+# include <pthread.h>
+#elif defined(HAVE_PTHREAD_STUBS)
+# include "cpython/pthread_stubs.h"
+#else
+# error "Require native threads. See https://bugs.python.org/issue31370"
+#endif
+
+#if (defined(_POSIX_SEMAPHORES) && (_POSIX_SEMAPHORES+0) != -1 && \
+ defined(HAVE_SEM_TIMEDWAIT))
+# define _Py_USE_SEMAPHORES
+# include <semaphore.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _PySemaphore {
+#if defined(MS_WINDOWS)
+ HANDLE platform_sem;
+#elif defined(_Py_USE_SEMAPHORES)
+ sem_t platform_sem;
+#else
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int counter;
+#endif
+} _PySemaphore;
+
+// Puts the current thread to sleep until _PySemaphore_Wakeup() is called.
+// If `detach` is true, then the thread will detach/release the GIL while
+// sleeping.
+PyAPI_FUNC(int)
+_PySemaphore_Wait(_PySemaphore *sema, PyTime_t timeout_ns, int detach);
+
+// Wakes up a single thread waiting on sema. Note that _PySemaphore_Wakeup()
+// can be called before _PySemaphore_Wait().
+PyAPI_FUNC(void)
+_PySemaphore_Wakeup(_PySemaphore *sema);
+
+// Initializes/destroys a semaphore
+PyAPI_FUNC(void) _PySemaphore_Init(_PySemaphore *sema);
+PyAPI_FUNC(void) _PySemaphore_Destroy(_PySemaphore *sema);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_SEMAPHORE_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_setobject.h b/contrib/tools/python3/Include/internal/pycore_setobject.h
new file mode 100644
index 00000000000..0494c07fe18
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_setobject.h
@@ -0,0 +1,39 @@
+#ifndef Py_INTERNAL_SETOBJECT_H
+#define Py_INTERNAL_SETOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+// Export for '_abc' shared extension
+PyAPI_FUNC(int) _PySet_NextEntry(
+ PyObject *set,
+ Py_ssize_t *pos,
+ PyObject **key,
+ Py_hash_t *hash);
+
+// Export for '_pickle' shared extension
+PyAPI_FUNC(int) _PySet_NextEntryRef(
+ PyObject *set,
+ Py_ssize_t *pos,
+ PyObject **key,
+ Py_hash_t *hash);
+
+// Export for '_pickle' shared extension
+PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
+
+// Export for the gdb plugin's (python-gdb.py) benefit
+PyAPI_DATA(PyObject *) _PySet_Dummy;
+
+PyAPI_FUNC(int) _PySet_Contains(PySetObject *so, PyObject *key);
+
+// Clears the set without acquiring locks. Used by _PyCode_Fini.
+extern void _PySet_ClearInternal(PySetObject *so);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // !Py_INTERNAL_SETOBJECT_H
diff --git a/contrib/tools/python3/Include/internal/pycore_signal.h b/contrib/tools/python3/Include/internal/pycore_signal.h
index ca3f69d09fc..47213a34ab7 100644
--- a/contrib/tools/python3/Include/internal/pycore_signal.h
+++ b/contrib/tools/python3/Include/internal/pycore_signal.h
@@ -10,10 +10,12 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_atomic.h" // _Py_atomic_address
+#include <signal.h> // NSIG
-#include <signal.h> // NSIG
+// Restore signals that the interpreter has called SIG_IGN on to SIG_DFL.
+// Export for '_posixsubprocess' shared extension.
+PyAPI_FUNC(void) _Py_RestoreSignals(void);
#ifdef _SIG_MAXSIG
// gh-91145: On FreeBSD, <signal.h> defines NSIG as 32: it doesn't include
@@ -35,12 +37,10 @@ extern "C" {
#define INVALID_FD (-1)
struct _signals_runtime_state {
- volatile struct {
- _Py_atomic_int tripped;
- /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe
- * (even though it would probably be otherwise, anyway).
- */
- _Py_atomic_address func;
+ struct {
+ // tripped and func should be accessed using atomic ops.
+ int tripped;
+ PyObject* func;
} handlers[Py_NSIG];
volatile struct {
@@ -60,8 +60,9 @@ struct _signals_runtime_state {
#endif
} wakeup;
- /* Speed up sigcheck() when none tripped */
- _Py_atomic_int is_tripped;
+ /* Speed up sigcheck() when none tripped.
+ is_tripped should be accessed using atomic ops. */
+ int is_tripped;
/* These objects necessarily belong to the main interpreter. */
PyObject *default_handler;
@@ -92,6 +93,15 @@ struct _signals_runtime_state {
}
+// Export for '_multiprocessing' shared extension
+PyAPI_FUNC(int) _PyOS_IsMainThread(void);
+
+#ifdef MS_WINDOWS
+// <windows.h> is not included by Python.h so use void* instead of HANDLE.
+// Export for '_multiprocessing' shared extension
+PyAPI_FUNC(void*) _PyOS_SigintEvent(void);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_sliceobject.h b/contrib/tools/python3/Include/internal/pycore_sliceobject.h
index 98665c3859d..ba8b1f1cb27 100644
--- a/contrib/tools/python3/Include/internal/pycore_sliceobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_sliceobject.h
@@ -11,9 +11,7 @@ extern "C" {
/* runtime lifecycle */
-extern void _PySlice_Fini(PyInterpreterState *);
-
-extern PyObject *
+PyAPI_FUNC(PyObject *)
_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop);
#ifdef __cplusplus
diff --git a/contrib/tools/python3/Include/internal/pycore_stackref.h b/contrib/tools/python3/Include/internal/pycore_stackref.h
new file mode 100644
index 00000000000..93898174789
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_stackref.h
@@ -0,0 +1,195 @@
+#ifndef Py_INTERNAL_STACKREF_H
+#define Py_INTERNAL_STACKREF_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include <stddef.h>
+
+typedef union {
+ uintptr_t bits;
+} _PyStackRef;
+
+static const _PyStackRef Py_STACKREF_NULL = { .bits = 0 };
+
+#define Py_TAG_DEFERRED (1)
+
+// Gets a PyObject * from a _PyStackRef
+#if defined(Py_GIL_DISABLED)
+static inline PyObject *
+PyStackRef_Get(_PyStackRef tagged)
+{
+ PyObject *cleared = ((PyObject *)((tagged).bits & (~Py_TAG_DEFERRED)));
+ return cleared;
+}
+#else
+# define PyStackRef_Get(tagged) ((PyObject *)((tagged).bits))
+#endif
+
+// Converts a PyObject * to a PyStackRef, stealing the reference.
+#if defined(Py_GIL_DISABLED)
+static inline _PyStackRef
+_PyStackRef_StealRef(PyObject *obj)
+{
+ // Make sure we don't take an already tagged value.
+ assert(((uintptr_t)obj & Py_TAG_DEFERRED) == 0);
+ return ((_PyStackRef){.bits = ((uintptr_t)(obj))});
+}
+# define PyStackRef_StealRef(obj) _PyStackRef_StealRef(_PyObject_CAST(obj))
+#else
+# define PyStackRef_StealRef(obj) ((_PyStackRef){.bits = ((uintptr_t)(obj))})
+#endif
+
+// Converts a PyObject * to a PyStackRef, with a new reference
+#if defined(Py_GIL_DISABLED)
+static inline _PyStackRef
+_PyStackRef_NewRefDeferred(PyObject *obj)
+{
+ // Make sure we don't take an already tagged value.
+ assert(((uintptr_t)obj & Py_TAG_DEFERRED) == 0);
+ assert(obj != NULL);
+ if (_PyObject_HasDeferredRefcount(obj)) {
+ return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_DEFERRED };
+ }
+ else {
+ return (_PyStackRef){ .bits = (uintptr_t)Py_NewRef(obj) };
+ }
+}
+# define PyStackRef_NewRefDeferred(obj) _PyStackRef_NewRefDeferred(_PyObject_CAST(obj))
+#else
+# define PyStackRef_NewRefDeferred(obj) PyStackRef_NewRef(((_PyStackRef){.bits = ((uintptr_t)(obj))}))
+#endif
+
+#if defined(Py_GIL_DISABLED)
+static inline _PyStackRef
+_PyStackRef_XNewRefDeferred(PyObject *obj)
+{
+ // Make sure we don't take an already tagged value.
+ assert(((uintptr_t)obj & Py_TAG_DEFERRED) == 0);
+ if (obj == NULL) {
+ return Py_STACKREF_NULL;
+ }
+ return _PyStackRef_NewRefDeferred(obj);
+}
+# define PyStackRef_XNewRefDeferred(obj) _PyStackRef_XNewRefDeferred(_PyObject_CAST(obj))
+#else
+# define PyStackRef_XNewRefDeferred(obj) PyStackRef_XNewRef(((_PyStackRef){.bits = ((uintptr_t)(obj))}))
+#endif
+
+// Converts a PyStackRef back to a PyObject *.
+#if defined(Py_GIL_DISABLED)
+static inline PyObject *
+PyStackRef_StealObject(_PyStackRef tagged)
+{
+ if ((tagged.bits & Py_TAG_DEFERRED) == Py_TAG_DEFERRED) {
+ assert(_PyObject_HasDeferredRefcount(PyStackRef_Get(tagged)));
+ return Py_NewRef(PyStackRef_Get(tagged));
+ }
+ return PyStackRef_Get(tagged);
+}
+#else
+# define PyStackRef_StealObject(tagged) PyStackRef_Get(tagged)
+#endif
+
+static inline void
+_Py_untag_stack_borrowed(PyObject **dst, const _PyStackRef *src, size_t length)
+{
+ for (size_t i = 0; i < length; i++) {
+ dst[i] = PyStackRef_Get(src[i]);
+ }
+}
+
+static inline void
+_Py_untag_stack_steal(PyObject **dst, const _PyStackRef *src, size_t length)
+{
+ for (size_t i = 0; i < length; i++) {
+ dst[i] = PyStackRef_StealObject(src[i]);
+ }
+}
+
+
+#define PyStackRef_XSETREF(dst, src) \
+ do { \
+ _PyStackRef *_tmp_dst_ptr = &(dst); \
+ _PyStackRef _tmp_old_dst = (*_tmp_dst_ptr); \
+ *_tmp_dst_ptr = (src); \
+ PyStackRef_XDECREF(_tmp_old_dst); \
+ } while (0)
+
+#define PyStackRef_SETREF(dst, src) \
+ do { \
+ _PyStackRef *_tmp_dst_ptr = &(dst); \
+ _PyStackRef _tmp_old_dst = (*_tmp_dst_ptr); \
+ *_tmp_dst_ptr = (src); \
+ PyStackRef_DECREF(_tmp_old_dst); \
+ } while (0)
+
+#define PyStackRef_CLEAR(op) \
+ do { \
+ _PyStackRef *_tmp_op_ptr = &(op); \
+ _PyStackRef _tmp_old_op = (*_tmp_op_ptr); \
+ if (_tmp_old_op.bits != Py_STACKREF_NULL.bits) { \
+ *_tmp_op_ptr = Py_STACKREF_NULL; \
+ PyStackRef_DECREF(_tmp_old_op); \
+ } \
+ } while (0)
+
+#if defined(Py_GIL_DISABLED)
+static inline void
+PyStackRef_DECREF(_PyStackRef tagged)
+{
+ if ((tagged.bits & Py_TAG_DEFERRED) == Py_TAG_DEFERRED) {
+ return;
+ }
+ Py_DECREF(PyStackRef_Get(tagged));
+}
+#else
+# define PyStackRef_DECREF(op) Py_DECREF(PyStackRef_Get(op))
+#endif
+
+#if defined(Py_GIL_DISABLED)
+static inline void
+PyStackRef_INCREF(_PyStackRef tagged)
+{
+ if ((tagged.bits & Py_TAG_DEFERRED) == Py_TAG_DEFERRED) {
+ assert(_PyObject_HasDeferredRefcount(PyStackRef_Get(tagged)));
+ return;
+ }
+ Py_INCREF(PyStackRef_Get(tagged));
+}
+#else
+# define PyStackRef_INCREF(op) Py_INCREF(PyStackRef_Get(op))
+#endif
+
+static inline void
+PyStackRef_XDECREF(_PyStackRef op)
+{
+ if (op.bits != Py_STACKREF_NULL.bits) {
+ PyStackRef_DECREF(op);
+ }
+}
+
+static inline _PyStackRef
+PyStackRef_NewRef(_PyStackRef obj)
+{
+ PyStackRef_INCREF(obj);
+ return obj;
+}
+
+static inline _PyStackRef
+PyStackRef_XNewRef(_PyStackRef obj)
+{
+ if (obj.bits == Py_STACKREF_NULL.bits) {
+ return obj;
+ }
+ return PyStackRef_NewRef(obj);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_STACKREF_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_strhex.h b/contrib/tools/python3/Include/internal/pycore_strhex.h
index f427b4d695b..225f423912f 100644
--- a/contrib/tools/python3/Include/internal/pycore_strhex.h
+++ b/contrib/tools/python3/Include/internal/pycore_strhex.h
@@ -9,21 +9,24 @@ extern "C" {
#endif
// Returns a str() containing the hex representation of argbuf.
+// Export for '_hashlib' shared extension.
PyAPI_FUNC(PyObject*) _Py_strhex(const
char* argbuf,
const Py_ssize_t arglen);
// Returns a bytes() containing the ASCII hex representation of argbuf.
-PyAPI_FUNC(PyObject*) _Py_strhex_bytes(
+extern PyObject* _Py_strhex_bytes(
const char* argbuf,
const Py_ssize_t arglen);
// These variants include support for a separator between every N bytes:
-PyAPI_FUNC(PyObject*) _Py_strhex_with_sep(
+extern PyObject* _Py_strhex_with_sep(
const char* argbuf,
const Py_ssize_t arglen,
PyObject* sep,
const int bytes_per_group);
+
+// Export for 'binascii' shared extension
PyAPI_FUNC(PyObject*) _Py_strhex_bytes_with_sep(
const char* argbuf,
const Py_ssize_t arglen,
diff --git a/contrib/tools/python3/Include/internal/pycore_structseq.h b/contrib/tools/python3/Include/internal/pycore_structseq.h
index 6f5dfc12707..5cff1656275 100644
--- a/contrib/tools/python3/Include/internal/pycore_structseq.h
+++ b/contrib/tools/python3/Include/internal/pycore_structseq.h
@@ -11,7 +11,8 @@ extern "C" {
/* other API */
-PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType(
+// Export for '_curses' shared extension
+PyAPI_FUNC(PyTypeObject*) _PyStructSequence_NewType(
PyStructSequence_Desc *desc,
unsigned long tp_flags);
diff --git a/contrib/tools/python3/Include/internal/pycore_symtable.h b/contrib/tools/python3/Include/internal/pycore_symtable.h
index 3ff5c33efe5..90252bf8365 100644
--- a/contrib/tools/python3/Include/internal/pycore_symtable.h
+++ b/contrib/tools/python3/Include/internal/pycore_symtable.h
@@ -15,11 +15,23 @@ typedef enum _block_type {
// Used for annotations if 'from __future__ import annotations' is active.
// Annotation blocks cannot bind names and are not evaluated.
AnnotationBlock,
- // Used for generics and type aliases. These work mostly like functions
- // (see PEP 695 for details). The three different blocks function identically;
- // they are different enum entries only so that error messages can be more
- // precise.
- TypeVarBoundBlock, TypeAliasBlock, TypeParamBlock
+
+ // The following blocks are used for generics and type aliases. These work
+ // mostly like functions (see PEP 695 for details). The three different
+ // blocks function identically; they are different enum entries only so
+ // that error messages can be more precise.
+
+ // The block to enter when processing a "type" (PEP 695) construction,
+ // e.g., "type MyGeneric[T] = list[T]".
+ TypeAliasBlock,
+ // The block to enter when processing a "generic" (PEP 695) object,
+ // e.g., "def foo[T](): pass" or "class A[T]: pass".
+ TypeParametersBlock,
+ // The block to enter when processing the bound, the constraint tuple
+ // or the default value of a single "type variable" in the formal sense,
+ // i.e., a TypeVar, a TypeVarTuple or a ParamSpec object (the latter two
+ // do not support a bound or a constraint tuple).
+ TypeVariableBlock,
} _Py_block_ty;
typedef enum _comprehension_type {
@@ -29,6 +41,29 @@ typedef enum _comprehension_type {
SetComprehension = 3,
GeneratorExpression = 4 } _Py_comprehension_ty;
+/* source location information */
+typedef struct {
+ int lineno;
+ int end_lineno;
+ int col_offset;
+ int end_col_offset;
+} _Py_SourceLocation;
+
+#define SRC_LOCATION_FROM_AST(n) \
+ (_Py_SourceLocation){ \
+ .lineno = (n)->lineno, \
+ .end_lineno = (n)->end_lineno, \
+ .col_offset = (n)->col_offset, \
+ .end_col_offset = (n)->end_col_offset }
+
+static const _Py_SourceLocation NO_LOCATION = {-1, -1, -1, -1};
+
+/* __future__ information */
+typedef struct {
+ int ff_features; /* flags set by future statements */
+ _Py_SourceLocation ff_location; /* location of last future statement */
+} _PyFutureFeatures;
+
struct _symtable_entry;
struct symtable {
@@ -44,7 +79,7 @@ struct symtable {
consistency with the corresponding
compiler structure */
PyObject *st_private; /* name of current class or NULL */
- PyFutureFeatures *st_future; /* module's future features that affect
+ _PyFutureFeatures *st_future; /* module's future features that affect
the symbol table */
int recursion_depth; /* current recursion depth */
int recursion_limit; /* recursion limit */
@@ -58,7 +93,17 @@ typedef struct _symtable_entry {
PyObject *ste_varnames; /* list of function parameters */
PyObject *ste_children; /* list of child blocks */
PyObject *ste_directives;/* locations of global and nonlocal statements */
+ PyObject *ste_mangled_names; /* set of names for which mangling should be applied */
+
_Py_block_ty ste_type;
+ // Optional string set by symtable.c and used when reporting errors.
+ // The content of that string is a description of the current "context".
+ //
+ // For instance, if we are processing the default value of the type
+ // variable "T" in "def foo[T = int](): pass", `ste_scope_info` is
+ // set to "a TypeVar default".
+ const char *ste_scope_info;
+
int ste_nested; /* true if block is nested */
unsigned ste_free : 1; /* true if block has free variables */
unsigned ste_child_free : 1; /* true if a child block has free vars,
@@ -87,7 +132,6 @@ typedef struct _symtable_entry {
int ste_opt_lineno; /* lineno of last exec or import * */
int ste_opt_col_offset; /* offset of last exec or import * */
struct symtable *ste_table;
- PyObject *ste_mangled_names; /* set of names for which mangling should be applied */
} PySTEntryObject;
extern PyTypeObject PySTEntry_Type;
@@ -101,8 +145,8 @@ extern int _PyST_IsFunctionLike(PySTEntryObject *);
extern struct symtable* _PySymtable_Build(
struct _mod *mod,
PyObject *filename,
- PyFutureFeatures *future);
-PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *);
+ _PyFutureFeatures *future);
+extern PySTEntryObject* _PySymtable_Lookup(struct symtable *, void *);
extern void _PySymtable_Free(struct symtable *);
@@ -152,7 +196,7 @@ extern struct symtable* _Py_SymtableStringObjectFlags(
int _PyFuture_FromAST(
struct _mod * mod,
PyObject *filename,
- PyFutureFeatures* futures);
+ _PyFutureFeatures* futures);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_sysmodule.h b/contrib/tools/python3/Include/internal/pycore_sysmodule.h
index e76c2691002..6df574487bc 100644
--- a/contrib/tools/python3/Include/internal/pycore_sysmodule.h
+++ b/contrib/tools/python3/Include/internal/pycore_sysmodule.h
@@ -8,22 +8,26 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+PyAPI_FUNC(PyObject *) _PySys_GetAttr(PyThreadState *, PyObject *); /* unused */
PyAPI_FUNC(int) _PySys_GetOptionalAttr(PyObject *, PyObject **);
PyAPI_FUNC(int) _PySys_GetOptionalAttrString(const char *, PyObject **);
PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttr(PyObject *);
PyAPI_FUNC(PyObject *) _PySys_GetRequiredAttrString(const char *);
-PyAPI_FUNC(int) _PySys_Audit(
+// Export for '_pickle' shared extension
+PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *);
+
+extern int _PySys_Audit(
PyThreadState *tstate,
const char *event,
const char *argFormat,
...);
-/* We want minimal exposure of this function, so use extern rather than
- PyAPI_FUNC() to not export the symbol. */
+// _PySys_ClearAuditHooks() must not be exported: use extern rather than
+// PyAPI_FUNC(). We want minimal exposure of this function.
extern void _PySys_ClearAuditHooks(PyThreadState *tstate);
-PyAPI_FUNC(int) _PySys_SetAttr(PyObject *, PyObject *);
+extern int _PySys_SetAttr(PyObject *, PyObject *);
extern int _PySys_ClearAttrString(PyInterpreterState *interp,
const char *name, int verbose);
diff --git a/contrib/tools/python3/Include/internal/pycore_time.h b/contrib/tools/python3/Include/internal/pycore_time.h
index 949170c4493..205ac5d3781 100644
--- a/contrib/tools/python3/Include/internal/pycore_time.h
+++ b/contrib/tools/python3/Include/internal/pycore_time.h
@@ -1,3 +1,52 @@
+// Internal PyTime_t C API: see Doc/c-api/time.rst for the documentation.
+//
+// The PyTime_t type is an integer to support directly common arithmetic
+// operations such as t1 + t2.
+//
+// Time formats:
+//
+// * Seconds.
+// * Seconds as a floating-point number (C double).
+// * Milliseconds (10^-3 seconds).
+// * Microseconds (10^-6 seconds).
+// * 100 nanoseconds (10^-7 seconds), used on Windows.
+// * Nanoseconds (10^-9 seconds).
+// * timeval structure, 1 microsecond (10^-6 seconds).
+// * timespec structure, 1 nanosecond (10^-9 seconds).
+//
+// Note that PyTime_t is now specified as int64_t, in nanoseconds.
+// (If we need to change this, we'll need new public API with new names.)
+// Previously, PyTime_t was configurable (in theory); some comments and code
+// might still allude to that.
+//
+// Integer overflows are detected and raise OverflowError. Conversion to a
+// resolution larger than 1 nanosecond is rounded correctly with the requested
+// rounding mode. Available rounding modes:
+//
+// * Round towards minus infinity (-inf). For example, used to read a clock.
+// * Round towards infinity (+inf). For example, used for timeout to wait "at
+// least" N seconds.
+// * Round to nearest with ties going to nearest even integer. For example, used
+// to round from a Python float.
+// * Round away from zero. For example, used for timeout.
+//
+// Some functions clamp the result in the range [PyTime_MIN; PyTime_MAX]. The
+// caller doesn't have to handle errors and so doesn't need to hold the GIL to
+// handle exceptions. For example, _PyTime_Add(t1, t2) computes t1+t2 and
+// clamps the result on overflow.
+//
+// Clocks:
+//
+// * System clock
+// * Monotonic clock
+// * Performance counter
+//
+// Internally, operations like (t * k / q) with integers are implemented in a
+// way to reduce the risk of integer overflow. Such operation is used to convert a
+// clock value expressed in ticks with a frequency to PyTime_t, like
+// QueryPerformanceCounter() with QueryPerformanceFrequency() on Windows.
+
+
#ifndef Py_INTERNAL_TIME_H
#define Py_INTERNAL_TIME_H
#ifdef __cplusplus
@@ -9,17 +58,280 @@ extern "C" {
#endif
-struct _time_runtime_state {
-#ifdef HAVE_TIMES
- int ticks_per_second_initialized;
- long ticks_per_second;
-#else
- int _not_used;
+#ifdef __clang__
+struct timeval;
+#endif
+
+#define _SIZEOF_PYTIME_T 8
+
+typedef enum {
+ // Round towards minus infinity (-inf).
+ // For example, used to read a clock.
+ _PyTime_ROUND_FLOOR=0,
+
+ // Round towards infinity (+inf).
+ // For example, used for timeout to wait "at least" N seconds.
+ _PyTime_ROUND_CEILING=1,
+
+ // Round to nearest with ties going to nearest even integer.
+ // For example, used to round from a Python float.
+ _PyTime_ROUND_HALF_EVEN=2,
+
+ // Round away from zero
+ // For example, used for timeout. _PyTime_ROUND_CEILING rounds
+ // -1e-9 to 0 milliseconds which causes bpo-31786 issue.
+ // _PyTime_ROUND_UP rounds -1e-9 to -1 millisecond which keeps
+ // the timeout sign as expected. select.poll(timeout) must block
+ // for negative values.
+ _PyTime_ROUND_UP=3,
+
+ // _PyTime_ROUND_TIMEOUT (an alias for _PyTime_ROUND_UP) should be
+ // used for timeouts.
+ _PyTime_ROUND_TIMEOUT = _PyTime_ROUND_UP
+} _PyTime_round_t;
+
+
+// Convert a time_t to a PyLong.
+// Export for '_testinternalcapi' shared extension
+PyAPI_FUNC(PyObject*) _PyLong_FromTime_t(time_t sec);
+
+// Convert a PyLong to a time_t.
+// Export for '_datetime' shared extension
+PyAPI_FUNC(time_t) _PyLong_AsTime_t(PyObject *obj);
+
+// Convert a number of seconds, int or float, to time_t.
+// Export for '_datetime' shared extension.
+PyAPI_FUNC(int) _PyTime_ObjectToTime_t(
+ PyObject *obj,
+ time_t *sec,
+ _PyTime_round_t);
+
+// Convert a number of seconds, int or float, to a timeval structure.
+// usec is in the range [0; 999999] and rounded towards zero.
+// For example, -1.2 is converted to (-2, 800000).
+// Export for '_datetime' shared extension.
+PyAPI_FUNC(int) _PyTime_ObjectToTimeval(
+ PyObject *obj,
+ time_t *sec,
+ long *usec,
+ _PyTime_round_t);
+
+// Convert a number of seconds, int or float, to a timespec structure.
+// nsec is in the range [0; 999999999] and rounded towards zero.
+// For example, -1.2 is converted to (-2, 800000000).
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(int) _PyTime_ObjectToTimespec(
+ PyObject *obj,
+ time_t *sec,
+ long *nsec,
+ _PyTime_round_t);
+
+
+// Create a timestamp from a number of seconds.
+// Export for '_socket' shared extension.
+PyAPI_FUNC(PyTime_t) _PyTime_FromSeconds(int seconds);
+
+// Create a timestamp from a number of seconds in double.
+extern int _PyTime_FromSecondsDouble(
+ double seconds,
+ _PyTime_round_t round,
+ PyTime_t *result);
+
+// Macro to create a timestamp from a number of seconds, no integer overflow.
+// Only use the macro for small values, prefer _PyTime_FromSeconds().
+#define _PYTIME_FROMSECONDS(seconds) \
+ ((PyTime_t)(seconds) * (1000 * 1000 * 1000))
+
+// Create a timestamp from a number of microseconds.
+// Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
+extern PyTime_t _PyTime_FromMicrosecondsClamp(PyTime_t us);
+
+// Create a timestamp from a Python int object (number of nanoseconds).
+// Export for '_lsprof' shared extension.
+PyAPI_FUNC(int) _PyTime_FromLong(PyTime_t *t,
+ PyObject *obj);
+
+// Convert a number of seconds (Python float or int) to a timestamp.
+// Raise an exception and return -1 on error, return 0 on success.
+// Export for '_socket' shared extension.
+PyAPI_FUNC(int) _PyTime_FromSecondsObject(PyTime_t *t,
+ PyObject *obj,
+ _PyTime_round_t round);
+
+// Convert a number of milliseconds (Python float or int, 10^-3) to a timestamp.
+// Raise an exception and return -1 on error, return 0 on success.
+// Export for 'select' shared extension.
+PyAPI_FUNC(int) _PyTime_FromMillisecondsObject(PyTime_t *t,
+ PyObject *obj,
+ _PyTime_round_t round);
+
+// Convert timestamp to a number of milliseconds (10^-3 seconds).
+// Export for '_ssl' shared extension.
+PyAPI_FUNC(PyTime_t) _PyTime_AsMilliseconds(PyTime_t t,
+ _PyTime_round_t round);
+
+// Convert timestamp to a number of microseconds (10^-6 seconds).
+// Export for '_queue' shared extension.
+PyAPI_FUNC(PyTime_t) _PyTime_AsMicroseconds(PyTime_t t,
+ _PyTime_round_t round);
+
+#ifdef MS_WINDOWS
+// Convert timestamp to a number of 100 nanoseconds (10^-7 seconds).
+extern PyTime_t _PyTime_As100Nanoseconds(PyTime_t t,
+ _PyTime_round_t round);
+#endif
+
+// Convert a timestamp (number of nanoseconds) as a Python int object.
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(PyObject*) _PyTime_AsLong(PyTime_t t);
+
+#ifndef MS_WINDOWS
+// Create a timestamp from a timeval structure.
+// Raise an exception and return -1 on overflow, return 0 on success.
+extern int _PyTime_FromTimeval(PyTime_t *tp, struct timeval *tv);
+#endif
+
+// Convert a timestamp to a timeval structure (microsecond resolution).
+// tv_usec is always positive.
+// Raise an exception and return -1 if the conversion overflowed,
+// return 0 on success.
+// Export for 'select' shared extension.
+PyAPI_FUNC(int) _PyTime_AsTimeval(PyTime_t t,
+ struct timeval *tv,
+ _PyTime_round_t round);
+
+// Similar to _PyTime_AsTimeval() but don't raise an exception on overflow.
+// On overflow, clamp tv_sec to PyTime_t min/max.
+// Export for 'select' shared extension.
+PyAPI_FUNC(void) _PyTime_AsTimeval_clamp(PyTime_t t,
+ struct timeval *tv,
+ _PyTime_round_t round);
+
+// Convert a timestamp to a number of seconds (secs) and microseconds (us).
+// us is always positive. This function is similar to _PyTime_AsTimeval()
+// except that secs is always a time_t type, whereas the timeval structure
+// uses a C long for tv_sec on Windows.
+// Raise an exception and return -1 if the conversion overflowed,
+// return 0 on success.
+// Export for '_datetime' shared extension.
+PyAPI_FUNC(int) _PyTime_AsTimevalTime_t(
+ PyTime_t t,
+ time_t *secs,
+ int *us,
+ _PyTime_round_t round);
+
+#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
+// Create a timestamp from a timespec structure.
+// Raise an exception and return -1 on overflow, return 0 on success.
+extern int _PyTime_FromTimespec(PyTime_t *tp, const struct timespec *ts);
+
+// Convert a timestamp to a timespec structure (nanosecond resolution).
+// tv_nsec is always positive.
+// Raise an exception and return -1 on error, return 0 on success.
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(int) _PyTime_AsTimespec(PyTime_t t, struct timespec *ts);
+
+// Similar to _PyTime_AsTimespec() but don't raise an exception on overflow.
+// On overflow, clamp tv_sec to PyTime_t min/max.
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(void) _PyTime_AsTimespec_clamp(PyTime_t t, struct timespec *ts);
#endif
-};
+
+
+// Compute t1 + t2. Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
+extern PyTime_t _PyTime_Add(PyTime_t t1, PyTime_t t2);
+
+// Structure used by time.get_clock_info()
+typedef struct {
+ const char *implementation;
+ int monotonic;
+ int adjustable;
+ double resolution;
+} _Py_clock_info_t;
+
+// Get the current time from the system clock.
+// On success, set *t and *info (if not NULL), and return 0.
+// On error, raise an exception and return -1.
+extern int _PyTime_TimeWithInfo(
+ PyTime_t *t,
+ _Py_clock_info_t *info);
+
+// Get the time of a monotonic clock, i.e. a clock that cannot go backwards.
+// The clock is not affected by system clock updates. The reference point of
+// the returned value is undefined, so that only the difference between the
+// results of consecutive calls is valid.
+//
+// Fill info (if set) with information of the function used to get the time.
+//
+// Return 0 on success, raise an exception and return -1 on error.
+// Export for '_testsinglephase' shared extension.
+PyAPI_FUNC(int) _PyTime_MonotonicWithInfo(
+ PyTime_t *t,
+ _Py_clock_info_t *info);
+
+
+// Converts a timestamp to the Gregorian time, using the local time zone.
+// Return 0 on success, raise an exception and return -1 on error.
+// Export for '_datetime' shared extension.
+PyAPI_FUNC(int) _PyTime_localtime(time_t t, struct tm *tm);
+
+// Converts a timestamp to the Gregorian time, assuming UTC.
+// Return 0 on success, raise an exception and return -1 on error.
+// Export for '_datetime' shared extension.
+PyAPI_FUNC(int) _PyTime_gmtime(time_t t, struct tm *tm);
+
+
+// Get the performance counter: clock with the highest available resolution to
+// measure a short duration.
+//
+// Fill info (if set) with information of the function used to get the time.
+//
+// Return 0 on success, raise an exception and return -1 on error.
+extern int _PyTime_PerfCounterWithInfo(
+ PyTime_t *t,
+ _Py_clock_info_t *info);
+
+
+// --- _PyDeadline -----------------------------------------------------------
+
+// Create a deadline.
+// Pseudo code: return PyTime_MonotonicRaw() + timeout
+// Export for '_ssl' shared extension.
+PyAPI_FUNC(PyTime_t) _PyDeadline_Init(PyTime_t timeout);
+
+// Get remaining time from a deadline.
+// Pseudo code: return deadline - PyTime_MonotonicRaw()
+// Export for '_ssl' shared extension.
+PyAPI_FUNC(PyTime_t) _PyDeadline_Get(PyTime_t deadline);
+
+
+// --- _PyTimeFraction -------------------------------------------------------
+
+typedef struct {
+ PyTime_t numer;
+ PyTime_t denom;
+} _PyTimeFraction;
+
+// Set a fraction.
+// Return 0 on success.
+// Return -1 if the fraction is invalid.
+extern int _PyTimeFraction_Set(
+ _PyTimeFraction *frac,
+ PyTime_t numer,
+ PyTime_t denom);
+
+// Compute ticks * frac.numer / frac.denom.
+// Clamp to [PyTime_MIN; PyTime_MAX] on overflow.
+extern PyTime_t _PyTimeFraction_Mul(
+ PyTime_t ticks,
+ const _PyTimeFraction *frac);
+
+// Compute a clock resolution: frac.numer / frac.denom / 1e9.
+extern double _PyTimeFraction_Resolution(
+ const _PyTimeFraction *frac);
#ifdef __cplusplus
}
#endif
-#endif /* !Py_INTERNAL_TIME_H */
+#endif // !Py_INTERNAL_TIME_H
diff --git a/contrib/tools/python3/Include/internal/pycore_token.h b/contrib/tools/python3/Include/internal/pycore_token.h
index c02e637fee1..571cd6249f2 100644
--- a/contrib/tools/python3/Include/internal/pycore_token.h
+++ b/contrib/tools/python3/Include/internal/pycore_token.h
@@ -1,4 +1,4 @@
-/* Auto-generated by Tools/build/generate_token.py */
+// Auto-generated by Tools/build/generate_token.py
/* Token types */
#ifndef Py_INTERNAL_TOKEN_H
@@ -69,18 +69,16 @@ extern "C" {
#define COLONEQUAL 53
#define EXCLAMATION 54
#define OP 55
-#define AWAIT 56
-#define ASYNC 57
-#define TYPE_IGNORE 58
-#define TYPE_COMMENT 59
-#define SOFT_KEYWORD 60
-#define FSTRING_START 61
-#define FSTRING_MIDDLE 62
-#define FSTRING_END 63
-#define COMMENT 64
-#define NL 65
-#define ERRORTOKEN 66
-#define N_TOKENS 68
+#define TYPE_IGNORE 56
+#define TYPE_COMMENT 57
+#define SOFT_KEYWORD 58
+#define FSTRING_START 59
+#define FSTRING_MIDDLE 60
+#define FSTRING_END 61
+#define COMMENT 62
+#define NL 63
+#define ERRORTOKEN 64
+#define N_TOKENS 66
#define NT_OFFSET 256
/* Special definitions for cooperation with parser */
@@ -96,7 +94,7 @@ extern "C" {
(x) == FSTRING_MIDDLE)
-// Symbols exported for test_peg_generator
+// Export these 4 symbols for 'test_peg_generator'
PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */
PyAPI_FUNC(int) _PyToken_OneChar(int);
PyAPI_FUNC(int) _PyToken_TwoChars(int, int);
diff --git a/contrib/tools/python3/Include/internal/pycore_traceback.h b/contrib/tools/python3/Include/internal/pycore_traceback.h
index c393b2c136f..10922bff98b 100644
--- a/contrib/tools/python3/Include/internal/pycore_traceback.h
+++ b/contrib/tools/python3/Include/internal/pycore_traceback.h
@@ -8,6 +8,12 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+// Export for '_ctypes' shared extension
+PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int, int *, PyObject **);
+
+// Export for 'pyexact' shared extension
+PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int);
+
/* Write the Python traceback into the file 'fd'. For example:
Traceback (most recent call first):
@@ -25,7 +31,7 @@ extern "C" {
This function is signal safe. */
-PyAPI_FUNC(void) _Py_DumpTraceback(
+extern void _Py_DumpTraceback(
int fd,
PyThreadState *tstate);
@@ -52,7 +58,7 @@ PyAPI_FUNC(void) _Py_DumpTraceback(
This function is signal safe. */
-PyAPI_FUNC(const char*) _Py_DumpTracebackThreads(
+extern const char* _Py_DumpTracebackThreads(
int fd,
PyInterpreterState *interp,
PyThreadState *current_tstate);
@@ -64,23 +70,23 @@ PyAPI_FUNC(const char*) _Py_DumpTracebackThreads(
string which is not ready (PyUnicode_WCHAR_KIND).
This function is signal safe. */
-PyAPI_FUNC(void) _Py_DumpASCII(int fd, PyObject *text);
+extern void _Py_DumpASCII(int fd, PyObject *text);
/* Format an integer as decimal into the file descriptor fd.
This function is signal safe. */
-PyAPI_FUNC(void) _Py_DumpDecimal(
+extern void _Py_DumpDecimal(
int fd,
size_t value);
/* Format an integer as hexadecimal with width digits into fd file descriptor.
The function is signal safe. */
-PyAPI_FUNC(void) _Py_DumpHexadecimal(
+extern void _Py_DumpHexadecimal(
int fd,
uintptr_t value,
Py_ssize_t width);
-PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame(
+extern PyObject* _PyTraceBack_FromFrame(
PyObject *tb_next,
PyFrameObject *frame);
@@ -89,11 +95,10 @@ PyAPI_FUNC(PyObject*) _PyTraceBack_FromFrame(
/* Write the traceback tb to file f. Prefix each line with
indent spaces followed by the margin (if it is not NULL). */
-PyAPI_FUNC(int) _PyTraceBack_Print_Indented(
- PyObject *tb, int indent, const char* margin,
- const char *header_margin, const char *header, PyObject *f);
-PyAPI_FUNC(int) _Py_WriteIndentedMargin(int, const char*, PyObject *);
-PyAPI_FUNC(int) _Py_WriteIndent(int, PyObject *);
+extern int _PyTraceBack_Print(
+ PyObject *tb, const char *header, PyObject *f);
+extern int _Py_WriteIndentedMargin(int, const char*, PyObject *);
+extern int _Py_WriteIndent(int, PyObject *);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_tracemalloc.h b/contrib/tools/python3/Include/internal/pycore_tracemalloc.h
index d086adc61c3..f70d47074f8 100644
--- a/contrib/tools/python3/Include/internal/pycore_tracemalloc.h
+++ b/contrib/tools/python3/Include/internal/pycore_tracemalloc.h
@@ -117,6 +117,53 @@ struct _tracemalloc_runtime_state {
}
+// Get the traceback where a memory block was allocated.
+//
+// Return a tuple of (filename: str, lineno: int) tuples.
+//
+// Return None if the tracemalloc module is disabled or if the memory block
+// is not tracked by tracemalloc.
+//
+// Raise an exception and return NULL on error.
+//
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback(
+ unsigned int domain,
+ uintptr_t ptr);
+
+/* Return non-zero if tracemalloc is tracing */
+extern int _PyTraceMalloc_IsTracing(void);
+
+/* Clear the tracemalloc traces */
+extern void _PyTraceMalloc_ClearTraces(void);
+
+/* Clear the tracemalloc traces */
+extern PyObject* _PyTraceMalloc_GetTraces(void);
+
+/* Clear tracemalloc traceback for an object */
+extern PyObject* _PyTraceMalloc_GetObjectTraceback(PyObject *obj);
+
+/* Initialize tracemalloc */
+extern PyStatus _PyTraceMalloc_Init(void);
+
+/* Start tracemalloc */
+extern int _PyTraceMalloc_Start(int max_nframe);
+
+/* Stop tracemalloc */
+extern void _PyTraceMalloc_Stop(void);
+
+/* Get the tracemalloc traceback limit */
+extern int _PyTraceMalloc_GetTracebackLimit(void);
+
+/* Get the memory usage of tracemalloc in bytes */
+extern size_t _PyTraceMalloc_GetMemory(void);
+
+/* Get the current size and peak size of traced memory blocks as a 2-tuple */
+extern PyObject* _PyTraceMalloc_GetTracedMemory(void);
+
+/* Set the peak size of traced memory blocks to the current size */
+extern void _PyTraceMalloc_ResetPeak(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_tstate.h b/contrib/tools/python3/Include/internal/pycore_tstate.h
new file mode 100644
index 00000000000..1ed5b1d826a
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_tstate.h
@@ -0,0 +1,46 @@
+#ifndef Py_INTERNAL_TSTATE_H
+#define Py_INTERNAL_TSTATE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_brc.h" // struct _brc_thread_state
+#include "pycore_freelist.h" // struct _Py_freelist_state
+#include "pycore_mimalloc.h" // struct _mimalloc_thread_state
+#include "pycore_qsbr.h" // struct qsbr
+
+
+// Every PyThreadState is actually allocated as a _PyThreadStateImpl. The
+// PyThreadState fields are exposed as part of the C API, although most fields
+// are intended to be private. The _PyThreadStateImpl fields not exposed.
+typedef struct _PyThreadStateImpl {
+ // semi-public fields are in PyThreadState.
+ PyThreadState base;
+
+ PyObject *asyncio_running_loop; // Strong reference
+
+ struct _qsbr_thread_state *qsbr; // only used by free-threaded build
+ struct llist_node mem_free_queue; // delayed free queue
+
+#ifdef Py_GIL_DISABLED
+ struct _gc_thread_state gc;
+ struct _mimalloc_thread_state mimalloc;
+ struct _Py_object_freelists freelists;
+ struct _brc_thread_state brc;
+#endif
+
+#if defined(Py_REF_DEBUG) && defined(Py_GIL_DISABLED)
+ Py_ssize_t reftotal; // this thread's total refcount operations
+#endif
+
+} _PyThreadStateImpl;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_TSTATE_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_tuple.h b/contrib/tools/python3/Include/internal/pycore_tuple.h
index 335edad8979..14a9e42c3a3 100644
--- a/contrib/tools/python3/Include/internal/pycore_tuple.h
+++ b/contrib/tools/python3/Include/internal/pycore_tuple.h
@@ -8,64 +8,20 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "tupleobject.h" /* _PyTuple_CAST() */
-
+extern void _PyTuple_MaybeUntrack(PyObject *);
+extern void _PyTuple_DebugMallocStats(FILE *out);
/* runtime lifecycle */
extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *);
-extern void _PyTuple_Fini(PyInterpreterState *);
/* other API */
-// PyTuple_MAXSAVESIZE - largest tuple to save on free list
-// PyTuple_MAXFREELIST - maximum number of tuples of each size to save
-
-#if defined(PyTuple_MAXSAVESIZE) && PyTuple_MAXSAVESIZE <= 0
- // A build indicated that tuple freelists should not be used.
-# define PyTuple_NFREELISTS 0
-# undef PyTuple_MAXSAVESIZE
-# undef PyTuple_MAXFREELIST
-
-#elif !defined(WITH_FREELISTS)
-# define PyTuple_NFREELISTS 0
-# undef PyTuple_MAXSAVESIZE
-# undef PyTuple_MAXFREELIST
-
-#else
- // We are using a freelist for tuples.
-# ifndef PyTuple_MAXSAVESIZE
-# define PyTuple_MAXSAVESIZE 20
-# endif
-# define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE
-# ifndef PyTuple_MAXFREELIST
-# define PyTuple_MAXFREELIST 2000
-# endif
-#endif
-
-struct _Py_tuple_state {
-#if PyTuple_NFREELISTS > 0
- /* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE.
- The empty tuple is handled separately.
-
- Each tuple stored in the array is the head of the linked list
- (and the next available tuple) for that size. The actual tuple
- object is used as the linked list node, with its first item
- (ob_item[0]) pointing to the next node (i.e. the previous head).
- Each linked list is initially NULL. */
- PyTupleObject *free_list[PyTuple_NFREELISTS];
- int numfree[PyTuple_NFREELISTS];
-#else
- char _unused; // Empty structs are not allowed.
-#endif
-};
-
#define _PyTuple_ITEMS(op) _Py_RVALUE(_PyTuple_CAST(op)->ob_item)
extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t);
-extern PyObject *_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t);
-
+PyAPI_FUNC(PyObject *)_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t);
typedef struct {
PyObject_HEAD
diff --git a/contrib/tools/python3/Include/internal/pycore_typeobject.h b/contrib/tools/python3/Include/internal/pycore_typeobject.h
index 4fdbc91a1ba..164b243dae7 100644
--- a/contrib/tools/python3/Include/internal/pycore_typeobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_typeobject.h
@@ -4,23 +4,38 @@
extern "C" {
#endif
-#include "pycore_moduleobject.h"
-
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_moduleobject.h" // PyModuleObject
+#include "pycore_lock.h" // PyMutex
+
/* state */
#define _Py_TYPE_BASE_VERSION_TAG (2<<16)
#define _Py_MAX_GLOBAL_TYPE_VERSION_TAG (_Py_TYPE_BASE_VERSION_TAG - 1)
+/* For now we hard-code this to a value for which we are confident
+ all the static builtin types will fit (for all builds). */
+#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 200
+#define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10
+#define _Py_MAX_MANAGED_STATIC_TYPES \
+ (_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES + _Py_MAX_MANAGED_STATIC_EXT_TYPES)
+
struct _types_runtime_state {
/* Used to set PyTypeObject.tp_version_tag for core static types. */
// bpo-42745: next_version_tag remains shared by all interpreters
// because of static types.
unsigned int next_version_tag;
+
+ struct {
+ struct {
+ PyTypeObject *type;
+ int64_t interp_count;
+ } types[_Py_MAX_MANAGED_STATIC_TYPES];
+ } managed_static;
};
@@ -28,6 +43,9 @@ struct _types_runtime_state {
// see _PyType_Lookup().
struct type_cache_entry {
unsigned int version; // initialized from type->tp_version_tag
+#ifdef Py_GIL_DISABLED
+ _PySeqLock sequence;
+#endif
PyObject *name; // reference to exactly a str or None
PyObject *value; // borrowed reference or NULL
};
@@ -38,12 +56,9 @@ struct type_cache {
struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP];
};
-/* For now we hard-code this to a value for which we are confident
- all the static builtin types will fit (for all builds). */
-#define _Py_MAX_STATIC_BUILTIN_TYPES 200
-
typedef struct {
PyTypeObject *type;
+ int isbuiltin;
int readying;
int ready;
// XXX tp_dict can probably be statically allocated,
@@ -55,7 +70,7 @@ typedef struct {
are also some diagnostic uses for the list of weakrefs,
so we still keep it. */
PyObject *tp_weaklist;
-} static_builtin_state;
+} managed_static_type_state;
struct types_state {
/* Used to set PyTypeObject.tp_version_tag.
@@ -64,8 +79,54 @@ struct types_state {
unsigned int next_version_tag;
struct type_cache type_cache;
- size_t num_builtins_initialized;
- static_builtin_state builtins[_Py_MAX_STATIC_BUILTIN_TYPES];
+
+ /* Every static builtin type is initialized for each interpreter
+ during its own initialization, including for the main interpreter
+ during global runtime initialization. This is done by calling
+ _PyStaticType_InitBuiltin().
+
+ The first time a static builtin type is initialized, all the
+ normal PyType_Ready() stuff happens. The only difference from
+ normal is that there are three PyTypeObject fields holding
+ objects which are stored here (on PyInterpreterState) rather
+ than in the corresponding PyTypeObject fields. Those are:
+ tp_dict (cls.__dict__), tp_subclasses (cls.__subclasses__),
+ and tp_weaklist.
+
+ When a subinterpreter is initialized, each static builtin type
+ is still initialized, but only the interpreter-specific portion,
+ namely those three objects.
+
+ Those objects are stored in the PyInterpreterState.types.builtins
+ array, at the index corresponding to each specific static builtin
+ type. That index (a size_t value) is stored in the tp_subclasses
+ field. For static builtin types, we re-purposed the now-unused
+ tp_subclasses to avoid adding another field to PyTypeObject.
+ In all other cases tp_subclasses holds a dict like before.
+ (The field was previously defined as PyObject*, but is now void*
+ to reflect its dual use.)
+
+ The index for each static builtin type isn't statically assigned.
+ Instead it is calculated the first time a type is initialized
+ (by the main interpreter). The index matches the order in which
+ the type was initialized relative to the others. The actual
+ value comes from the current value of num_builtins_initialized,
+ as each type is initialized for the main interpreter.
+
+ num_builtins_initialized is incremented once for each static
+ builtin type. Once initialization is over for a subinterpreter,
+ the value will be the same as for all other interpreters. */
+ struct {
+ size_t num_initialized;
+ managed_static_type_state initialized[_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES];
+ } builtins;
+ /* We apply a similar strategy for managed extension modules. */
+ struct {
+ size_t num_initialized;
+ size_t next_index;
+ managed_static_type_state initialized[_Py_MAX_MANAGED_STATIC_EXT_TYPES];
+ } for_extensions;
+ PyMutex mutex;
};
@@ -73,8 +134,9 @@ struct types_state {
extern PyStatus _PyTypes_InitTypes(PyInterpreterState *);
extern void _PyTypes_FiniTypes(PyInterpreterState *);
+extern void _PyTypes_FiniExtTypes(PyInterpreterState *interp);
extern void _PyTypes_Fini(PyInterpreterState *);
-
+extern void _PyTypes_AfterFork(void);
/* other API */
@@ -88,12 +150,31 @@ typedef struct wrapperbase pytype_slotdef;
static inline PyObject **
-_PyStaticType_GET_WEAKREFS_LISTPTR(static_builtin_state *state)
+_PyStaticType_GET_WEAKREFS_LISTPTR(managed_static_type_state *state)
{
assert(state != NULL);
return &state->tp_weaklist;
}
+extern int _PyStaticType_InitBuiltin(
+ PyInterpreterState *interp,
+ PyTypeObject *type);
+extern void _PyStaticType_FiniBuiltin(
+ PyInterpreterState *interp,
+ PyTypeObject *type);
+extern void _PyStaticType_ClearWeakRefs(
+ PyInterpreterState *interp,
+ PyTypeObject *type);
+extern managed_static_type_state * _PyStaticType_GetState(
+ PyInterpreterState *interp,
+ PyTypeObject *type);
+
+// Export for '_datetime' shared extension.
+PyAPI_FUNC(int) _PyStaticType_InitForExtension(
+ PyInterpreterState *interp,
+ PyTypeObject *self);
+
+
/* Like PyType_GetModuleState, but skips verification
* that type is a heap type with an associated module */
static inline void *
@@ -109,16 +190,16 @@ _PyType_GetModuleState(PyTypeObject *type)
}
-extern int _PyStaticType_InitBuiltin(PyInterpreterState *, PyTypeObject *type);
-extern static_builtin_state * _PyStaticType_GetState(PyInterpreterState *, PyTypeObject *);
-extern void _PyStaticType_ClearWeakRefs(PyInterpreterState *, PyTypeObject *type);
-extern void _PyStaticType_Dealloc(PyInterpreterState *, PyTypeObject *);
-
+// Export for 'math' shared extension, used via _PyType_IsReady() static inline
+// function
PyAPI_FUNC(PyObject *) _PyType_GetDict(PyTypeObject *);
+
extern PyObject * _PyType_GetBases(PyTypeObject *type);
extern PyObject * _PyType_GetMRO(PyTypeObject *type);
extern PyObject* _PyType_GetSubclasses(PyTypeObject *);
extern int _PyType_HasSubclasses(PyTypeObject *);
+PyAPI_FUNC(PyObject *) _PyType_GetModuleByDef2(PyTypeObject *, PyTypeObject *, PyModuleDef *);
+PyAPI_FUNC(PyObject *) _PyType_GetModuleByDef3(PyTypeObject *, PyTypeObject *, PyTypeObject *, PyModuleDef *);
// PyType_Ready() must be called if _PyType_IsReady() is false.
// See also the Py_TPFLAGS_READY flag.
@@ -128,23 +209,36 @@ _PyType_IsReady(PyTypeObject *type)
return _PyType_GetDict(type) != NULL;
}
-PyObject *
-_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute);
-PyObject *
-_Py_type_getattro(PyTypeObject *type, PyObject *name);
+extern PyObject* _Py_type_getattro_impl(PyTypeObject *type, PyObject *name,
+ int *suppress_missing_attribute);
+extern PyObject* _Py_type_getattro(PyObject *type, PyObject *name);
extern PyObject* _Py_BaseObject_RichCompare(PyObject* self, PyObject* other, int op);
-PyObject *_Py_slot_tp_getattro(PyObject *self, PyObject *name);
-PyObject *_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name);
+extern PyObject* _Py_slot_tp_getattro(PyObject *self, PyObject *name);
+extern PyObject* _Py_slot_tp_getattr_hook(PyObject *self, PyObject *name);
-PyAPI_DATA(PyTypeObject) _PyBufferWrapper_Type;
+extern PyTypeObject _PyBufferWrapper_Type;
-PyObject *
-_PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *meth_found);
+PyAPI_FUNC(PyObject*) _PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj,
+ PyObject *name, int *meth_found);
+extern PyObject* _PyType_GetFullyQualifiedName(PyTypeObject *type, char sep);
+
+// Perform the following operation, in a thread-safe way when required by the
+// build mode.
+//
+// self->tp_flags = (self->tp_flags & ~mask) | flags;
+extern void _PyType_SetFlags(PyTypeObject *self, unsigned long mask,
+ unsigned long flags);
extern int _PyType_AddMethod(PyTypeObject *, PyMethodDef *);
+// Like _PyType_SetFlags(), but apply the operation to self and any of its
+// subclasses without Py_TPFLAGS_IMMUTABLETYPE set.
+extern void _PyType_SetFlagsRecursive(PyTypeObject *self, unsigned long mask,
+ unsigned long flags);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_typevarobject.h b/contrib/tools/python3/Include/internal/pycore_typevarobject.h
index c9fa97d6820..a368edebd62 100644
--- a/contrib/tools/python3/Include/internal/pycore_typevarobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_typevarobject.h
@@ -13,10 +13,13 @@ extern PyObject *_Py_make_paramspec(PyThreadState *, PyObject *);
extern PyObject *_Py_make_typevartuple(PyThreadState *, PyObject *);
extern PyObject *_Py_make_typealias(PyThreadState *, PyObject *);
extern PyObject *_Py_subscript_generic(PyThreadState *, PyObject *);
+extern PyObject *_Py_set_typeparam_default(PyThreadState *, PyObject *, PyObject *);
extern int _Py_initialize_generic(PyInterpreterState *);
extern void _Py_clear_generic_types(PyInterpreterState *);
extern PyTypeObject _PyTypeAlias_Type;
+extern PyTypeObject _PyNoDefault_Type;
+extern PyObject _Py_NoDefaultStruct;
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_ucnhash.h b/contrib/tools/python3/Include/internal/pycore_ucnhash.h
index 187dd68e734..1561dfbb315 100644
--- a/contrib/tools/python3/Include/internal/pycore_ucnhash.h
+++ b/contrib/tools/python3/Include/internal/pycore_ucnhash.h
@@ -28,6 +28,8 @@ typedef struct {
} _PyUnicode_Name_CAPI;
+extern _PyUnicode_Name_CAPI* _PyUnicode_GetNameCAPI(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/contrib/tools/python3/Include/internal/pycore_unicodeobject.h b/contrib/tools/python3/Include/internal/pycore_unicodeobject.h
index cecdabe4155..5ebc7c120fc 100644
--- a/contrib/tools/python3/Include/internal/pycore_unicodeobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_unicodeobject.h
@@ -8,25 +8,289 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_lock.h" // PyMutex
#include "pycore_fileutils.h" // _Py_error_handler
+#include "pycore_identifier.h" // _Py_Identifier
#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI
+#include "pycore_global_objects.h" // _Py_SINGLETON
-void _PyUnicode_ExactDealloc(PyObject *op);
-Py_ssize_t _PyUnicode_InternedSize(void);
-Py_ssize_t _PyUnicode_InternedSize_Immortal(void);
+/* --- Characters Type APIs ----------------------------------------------- */
-/* runtime lifecycle */
+extern int _PyUnicode_IsXidStart(Py_UCS4 ch);
+extern int _PyUnicode_IsXidContinue(Py_UCS4 ch);
+extern int _PyUnicode_ToLowerFull(Py_UCS4 ch, Py_UCS4 *res);
+extern int _PyUnicode_ToTitleFull(Py_UCS4 ch, Py_UCS4 *res);
+extern int _PyUnicode_ToUpperFull(Py_UCS4 ch, Py_UCS4 *res);
+extern int _PyUnicode_ToFoldedFull(Py_UCS4 ch, Py_UCS4 *res);
+extern int _PyUnicode_IsCaseIgnorable(Py_UCS4 ch);
+extern int _PyUnicode_IsCased(Py_UCS4 ch);
+
+/* --- Unicode API -------------------------------------------------------- */
+
+// Export for '_json' shared extension
+PyAPI_FUNC(int) _PyUnicode_CheckConsistency(
+ PyObject *op,
+ int check_content);
+
+PyAPI_FUNC(void) _PyUnicode_ExactDealloc(PyObject *op);
+extern Py_ssize_t _PyUnicode_InternedSize(void);
+extern Py_ssize_t _PyUnicode_InternedSize_Immortal(void);
+
+// Get a copy of a Unicode string.
+// Export for '_datetime' shared extension.
+PyAPI_FUNC(PyObject*) _PyUnicode_Copy(
+ PyObject *unicode);
+
+/* Unsafe version of PyUnicode_Fill(): don't check arguments and so may crash
+ if parameters are invalid (e.g. if length is longer than the string). */
+extern void _PyUnicode_FastFill(
+ PyObject *unicode,
+ Py_ssize_t start,
+ Py_ssize_t length,
+ Py_UCS4 fill_char
+ );
+
+/* Unsafe version of PyUnicode_CopyCharacters(): don't check arguments and so
+ may crash if parameters are invalid (e.g. if the output string
+ is too short). */
+extern void _PyUnicode_FastCopyCharacters(
+ PyObject *to,
+ Py_ssize_t to_start,
+ PyObject *from,
+ Py_ssize_t from_start,
+ Py_ssize_t how_many
+ );
+
+/* Create a new string from a buffer of ASCII characters.
+ WARNING: Don't check if the string contains any non-ASCII character. */
+extern PyObject* _PyUnicode_FromASCII(
+ const char *buffer,
+ Py_ssize_t size);
+
+/* Compute the maximum character of the substring unicode[start:end].
+ Return 127 for an empty string. */
+extern Py_UCS4 _PyUnicode_FindMaxChar (
+ PyObject *unicode,
+ Py_ssize_t start,
+ Py_ssize_t end);
+
+/* --- _PyUnicodeWriter API ----------------------------------------------- */
+
+/* Format the object based on the format_spec, as defined in PEP 3101
+ (Advanced String Formatting). */
+extern int _PyUnicode_FormatAdvancedWriter(
+ _PyUnicodeWriter *writer,
+ PyObject *obj,
+ PyObject *format_spec,
+ Py_ssize_t start,
+ Py_ssize_t end);
+
+/* --- UTF-7 Codecs ------------------------------------------------------- */
+
+extern PyObject* _PyUnicode_EncodeUTF7(
+ PyObject *unicode, /* Unicode object */
+ int base64SetO, /* Encode RFC2152 Set O characters in base64 */
+ int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */
+ const char *errors); /* error handling */
+
+/* --- UTF-8 Codecs ------------------------------------------------------- */
+
+// Export for '_tkinter' shared extension.
+PyAPI_FUNC(PyObject*) _PyUnicode_AsUTF8String(
+ PyObject *unicode,
+ const char *errors);
+
+/* --- UTF-32 Codecs ------------------------------------------------------ */
+
+// Export for '_tkinter' shared extension
+PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF32(
+ PyObject *object, /* Unicode object */
+ const char *errors, /* error handling */
+ int byteorder); /* byteorder to use 0=BOM+native;-1=LE,1=BE */
+
+/* --- UTF-16 Codecs ------------------------------------------------------ */
+
+// Returns a Python string object holding the UTF-16 encoded value of
+// the Unicode data.
+//
+// If byteorder is not 0, output is written according to the following
+// byte order:
+//
+// byteorder == -1: little endian
+// byteorder == 0: native byte order (writes a BOM mark)
+// byteorder == 1: big endian
+//
+// If byteorder is 0, the output string will always start with the
+// Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is
+// prepended.
+//
+// Export for '_tkinter' shared extension
+PyAPI_FUNC(PyObject*) _PyUnicode_EncodeUTF16(
+ PyObject* unicode, /* Unicode object */
+ const char *errors, /* error handling */
+ int byteorder); /* byteorder to use 0=BOM+native;-1=LE,1=BE */
+
+/* --- Unicode-Escape Codecs ---------------------------------------------- */
+
+/* Variant of PyUnicode_DecodeUnicodeEscape that supports partial decoding. */
+extern PyObject* _PyUnicode_DecodeUnicodeEscapeStateful(
+ const char *string, /* Unicode-Escape encoded string */
+ Py_ssize_t length, /* size of string */
+ const char *errors, /* error handling */
+ Py_ssize_t *consumed); /* bytes consumed */
+
+// Helper for PyUnicode_DecodeUnicodeEscape that detects invalid escape
+// chars.
+// Export for test_peg_generator.
+PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal2(
+ const char *string, /* Unicode-Escape encoded string */
+ Py_ssize_t length, /* size of string */
+ const char *errors, /* error handling */
+ Py_ssize_t *consumed, /* bytes consumed */
+ int *first_invalid_escape_char, /* on return, if not -1, contain the first
+ invalid escaped char (<= 0xff) or invalid
+ octal escape (> 0xff) in string. */
+ const char **first_invalid_escape_ptr); /* on return, if not NULL, may
+ point to the first invalid escaped
+ char in string.
+ May be NULL if errors is not NULL. */
+// Export for binary compatibility.
+PyAPI_FUNC(PyObject*) _PyUnicode_DecodeUnicodeEscapeInternal(
+ const char *string, /* Unicode-Escape encoded string */
+ Py_ssize_t length, /* size of string */
+ const char *errors, /* error handling */
+ Py_ssize_t *consumed, /* bytes consumed */
+ const char **first_invalid_escape); /* on return, points to first
+ invalid escaped char in
+ string. */
+
+/* --- Raw-Unicode-Escape Codecs ---------------------------------------------- */
+
+/* Variant of PyUnicode_DecodeRawUnicodeEscape that supports partial decoding. */
+extern PyObject* _PyUnicode_DecodeRawUnicodeEscapeStateful(
+ const char *string, /* Unicode-Escape encoded string */
+ Py_ssize_t length, /* size of string */
+ const char *errors, /* error handling */
+ Py_ssize_t *consumed); /* bytes consumed */
+
+/* --- Latin-1 Codecs ----------------------------------------------------- */
+
+extern PyObject* _PyUnicode_AsLatin1String(
+ PyObject* unicode,
+ const char* errors);
+
+/* --- ASCII Codecs ------------------------------------------------------- */
+
+extern PyObject* _PyUnicode_AsASCIIString(
+ PyObject* unicode,
+ const char* errors);
+
+/* --- Character Map Codecs ----------------------------------------------- */
+
+/* Translate an Unicode object by applying a character mapping table to
+ it and return the resulting Unicode object.
+
+ The mapping table must map Unicode ordinal integers to Unicode strings,
+ Unicode ordinal integers or None (causing deletion of the character).
+
+ Mapping tables may be dictionaries or sequences. Unmapped character
+ ordinals (ones which cause a LookupError) are left untouched and
+ are copied as-is.
+*/
+extern PyObject* _PyUnicode_EncodeCharmap(
+ PyObject *unicode, /* Unicode object */
+ PyObject *mapping, /* encoding mapping */
+ const char *errors); /* error handling */
+
+/* --- Decimal Encoder ---------------------------------------------------- */
+
+// Coverts a Unicode object holding a decimal value to an ASCII string
+// for using in int, float and complex parsers.
+// Transforms code points that have decimal digit property to the
+// corresponding ASCII digit code points. Transforms spaces to ASCII.
+// Transforms code points starting from the first non-ASCII code point that
+// is neither a decimal digit nor a space to the end into '?'.
+//
+// Export for '_testinternalcapi' shared extension.
+PyAPI_FUNC(PyObject*) _PyUnicode_TransformDecimalAndSpaceToASCII(
+ PyObject *unicode); /* Unicode object */
+
+/* --- Methods & Slots ---------------------------------------------------- */
+
+PyAPI_FUNC(PyObject*) _PyUnicode_JoinArray(
+ PyObject *separator,
+ PyObject *const *items,
+ Py_ssize_t seqlen
+ );
+
+/* Test whether a unicode is equal to ASCII identifier. Return 1 if true,
+ 0 otherwise. The right argument must be ASCII identifier.
+ Any error occurs inside will be cleared before return. */
+extern int _PyUnicode_EqualToASCIIId(
+ PyObject *left, /* Left string */
+ _Py_Identifier *right /* Right identifier */
+ );
+
+// Test whether a unicode is equal to ASCII string. Return 1 if true,
+// 0 otherwise. The right argument must be ASCII-encoded string.
+// Any error occurs inside will be cleared before return.
+// Export for '_ctypes' shared extension
+PyAPI_FUNC(int) _PyUnicode_EqualToASCIIString(
+ PyObject *left,
+ const char *right /* ASCII-encoded string */
+ );
+
+/* Externally visible for str.strip(unicode) */
+extern PyObject* _PyUnicode_XStrip(
+ PyObject *self,
+ int striptype,
+ PyObject *sepobj
+ );
+
+
+/* Using explicit passed-in values, insert the thousands grouping
+ into the string pointed to by buffer. For the argument descriptions,
+ see Objects/stringlib/localeutil.h */
+extern Py_ssize_t _PyUnicode_InsertThousandsGrouping(
+ _PyUnicodeWriter *writer,
+ Py_ssize_t n_buffer,
+ PyObject *digits,
+ Py_ssize_t d_pos,
+ Py_ssize_t n_digits,
+ Py_ssize_t min_width,
+ const char *grouping,
+ PyObject *thousands_sep,
+ Py_UCS4 *maxchar);
+
+/* --- Misc functions ----------------------------------------------------- */
+
+extern PyObject* _PyUnicode_FormatLong(PyObject *, int, int, int);
+
+/* Fast equality check when the inputs are known to be exact unicode types
+ and where the hash values are equal (i.e. a very probable match) */
+extern int _PyUnicode_EQ(PyObject *, PyObject *);
+
+// Equality check.
+// Export for '_pickle' shared extension.
+PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *, PyObject *);
+
+extern int _PyUnicode_WideCharString_Converter(PyObject *, void *);
+extern int _PyUnicode_WideCharString_Opt_Converter(PyObject *, void *);
+
+// Export for test_peg_generator
+PyAPI_FUNC(Py_ssize_t) _PyUnicode_ScanIdentifier(PyObject *);
+
+/* --- Runtime lifecycle -------------------------------------------------- */
extern void _PyUnicode_InitState(PyInterpreterState *);
extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *);
-extern PyStatus _PyUnicode_InitInternDict(PyInterpreterState *);
extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *);
extern void _PyUnicode_Fini(PyInterpreterState *);
extern void _PyUnicode_FiniTypes(PyInterpreterState *);
extern PyTypeObject _PyUnicodeASCIIIter_Type;
-/* Interning */
+/* --- Interning ---------------------------------------------------------- */
// All these are "ref-neutral", like the public PyUnicode_InternInPlace.
@@ -35,13 +299,13 @@ PyAPI_FUNC(void) _PyUnicode_InternMortal(PyInterpreterState *interp, PyObject **
PyAPI_FUNC(void) _PyUnicode_InternImmortal(PyInterpreterState *interp, PyObject **);
// Left here to help backporting:
PyAPI_FUNC(void) _PyUnicode_InternInPlace(PyInterpreterState *interp, PyObject **p);
-// Only for statically allocated strings:
+// Only for singletons in the _PyRuntime struct:
extern void _PyUnicode_InternStatic(PyInterpreterState *interp, PyObject **);
-/* other API */
+/* --- Other API ---------------------------------------------------------- */
struct _Py_unicode_runtime_ids {
- PyThread_type_lock lock;
+ PyMutex mutex;
// next_index value must be preserved when Py_Initialize()/Py_Finalize()
// is called multiple times: see _PyUnicode_FromId() implementation.
Py_ssize_t next_index;
@@ -77,7 +341,8 @@ struct _Py_unicode_state {
extern void _PyUnicode_ClearInterned(PyInterpreterState *interp);
// Like PyUnicode_AsUTF8(), but check for embedded null characters.
-extern const char* _PyUnicode_AsUTF8NoNUL(PyObject *);
+// Export for '_sqlite3' shared extension.
+PyAPI_FUNC(const char *) _PyUnicode_AsUTF8NoNUL(PyObject *);
#ifdef __cplusplus
diff --git a/contrib/tools/python3/Include/internal/pycore_unicodeobject_generated.h b/contrib/tools/python3/Include/internal/pycore_unicodeobject_generated.h
index 90c61bcd090..7f6b6e07984 100644
--- a/contrib/tools/python3/Include/internal/pycore_unicodeobject_generated.h
+++ b/contrib/tools/python3/Include/internal/pycore_unicodeobject_generated.h
@@ -104,10 +104,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_ID(__asyncio_running_event_loop__);
- _PyUnicode_InternStatic(interp, &string);
- assert(_PyUnicode_CheckConsistency(string, 1));
- assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(__await__);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -232,6 +228,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(__firstlineno__);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(__float__);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -412,6 +412,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(__match_args__);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(__matmul__);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -628,6 +632,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(__static_attributes__);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(__str__);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -700,6 +708,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(_align_);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(_annotation);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -740,6 +752,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(_field_types);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(_fields_);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -824,6 +840,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(_strptime);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(_strptime_datetime);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -856,6 +876,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(aclose);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(add);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -880,6 +904,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(allow_code);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(append);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -908,10 +936,18 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(asend);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(ast);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(athrow);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(attribute);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1004,6 +1040,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(cached_datetime_module);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(cached_statements);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1028,6 +1068,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(callback);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(cancel);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1148,6 +1192,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(col_offset);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(command);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1208,6 +1256,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(day);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(decode);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1232,6 +1284,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(desired_access);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(detect_types);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1304,10 +1360,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_ID(duration);
- _PyUnicode_InternStatic(interp, &string);
- assert(_PyUnicode_CheckConsistency(string, 1));
- assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(eager_start);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1332,6 +1384,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(end_col_offset);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(end_lineno);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1456,6 +1512,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(filter);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(filters);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1480,15 +1540,15 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_ID(follow_symlinks);
+ string = &_Py_ID(fold);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_ID(format);
+ string = &_Py_ID(follow_symlinks);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_ID(frequency);
+ string = &_Py_ID(format);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
@@ -1576,6 +1636,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(handle_seq);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(has_location);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(hash_name);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1596,7 +1664,7 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_ID(id);
+ string = &_Py_ID(hour);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
@@ -1604,6 +1672,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(identity_hint);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(ignore);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1636,6 +1708,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(inherit_handle);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(inheritable);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1648,6 +1724,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(initial_owner);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(initial_state);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(initial_value);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1684,6 +1768,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(interval);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(is_running);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1768,6 +1856,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(kwdefaults);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(label);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(lambda);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1860,6 +1956,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(manual_reset);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(mapping);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1880,6 +1980,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(maxlen);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(maxmem);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1916,6 +2020,18 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(microsecond);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(milliseconds);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(minute);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(mod);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1936,6 +2052,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(month);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(mro);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1944,6 +2064,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(mutex);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(mycmp);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -1988,6 +2112,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(nested);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(new_file_name);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2336,6 +2464,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(second);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(security_attributes);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(seek);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2436,10 +2572,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_ID(sound);
- _PyUnicode_InternStatic(interp, &string);
- assert(_PyUnicode_CheckConsistency(string, 1));
- assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(source);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2648,6 +2780,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(tzinfo);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(tzname);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2688,6 +2824,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(wait_all);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_ID(warn_on_full_buffer);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(warnings);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2768,6 +2912,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_STR(str_replace_inf);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
+ string = &_Py_STR(anon_null);
+ _PyUnicode_InternStatic(interp, &string);
+ assert(_PyUnicode_CheckConsistency(string, 1));
+ assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_STR(anon_dictcomp);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
@@ -2792,10 +2944,6 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
- string = &_Py_STR(shim_name);
- _PyUnicode_InternStatic(interp, &string);
- assert(_PyUnicode_CheckConsistency(string, 1));
- assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_STR(anon_string);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
diff --git a/contrib/tools/python3/Include/internal/pycore_unionobject.h b/contrib/tools/python3/Include/internal/pycore_unionobject.h
index 87264635b6e..6ece7134cde 100644
--- a/contrib/tools/python3/Include/internal/pycore_unionobject.h
+++ b/contrib/tools/python3/Include/internal/pycore_unionobject.h
@@ -8,9 +8,11 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-extern PyTypeObject _PyUnion_Type;
+// For extensions created by test_peg_generator
+PyAPI_DATA(PyTypeObject) _PyUnion_Type;
+PyAPI_FUNC(PyObject *) _Py_union_type_or(PyObject *, PyObject *);
+
#define _PyUnion_Check(op) Py_IS_TYPE((op), &_PyUnion_Type)
-extern PyObject *_Py_union_type_or(PyObject *, PyObject *);
#define _PyGenericAlias_Check(op) PyObject_TypeCheck((op), &Py_GenericAliasType)
extern PyObject *_Py_subs_parameters(PyObject *, PyObject *, PyObject *, PyObject *);
diff --git a/contrib/tools/python3/Include/internal/pycore_uop_ids.h b/contrib/tools/python3/Include/internal/pycore_uop_ids.h
new file mode 100644
index 00000000000..1bd5fae3b75
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_uop_ids.h
@@ -0,0 +1,295 @@
+// This file is generated by Tools/cases_generator/uop_id_generator.py
+// from:
+// Python/bytecodes.c
+// Do not edit!
+
+#ifndef Py_CORE_UOP_IDS_H
+#define Py_CORE_UOP_IDS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _EXIT_TRACE 300
+#define _SET_IP 301
+#define _BEFORE_ASYNC_WITH BEFORE_ASYNC_WITH
+#define _BEFORE_WITH BEFORE_WITH
+#define _BINARY_OP 302
+#define _BINARY_OP_ADD_FLOAT 303
+#define _BINARY_OP_ADD_INT 304
+#define _BINARY_OP_ADD_UNICODE 305
+#define _BINARY_OP_MULTIPLY_FLOAT 306
+#define _BINARY_OP_MULTIPLY_INT 307
+#define _BINARY_OP_SUBTRACT_FLOAT 308
+#define _BINARY_OP_SUBTRACT_INT 309
+#define _BINARY_SLICE BINARY_SLICE
+#define _BINARY_SUBSCR 310
+#define _BINARY_SUBSCR_DICT BINARY_SUBSCR_DICT
+#define _BINARY_SUBSCR_GETITEM BINARY_SUBSCR_GETITEM
+#define _BINARY_SUBSCR_LIST_INT BINARY_SUBSCR_LIST_INT
+#define _BINARY_SUBSCR_STR_INT BINARY_SUBSCR_STR_INT
+#define _BINARY_SUBSCR_TUPLE_INT BINARY_SUBSCR_TUPLE_INT
+#define _BUILD_CONST_KEY_MAP BUILD_CONST_KEY_MAP
+#define _BUILD_LIST BUILD_LIST
+#define _BUILD_MAP BUILD_MAP
+#define _BUILD_SET BUILD_SET
+#define _BUILD_SLICE BUILD_SLICE
+#define _BUILD_STRING BUILD_STRING
+#define _BUILD_TUPLE BUILD_TUPLE
+#define _CALL 311
+#define _CALL_ALLOC_AND_ENTER_INIT CALL_ALLOC_AND_ENTER_INIT
+#define _CALL_BUILTIN_CLASS 312
+#define _CALL_BUILTIN_FAST 313
+#define _CALL_BUILTIN_FAST_WITH_KEYWORDS 314
+#define _CALL_BUILTIN_O 315
+#define _CALL_FUNCTION_EX CALL_FUNCTION_EX
+#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1
+#define _CALL_INTRINSIC_2 CALL_INTRINSIC_2
+#define _CALL_ISINSTANCE CALL_ISINSTANCE
+#define _CALL_KW CALL_KW
+#define _CALL_LEN CALL_LEN
+#define _CALL_METHOD_DESCRIPTOR_FAST 316
+#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 317
+#define _CALL_METHOD_DESCRIPTOR_NOARGS 318
+#define _CALL_METHOD_DESCRIPTOR_O 319
+#define _CALL_NON_PY_GENERAL 320
+#define _CALL_STR_1 321
+#define _CALL_TUPLE_1 322
+#define _CALL_TYPE_1 CALL_TYPE_1
+#define _CHECK_ATTR_CLASS 323
+#define _CHECK_ATTR_METHOD_LAZY_DICT 324
+#define _CHECK_ATTR_MODULE 325
+#define _CHECK_ATTR_WITH_HINT 326
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 327
+#define _CHECK_EG_MATCH CHECK_EG_MATCH
+#define _CHECK_EXC_MATCH CHECK_EXC_MATCH
+#define _CHECK_FUNCTION 328
+#define _CHECK_FUNCTION_EXACT_ARGS 329
+#define _CHECK_FUNCTION_VERSION 330
+#define _CHECK_IS_NOT_PY_CALLABLE 331
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES 332
+#define _CHECK_METHOD_VERSION 333
+#define _CHECK_PEP_523 334
+#define _CHECK_PERIODIC 335
+#define _CHECK_RECURSION_REMAINING 336
+#define _CHECK_STACK_SPACE 337
+#define _CHECK_STACK_SPACE_OPERAND 338
+#define _CHECK_VALIDITY 339
+#define _CHECK_VALIDITY_AND_SET_IP 340
+#define _COLD_EXIT 341
+#define _COMPARE_OP 342
+#define _COMPARE_OP_FLOAT 343
+#define _COMPARE_OP_INT 344
+#define _COMPARE_OP_STR 345
+#define _CONTAINS_OP 346
+#define _CONTAINS_OP_DICT CONTAINS_OP_DICT
+#define _CONTAINS_OP_SET CONTAINS_OP_SET
+#define _CONVERT_VALUE CONVERT_VALUE
+#define _COPY COPY
+#define _COPY_FREE_VARS COPY_FREE_VARS
+#define _DELETE_ATTR DELETE_ATTR
+#define _DELETE_DEREF DELETE_DEREF
+#define _DELETE_FAST DELETE_FAST
+#define _DELETE_GLOBAL DELETE_GLOBAL
+#define _DELETE_NAME DELETE_NAME
+#define _DELETE_SUBSCR DELETE_SUBSCR
+#define _DEOPT 347
+#define _DICT_MERGE DICT_MERGE
+#define _DICT_UPDATE DICT_UPDATE
+#define _DYNAMIC_EXIT 348
+#define _END_SEND END_SEND
+#define _ERROR_POP_N 349
+#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
+#define _EXPAND_METHOD 350
+#define _FATAL_ERROR 351
+#define _FORMAT_SIMPLE FORMAT_SIMPLE
+#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
+#define _FOR_ITER 352
+#define _FOR_ITER_GEN_FRAME 353
+#define _FOR_ITER_TIER_TWO 354
+#define _GET_AITER GET_AITER
+#define _GET_ANEXT GET_ANEXT
+#define _GET_AWAITABLE GET_AWAITABLE
+#define _GET_ITER GET_ITER
+#define _GET_LEN GET_LEN
+#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
+#define _GUARD_BOTH_FLOAT 355
+#define _GUARD_BOTH_INT 356
+#define _GUARD_BOTH_UNICODE 357
+#define _GUARD_BUILTINS_VERSION 358
+#define _GUARD_DORV_NO_DICT 359
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 360
+#define _GUARD_GLOBALS_VERSION 361
+#define _GUARD_IS_FALSE_POP 362
+#define _GUARD_IS_NONE_POP 363
+#define _GUARD_IS_NOT_NONE_POP 364
+#define _GUARD_IS_TRUE_POP 365
+#define _GUARD_KEYS_VERSION 366
+#define _GUARD_NOS_FLOAT 367
+#define _GUARD_NOS_INT 368
+#define _GUARD_NOT_EXHAUSTED_LIST 369
+#define _GUARD_NOT_EXHAUSTED_RANGE 370
+#define _GUARD_NOT_EXHAUSTED_TUPLE 371
+#define _GUARD_TOS_FLOAT 372
+#define _GUARD_TOS_INT 373
+#define _GUARD_TYPE_VERSION 374
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 375
+#define _INIT_CALL_PY_EXACT_ARGS 376
+#define _INIT_CALL_PY_EXACT_ARGS_0 377
+#define _INIT_CALL_PY_EXACT_ARGS_1 378
+#define _INIT_CALL_PY_EXACT_ARGS_2 379
+#define _INIT_CALL_PY_EXACT_ARGS_3 380
+#define _INIT_CALL_PY_EXACT_ARGS_4 381
+#define _INSTRUMENTED_CALL INSTRUMENTED_CALL
+#define _INSTRUMENTED_CALL_FUNCTION_EX INSTRUMENTED_CALL_FUNCTION_EX
+#define _INSTRUMENTED_CALL_KW INSTRUMENTED_CALL_KW
+#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
+#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
+#define _INSTRUMENTED_JUMP_BACKWARD INSTRUMENTED_JUMP_BACKWARD
+#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
+#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
+#define _INSTRUMENTED_POP_JUMP_IF_FALSE INSTRUMENTED_POP_JUMP_IF_FALSE
+#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
+#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
+#define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE
+#define _INSTRUMENTED_RESUME INSTRUMENTED_RESUME
+#define _INSTRUMENTED_RETURN_CONST INSTRUMENTED_RETURN_CONST
+#define _INSTRUMENTED_RETURN_VALUE INSTRUMENTED_RETURN_VALUE
+#define _INSTRUMENTED_YIELD_VALUE INSTRUMENTED_YIELD_VALUE
+#define _INTERNAL_INCREMENT_OPT_COUNTER 382
+#define _IS_NONE 383
+#define _IS_OP IS_OP
+#define _ITER_CHECK_LIST 384
+#define _ITER_CHECK_RANGE 385
+#define _ITER_CHECK_TUPLE 386
+#define _ITER_JUMP_LIST 387
+#define _ITER_JUMP_RANGE 388
+#define _ITER_JUMP_TUPLE 389
+#define _ITER_NEXT_LIST 390
+#define _ITER_NEXT_RANGE 391
+#define _ITER_NEXT_TUPLE 392
+#define _JUMP_TO_TOP 393
+#define _LIST_APPEND LIST_APPEND
+#define _LIST_EXTEND LIST_EXTEND
+#define _LOAD_ASSERTION_ERROR LOAD_ASSERTION_ERROR
+#define _LOAD_ATTR 394
+#define _LOAD_ATTR_CLASS 395
+#define _LOAD_ATTR_CLASS_0 396
+#define _LOAD_ATTR_CLASS_1 397
+#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
+#define _LOAD_ATTR_INSTANCE_VALUE 398
+#define _LOAD_ATTR_INSTANCE_VALUE_0 399
+#define _LOAD_ATTR_INSTANCE_VALUE_1 400
+#define _LOAD_ATTR_METHOD_LAZY_DICT 401
+#define _LOAD_ATTR_METHOD_NO_DICT 402
+#define _LOAD_ATTR_METHOD_WITH_VALUES 403
+#define _LOAD_ATTR_MODULE 404
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 405
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 406
+#define _LOAD_ATTR_PROPERTY LOAD_ATTR_PROPERTY
+#define _LOAD_ATTR_SLOT 407
+#define _LOAD_ATTR_SLOT_0 408
+#define _LOAD_ATTR_SLOT_1 409
+#define _LOAD_ATTR_WITH_HINT 410
+#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
+#define _LOAD_CONST LOAD_CONST
+#define _LOAD_CONST_INLINE 411
+#define _LOAD_CONST_INLINE_BORROW 412
+#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 413
+#define _LOAD_CONST_INLINE_WITH_NULL 414
+#define _LOAD_DEREF LOAD_DEREF
+#define _LOAD_FAST 415
+#define _LOAD_FAST_0 416
+#define _LOAD_FAST_1 417
+#define _LOAD_FAST_2 418
+#define _LOAD_FAST_3 419
+#define _LOAD_FAST_4 420
+#define _LOAD_FAST_5 421
+#define _LOAD_FAST_6 422
+#define _LOAD_FAST_7 423
+#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
+#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
+#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
+#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
+#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
+#define _LOAD_GLOBAL 424
+#define _LOAD_GLOBAL_BUILTINS 425
+#define _LOAD_GLOBAL_MODULE 426
+#define _LOAD_LOCALS LOAD_LOCALS
+#define _LOAD_NAME LOAD_NAME
+#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
+#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
+#define _MAKE_CELL MAKE_CELL
+#define _MAKE_FUNCTION MAKE_FUNCTION
+#define _MAP_ADD MAP_ADD
+#define _MATCH_CLASS MATCH_CLASS
+#define _MATCH_KEYS MATCH_KEYS
+#define _MATCH_MAPPING MATCH_MAPPING
+#define _MATCH_SEQUENCE MATCH_SEQUENCE
+#define _NOP NOP
+#define _POP_EXCEPT POP_EXCEPT
+#define _POP_FRAME 427
+#define _POP_JUMP_IF_FALSE 428
+#define _POP_JUMP_IF_TRUE 429
+#define _POP_TOP POP_TOP
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 430
+#define _PUSH_EXC_INFO PUSH_EXC_INFO
+#define _PUSH_FRAME 431
+#define _PUSH_NULL PUSH_NULL
+#define _PY_FRAME_GENERAL 432
+#define _REPLACE_WITH_TRUE 433
+#define _RESUME_CHECK RESUME_CHECK
+#define _RETURN_GENERATOR RETURN_GENERATOR
+#define _SAVE_RETURN_OFFSET 434
+#define _SEND 435
+#define _SEND_GEN SEND_GEN
+#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
+#define _SET_ADD SET_ADD
+#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
+#define _SET_UPDATE SET_UPDATE
+#define _START_EXECUTOR 436
+#define _STORE_ATTR 437
+#define _STORE_ATTR_INSTANCE_VALUE 438
+#define _STORE_ATTR_SLOT 439
+#define _STORE_ATTR_WITH_HINT STORE_ATTR_WITH_HINT
+#define _STORE_DEREF STORE_DEREF
+#define _STORE_FAST 440
+#define _STORE_FAST_0 441
+#define _STORE_FAST_1 442
+#define _STORE_FAST_2 443
+#define _STORE_FAST_3 444
+#define _STORE_FAST_4 445
+#define _STORE_FAST_5 446
+#define _STORE_FAST_6 447
+#define _STORE_FAST_7 448
+#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
+#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
+#define _STORE_GLOBAL STORE_GLOBAL
+#define _STORE_NAME STORE_NAME
+#define _STORE_SLICE STORE_SLICE
+#define _STORE_SUBSCR 449
+#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
+#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
+#define _SWAP SWAP
+#define _TIER2_RESUME_CHECK 450
+#define _TO_BOOL 451
+#define _TO_BOOL_BOOL TO_BOOL_BOOL
+#define _TO_BOOL_INT TO_BOOL_INT
+#define _TO_BOOL_LIST TO_BOOL_LIST
+#define _TO_BOOL_NONE TO_BOOL_NONE
+#define _TO_BOOL_STR TO_BOOL_STR
+#define _UNARY_INVERT UNARY_INVERT
+#define _UNARY_NEGATIVE UNARY_NEGATIVE
+#define _UNARY_NOT UNARY_NOT
+#define _UNPACK_EX UNPACK_EX
+#define _UNPACK_SEQUENCE 452
+#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
+#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
+#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
+#define _WITH_EXCEPT_START WITH_EXCEPT_START
+#define _YIELD_VALUE YIELD_VALUE
+#define MAX_UOP_ID 452
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CORE_UOP_IDS_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_uop_metadata.h b/contrib/tools/python3/Include/internal/pycore_uop_metadata.h
new file mode 100644
index 00000000000..6c69c57b8df
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_uop_metadata.h
@@ -0,0 +1,1010 @@
+// This file is generated by Tools/cases_generator/uop_metadata_generator.py
+// from:
+// Python/bytecodes.c
+// Do not edit!
+
+#ifndef Py_CORE_UOP_METADATA_H
+#define Py_CORE_UOP_METADATA_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "pycore_uop_ids.h"
+extern const uint16_t _PyUop_Flags[MAX_UOP_ID+1];
+extern const uint8_t _PyUop_Replication[MAX_UOP_ID+1];
+extern const char * const _PyOpcode_uop_name[MAX_UOP_ID+1];
+
+extern int _PyUop_num_popped(int opcode, int oparg);
+
+#ifdef NEED_OPCODE_METADATA
+const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
+ [_NOP] = HAS_PURE_FLAG,
+ [_RESUME_CHECK] = HAS_DEOPT_FLAG,
+ [_LOAD_FAST_CHECK] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_FAST_0] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_1] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_2] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_3] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_4] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_5] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_6] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_7] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG,
+ [_LOAD_FAST_AND_CLEAR] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_LOAD_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_LOAD_CONST] = HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_PURE_FLAG,
+ [_STORE_FAST_0] = HAS_LOCAL_FLAG,
+ [_STORE_FAST_1] = HAS_LOCAL_FLAG,
+ [_STORE_FAST_2] = HAS_LOCAL_FLAG,
+ [_STORE_FAST_3] = HAS_LOCAL_FLAG,
+ [_STORE_FAST_4] = HAS_LOCAL_FLAG,
+ [_STORE_FAST_5] = HAS_LOCAL_FLAG,
+ [_STORE_FAST_6] = HAS_LOCAL_FLAG,
+ [_STORE_FAST_7] = HAS_LOCAL_FLAG,
+ [_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_STORE_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_STORE_FAST_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG,
+ [_POP_TOP] = HAS_PURE_FLAG,
+ [_PUSH_NULL] = HAS_PURE_FLAG,
+ [_END_SEND] = HAS_PURE_FLAG,
+ [_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_UNARY_NOT] = HAS_PURE_FLAG,
+ [_TO_BOOL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_TO_BOOL_BOOL] = HAS_EXIT_FLAG,
+ [_TO_BOOL_INT] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG,
+ [_TO_BOOL_LIST] = HAS_EXIT_FLAG,
+ [_TO_BOOL_NONE] = HAS_EXIT_FLAG,
+ [_TO_BOOL_STR] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG,
+ [_REPLACE_WITH_TRUE] = 0,
+ [_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GUARD_BOTH_INT] = HAS_EXIT_FLAG,
+ [_GUARD_NOS_INT] = HAS_EXIT_FLAG,
+ [_GUARD_TOS_INT] = HAS_EXIT_FLAG,
+ [_BINARY_OP_MULTIPLY_INT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_INT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_SUBTRACT_INT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_GUARD_BOTH_FLOAT] = HAS_EXIT_FLAG,
+ [_GUARD_NOS_FLOAT] = HAS_EXIT_FLAG,
+ [_GUARD_TOS_FLOAT] = HAS_EXIT_FLAG,
+ [_BINARY_OP_MULTIPLY_FLOAT] = HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_FLOAT] = HAS_PURE_FLAG,
+ [_BINARY_OP_SUBTRACT_FLOAT] = HAS_PURE_FLAG,
+ [_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG,
+ [_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BINARY_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_SUBSCR_STR_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_SUBSCR_TUPLE_INT] = HAS_DEOPT_FLAG,
+ [_BINARY_SUBSCR_DICT] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LIST_APPEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_SET_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_SUBSCR_LIST_INT] = HAS_DEOPT_FLAG,
+ [_STORE_SUBSCR_DICT] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_INTRINSIC_1] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_INTRINSIC_2] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_POP_FRAME] = 0,
+ [_GET_AITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_ANEXT] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_AWAITABLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_YIELD_VALUE] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_POP_EXCEPT] = HAS_ESCAPES_FLAG,
+ [_LOAD_ASSERTION_ERROR] = 0,
+ [_LOAD_BUILD_CLASS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_NAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_UNPACK_SEQUENCE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_UNPACK_SEQUENCE_TWO_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_UNPACK_SEQUENCE_TUPLE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_UNPACK_SEQUENCE_LIST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_UNPACK_EX] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DELETE_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_LOCALS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_GLOBAL] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GUARD_GLOBALS_VERSION] = HAS_DEOPT_FLAG,
+ [_GUARD_BUILTINS_VERSION] = HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_LOAD_GLOBAL_BUILTINS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_DELETE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MAKE_CELL] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG,
+ [_DELETE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_FROM_DICT_OR_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_STORE_DEREF] = HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ESCAPES_FLAG,
+ [_COPY_FREE_VARS] = HAS_ARG_FLAG,
+ [_BUILD_STRING] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_BUILD_TUPLE] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_BUILD_LIST] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_LIST_EXTEND] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_SET_UPDATE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_MAP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_SETUP_ANNOTATIONS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_CONST_KEY_MAP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DICT_UPDATE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG,
+ [_CHECK_MANAGED_OBJECT_HAS_VALUES] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_INSTANCE_VALUE_0] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_INSTANCE_VALUE_1] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_INSTANCE_VALUE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG,
+ [_CHECK_ATTR_MODULE] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_MODULE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CHECK_ATTR_WITH_HINT] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_WITH_HINT] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_SLOT_0] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_SLOT_1] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_SLOT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_OPARG_AND_1_FLAG,
+ [_CHECK_ATTR_CLASS] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_CLASS_0] = 0,
+ [_LOAD_ATTR_CLASS_1] = 0,
+ [_LOAD_ATTR_CLASS] = HAS_ARG_FLAG | HAS_OPARG_AND_1_FLAG,
+ [_GUARD_DORV_NO_DICT] = HAS_DEOPT_FLAG,
+ [_STORE_ATTR_INSTANCE_VALUE] = 0,
+ [_STORE_ATTR_SLOT] = 0,
+ [_COMPARE_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_COMPARE_OP_FLOAT] = HAS_ARG_FLAG,
+ [_COMPARE_OP_INT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_COMPARE_OP_STR] = HAS_ARG_FLAG,
+ [_IS_OP] = HAS_ARG_FLAG,
+ [_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CONTAINS_OP_SET] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CONTAINS_OP_DICT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_EG_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_EXC_MATCH] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_IS_NONE] = 0,
+ [_GET_LEN] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MATCH_CLASS] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MATCH_MAPPING] = 0,
+ [_MATCH_SEQUENCE] = 0,
+ [_MATCH_KEYS] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_ITER] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_GET_YIELD_FROM_ITER] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_FOR_ITER_TIER_TWO] = HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_ITER_CHECK_LIST] = HAS_EXIT_FLAG,
+ [_GUARD_NOT_EXHAUSTED_LIST] = HAS_EXIT_FLAG,
+ [_ITER_NEXT_LIST] = 0,
+ [_ITER_CHECK_TUPLE] = HAS_EXIT_FLAG,
+ [_GUARD_NOT_EXHAUSTED_TUPLE] = HAS_EXIT_FLAG,
+ [_ITER_NEXT_TUPLE] = 0,
+ [_ITER_CHECK_RANGE] = HAS_EXIT_FLAG,
+ [_GUARD_NOT_EXHAUSTED_RANGE] = HAS_EXIT_FLAG,
+ [_ITER_NEXT_RANGE] = HAS_ERROR_FLAG,
+ [_FOR_ITER_GEN_FRAME] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_WITH_EXCEPT_START] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_PUSH_EXC_INFO] = 0,
+ [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = HAS_DEOPT_FLAG,
+ [_GUARD_KEYS_VERSION] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_METHOD_WITH_VALUES] = HAS_ARG_FLAG,
+ [_LOAD_ATTR_METHOD_NO_DICT] = HAS_ARG_FLAG,
+ [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = HAS_ARG_FLAG,
+ [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = HAS_ARG_FLAG,
+ [_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
+ [_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG,
+ [_CHECK_PERIODIC] = HAS_EVAL_BREAK_FLAG,
+ [_PY_FRAME_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_FUNCTION_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
+ [_CHECK_METHOD_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
+ [_EXPAND_METHOD] = HAS_ARG_FLAG,
+ [_CHECK_IS_NOT_PY_CALLABLE] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
+ [_CALL_NON_PY_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
+ [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG,
+ [_CHECK_PEP_523] = HAS_DEOPT_FLAG,
+ [_CHECK_FUNCTION_EXACT_ARGS] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
+ [_CHECK_STACK_SPACE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CHECK_RECURSION_REMAINING] = HAS_DEOPT_FLAG,
+ [_INIT_CALL_PY_EXACT_ARGS_0] = HAS_PURE_FLAG,
+ [_INIT_CALL_PY_EXACT_ARGS_1] = HAS_PURE_FLAG,
+ [_INIT_CALL_PY_EXACT_ARGS_2] = HAS_PURE_FLAG,
+ [_INIT_CALL_PY_EXACT_ARGS_3] = HAS_PURE_FLAG,
+ [_INIT_CALL_PY_EXACT_ARGS_4] = HAS_PURE_FLAG,
+ [_INIT_CALL_PY_EXACT_ARGS] = HAS_ARG_FLAG | HAS_PURE_FLAG,
+ [_PUSH_FRAME] = 0,
+ [_CALL_TYPE_1] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_CALL_STR_1] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_TUPLE_1] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_EXIT_INIT_CHECK] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_CLASS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_O] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_FAST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_LEN] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_ISINSTANCE] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_O] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_NOARGS] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_CALL_METHOD_DESCRIPTOR_FAST] = HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_MAKE_FUNCTION] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_SET_FUNCTION_ATTRIBUTE] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_RETURN_GENERATOR] = HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_BUILD_SLICE] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_CONVERT_VALUE] = HAS_ARG_FLAG | HAS_ERROR_FLAG,
+ [_FORMAT_SIMPLE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_FORMAT_WITH_SPEC] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_COPY] = HAS_ARG_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_SWAP] = HAS_ARG_FLAG | HAS_PURE_FLAG,
+ [_GUARD_IS_TRUE_POP] = HAS_EXIT_FLAG,
+ [_GUARD_IS_FALSE_POP] = HAS_EXIT_FLAG,
+ [_GUARD_IS_NONE_POP] = HAS_EXIT_FLAG,
+ [_GUARD_IS_NOT_NONE_POP] = HAS_EXIT_FLAG,
+ [_JUMP_TO_TOP] = 0,
+ [_SET_IP] = 0,
+ [_CHECK_STACK_SPACE_OPERAND] = HAS_DEOPT_FLAG,
+ [_SAVE_RETURN_OFFSET] = HAS_ARG_FLAG,
+ [_EXIT_TRACE] = 0,
+ [_CHECK_VALIDITY] = HAS_DEOPT_FLAG,
+ [_LOAD_CONST_INLINE] = HAS_PURE_FLAG,
+ [_LOAD_CONST_INLINE_BORROW] = HAS_PURE_FLAG,
+ [_POP_TOP_LOAD_CONST_INLINE_BORROW] = HAS_PURE_FLAG,
+ [_LOAD_CONST_INLINE_WITH_NULL] = HAS_PURE_FLAG,
+ [_LOAD_CONST_INLINE_BORROW_WITH_NULL] = HAS_PURE_FLAG,
+ [_CHECK_FUNCTION] = HAS_DEOPT_FLAG,
+ [_INTERNAL_INCREMENT_OPT_COUNTER] = 0,
+ [_COLD_EXIT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_DYNAMIC_EXIT] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
+ [_START_EXECUTOR] = HAS_DEOPT_FLAG,
+ [_FATAL_ERROR] = 0,
+ [_CHECK_VALIDITY_AND_SET_IP] = HAS_DEOPT_FLAG,
+ [_DEOPT] = 0,
+ [_ERROR_POP_N] = HAS_ARG_FLAG,
+ [_TIER2_RESUME_CHECK] = HAS_DEOPT_FLAG,
+};
+
+const uint8_t _PyUop_Replication[MAX_UOP_ID+1] = {
+ [_LOAD_FAST] = 8,
+ [_STORE_FAST] = 8,
+ [_INIT_CALL_PY_EXACT_ARGS] = 5,
+};
+
+const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
+ [_BINARY_OP] = "_BINARY_OP",
+ [_BINARY_OP_ADD_FLOAT] = "_BINARY_OP_ADD_FLOAT",
+ [_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
+ [_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
+ [_BINARY_OP_MULTIPLY_FLOAT] = "_BINARY_OP_MULTIPLY_FLOAT",
+ [_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
+ [_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
+ [_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
+ [_BINARY_SLICE] = "_BINARY_SLICE",
+ [_BINARY_SUBSCR] = "_BINARY_SUBSCR",
+ [_BINARY_SUBSCR_DICT] = "_BINARY_SUBSCR_DICT",
+ [_BINARY_SUBSCR_LIST_INT] = "_BINARY_SUBSCR_LIST_INT",
+ [_BINARY_SUBSCR_STR_INT] = "_BINARY_SUBSCR_STR_INT",
+ [_BINARY_SUBSCR_TUPLE_INT] = "_BINARY_SUBSCR_TUPLE_INT",
+ [_BUILD_CONST_KEY_MAP] = "_BUILD_CONST_KEY_MAP",
+ [_BUILD_LIST] = "_BUILD_LIST",
+ [_BUILD_MAP] = "_BUILD_MAP",
+ [_BUILD_SLICE] = "_BUILD_SLICE",
+ [_BUILD_STRING] = "_BUILD_STRING",
+ [_BUILD_TUPLE] = "_BUILD_TUPLE",
+ [_CALL_BUILTIN_CLASS] = "_CALL_BUILTIN_CLASS",
+ [_CALL_BUILTIN_FAST] = "_CALL_BUILTIN_FAST",
+ [_CALL_BUILTIN_FAST_WITH_KEYWORDS] = "_CALL_BUILTIN_FAST_WITH_KEYWORDS",
+ [_CALL_BUILTIN_O] = "_CALL_BUILTIN_O",
+ [_CALL_INTRINSIC_1] = "_CALL_INTRINSIC_1",
+ [_CALL_INTRINSIC_2] = "_CALL_INTRINSIC_2",
+ [_CALL_ISINSTANCE] = "_CALL_ISINSTANCE",
+ [_CALL_LEN] = "_CALL_LEN",
+ [_CALL_METHOD_DESCRIPTOR_FAST] = "_CALL_METHOD_DESCRIPTOR_FAST",
+ [_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
+ [_CALL_METHOD_DESCRIPTOR_NOARGS] = "_CALL_METHOD_DESCRIPTOR_NOARGS",
+ [_CALL_METHOD_DESCRIPTOR_O] = "_CALL_METHOD_DESCRIPTOR_O",
+ [_CALL_NON_PY_GENERAL] = "_CALL_NON_PY_GENERAL",
+ [_CALL_STR_1] = "_CALL_STR_1",
+ [_CALL_TUPLE_1] = "_CALL_TUPLE_1",
+ [_CALL_TYPE_1] = "_CALL_TYPE_1",
+ [_CHECK_ATTR_CLASS] = "_CHECK_ATTR_CLASS",
+ [_CHECK_ATTR_METHOD_LAZY_DICT] = "_CHECK_ATTR_METHOD_LAZY_DICT",
+ [_CHECK_ATTR_MODULE] = "_CHECK_ATTR_MODULE",
+ [_CHECK_ATTR_WITH_HINT] = "_CHECK_ATTR_WITH_HINT",
+ [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = "_CHECK_CALL_BOUND_METHOD_EXACT_ARGS",
+ [_CHECK_EG_MATCH] = "_CHECK_EG_MATCH",
+ [_CHECK_EXC_MATCH] = "_CHECK_EXC_MATCH",
+ [_CHECK_FUNCTION] = "_CHECK_FUNCTION",
+ [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
+ [_CHECK_FUNCTION_VERSION] = "_CHECK_FUNCTION_VERSION",
+ [_CHECK_IS_NOT_PY_CALLABLE] = "_CHECK_IS_NOT_PY_CALLABLE",
+ [_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
+ [_CHECK_METHOD_VERSION] = "_CHECK_METHOD_VERSION",
+ [_CHECK_PEP_523] = "_CHECK_PEP_523",
+ [_CHECK_PERIODIC] = "_CHECK_PERIODIC",
+ [_CHECK_RECURSION_REMAINING] = "_CHECK_RECURSION_REMAINING",
+ [_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
+ [_CHECK_STACK_SPACE_OPERAND] = "_CHECK_STACK_SPACE_OPERAND",
+ [_CHECK_VALIDITY] = "_CHECK_VALIDITY",
+ [_CHECK_VALIDITY_AND_SET_IP] = "_CHECK_VALIDITY_AND_SET_IP",
+ [_COLD_EXIT] = "_COLD_EXIT",
+ [_COMPARE_OP] = "_COMPARE_OP",
+ [_COMPARE_OP_FLOAT] = "_COMPARE_OP_FLOAT",
+ [_COMPARE_OP_INT] = "_COMPARE_OP_INT",
+ [_COMPARE_OP_STR] = "_COMPARE_OP_STR",
+ [_CONTAINS_OP] = "_CONTAINS_OP",
+ [_CONTAINS_OP_DICT] = "_CONTAINS_OP_DICT",
+ [_CONTAINS_OP_SET] = "_CONTAINS_OP_SET",
+ [_CONVERT_VALUE] = "_CONVERT_VALUE",
+ [_COPY] = "_COPY",
+ [_COPY_FREE_VARS] = "_COPY_FREE_VARS",
+ [_DELETE_ATTR] = "_DELETE_ATTR",
+ [_DELETE_DEREF] = "_DELETE_DEREF",
+ [_DELETE_FAST] = "_DELETE_FAST",
+ [_DELETE_GLOBAL] = "_DELETE_GLOBAL",
+ [_DELETE_NAME] = "_DELETE_NAME",
+ [_DELETE_SUBSCR] = "_DELETE_SUBSCR",
+ [_DEOPT] = "_DEOPT",
+ [_DICT_MERGE] = "_DICT_MERGE",
+ [_DICT_UPDATE] = "_DICT_UPDATE",
+ [_DYNAMIC_EXIT] = "_DYNAMIC_EXIT",
+ [_END_SEND] = "_END_SEND",
+ [_ERROR_POP_N] = "_ERROR_POP_N",
+ [_EXIT_INIT_CHECK] = "_EXIT_INIT_CHECK",
+ [_EXIT_TRACE] = "_EXIT_TRACE",
+ [_EXPAND_METHOD] = "_EXPAND_METHOD",
+ [_FATAL_ERROR] = "_FATAL_ERROR",
+ [_FORMAT_SIMPLE] = "_FORMAT_SIMPLE",
+ [_FORMAT_WITH_SPEC] = "_FORMAT_WITH_SPEC",
+ [_FOR_ITER_GEN_FRAME] = "_FOR_ITER_GEN_FRAME",
+ [_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO",
+ [_GET_AITER] = "_GET_AITER",
+ [_GET_ANEXT] = "_GET_ANEXT",
+ [_GET_AWAITABLE] = "_GET_AWAITABLE",
+ [_GET_ITER] = "_GET_ITER",
+ [_GET_LEN] = "_GET_LEN",
+ [_GET_YIELD_FROM_ITER] = "_GET_YIELD_FROM_ITER",
+ [_GUARD_BOTH_FLOAT] = "_GUARD_BOTH_FLOAT",
+ [_GUARD_BOTH_INT] = "_GUARD_BOTH_INT",
+ [_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE",
+ [_GUARD_BUILTINS_VERSION] = "_GUARD_BUILTINS_VERSION",
+ [_GUARD_DORV_NO_DICT] = "_GUARD_DORV_NO_DICT",
+ [_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT] = "_GUARD_DORV_VALUES_INST_ATTR_FROM_DICT",
+ [_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION",
+ [_GUARD_IS_FALSE_POP] = "_GUARD_IS_FALSE_POP",
+ [_GUARD_IS_NONE_POP] = "_GUARD_IS_NONE_POP",
+ [_GUARD_IS_NOT_NONE_POP] = "_GUARD_IS_NOT_NONE_POP",
+ [_GUARD_IS_TRUE_POP] = "_GUARD_IS_TRUE_POP",
+ [_GUARD_KEYS_VERSION] = "_GUARD_KEYS_VERSION",
+ [_GUARD_NOS_FLOAT] = "_GUARD_NOS_FLOAT",
+ [_GUARD_NOS_INT] = "_GUARD_NOS_INT",
+ [_GUARD_NOT_EXHAUSTED_LIST] = "_GUARD_NOT_EXHAUSTED_LIST",
+ [_GUARD_NOT_EXHAUSTED_RANGE] = "_GUARD_NOT_EXHAUSTED_RANGE",
+ [_GUARD_NOT_EXHAUSTED_TUPLE] = "_GUARD_NOT_EXHAUSTED_TUPLE",
+ [_GUARD_TOS_FLOAT] = "_GUARD_TOS_FLOAT",
+ [_GUARD_TOS_INT] = "_GUARD_TOS_INT",
+ [_GUARD_TYPE_VERSION] = "_GUARD_TYPE_VERSION",
+ [_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = "_INIT_CALL_BOUND_METHOD_EXACT_ARGS",
+ [_INIT_CALL_PY_EXACT_ARGS] = "_INIT_CALL_PY_EXACT_ARGS",
+ [_INIT_CALL_PY_EXACT_ARGS_0] = "_INIT_CALL_PY_EXACT_ARGS_0",
+ [_INIT_CALL_PY_EXACT_ARGS_1] = "_INIT_CALL_PY_EXACT_ARGS_1",
+ [_INIT_CALL_PY_EXACT_ARGS_2] = "_INIT_CALL_PY_EXACT_ARGS_2",
+ [_INIT_CALL_PY_EXACT_ARGS_3] = "_INIT_CALL_PY_EXACT_ARGS_3",
+ [_INIT_CALL_PY_EXACT_ARGS_4] = "_INIT_CALL_PY_EXACT_ARGS_4",
+ [_INTERNAL_INCREMENT_OPT_COUNTER] = "_INTERNAL_INCREMENT_OPT_COUNTER",
+ [_IS_NONE] = "_IS_NONE",
+ [_IS_OP] = "_IS_OP",
+ [_ITER_CHECK_LIST] = "_ITER_CHECK_LIST",
+ [_ITER_CHECK_RANGE] = "_ITER_CHECK_RANGE",
+ [_ITER_CHECK_TUPLE] = "_ITER_CHECK_TUPLE",
+ [_ITER_NEXT_LIST] = "_ITER_NEXT_LIST",
+ [_ITER_NEXT_RANGE] = "_ITER_NEXT_RANGE",
+ [_ITER_NEXT_TUPLE] = "_ITER_NEXT_TUPLE",
+ [_JUMP_TO_TOP] = "_JUMP_TO_TOP",
+ [_LIST_APPEND] = "_LIST_APPEND",
+ [_LIST_EXTEND] = "_LIST_EXTEND",
+ [_LOAD_ASSERTION_ERROR] = "_LOAD_ASSERTION_ERROR",
+ [_LOAD_ATTR] = "_LOAD_ATTR",
+ [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS",
+ [_LOAD_ATTR_CLASS_0] = "_LOAD_ATTR_CLASS_0",
+ [_LOAD_ATTR_CLASS_1] = "_LOAD_ATTR_CLASS_1",
+ [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE",
+ [_LOAD_ATTR_INSTANCE_VALUE_0] = "_LOAD_ATTR_INSTANCE_VALUE_0",
+ [_LOAD_ATTR_INSTANCE_VALUE_1] = "_LOAD_ATTR_INSTANCE_VALUE_1",
+ [_LOAD_ATTR_METHOD_LAZY_DICT] = "_LOAD_ATTR_METHOD_LAZY_DICT",
+ [_LOAD_ATTR_METHOD_NO_DICT] = "_LOAD_ATTR_METHOD_NO_DICT",
+ [_LOAD_ATTR_METHOD_WITH_VALUES] = "_LOAD_ATTR_METHOD_WITH_VALUES",
+ [_LOAD_ATTR_MODULE] = "_LOAD_ATTR_MODULE",
+ [_LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = "_LOAD_ATTR_NONDESCRIPTOR_NO_DICT",
+ [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES",
+ [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT",
+ [_LOAD_ATTR_SLOT_0] = "_LOAD_ATTR_SLOT_0",
+ [_LOAD_ATTR_SLOT_1] = "_LOAD_ATTR_SLOT_1",
+ [_LOAD_ATTR_WITH_HINT] = "_LOAD_ATTR_WITH_HINT",
+ [_LOAD_BUILD_CLASS] = "_LOAD_BUILD_CLASS",
+ [_LOAD_CONST] = "_LOAD_CONST",
+ [_LOAD_CONST_INLINE] = "_LOAD_CONST_INLINE",
+ [_LOAD_CONST_INLINE_BORROW] = "_LOAD_CONST_INLINE_BORROW",
+ [_LOAD_CONST_INLINE_BORROW_WITH_NULL] = "_LOAD_CONST_INLINE_BORROW_WITH_NULL",
+ [_LOAD_CONST_INLINE_WITH_NULL] = "_LOAD_CONST_INLINE_WITH_NULL",
+ [_LOAD_DEREF] = "_LOAD_DEREF",
+ [_LOAD_FAST] = "_LOAD_FAST",
+ [_LOAD_FAST_0] = "_LOAD_FAST_0",
+ [_LOAD_FAST_1] = "_LOAD_FAST_1",
+ [_LOAD_FAST_2] = "_LOAD_FAST_2",
+ [_LOAD_FAST_3] = "_LOAD_FAST_3",
+ [_LOAD_FAST_4] = "_LOAD_FAST_4",
+ [_LOAD_FAST_5] = "_LOAD_FAST_5",
+ [_LOAD_FAST_6] = "_LOAD_FAST_6",
+ [_LOAD_FAST_7] = "_LOAD_FAST_7",
+ [_LOAD_FAST_AND_CLEAR] = "_LOAD_FAST_AND_CLEAR",
+ [_LOAD_FAST_CHECK] = "_LOAD_FAST_CHECK",
+ [_LOAD_FAST_LOAD_FAST] = "_LOAD_FAST_LOAD_FAST",
+ [_LOAD_FROM_DICT_OR_DEREF] = "_LOAD_FROM_DICT_OR_DEREF",
+ [_LOAD_GLOBAL] = "_LOAD_GLOBAL",
+ [_LOAD_GLOBAL_BUILTINS] = "_LOAD_GLOBAL_BUILTINS",
+ [_LOAD_GLOBAL_MODULE] = "_LOAD_GLOBAL_MODULE",
+ [_LOAD_LOCALS] = "_LOAD_LOCALS",
+ [_LOAD_SUPER_ATTR_ATTR] = "_LOAD_SUPER_ATTR_ATTR",
+ [_LOAD_SUPER_ATTR_METHOD] = "_LOAD_SUPER_ATTR_METHOD",
+ [_MAKE_CELL] = "_MAKE_CELL",
+ [_MAKE_FUNCTION] = "_MAKE_FUNCTION",
+ [_MAP_ADD] = "_MAP_ADD",
+ [_MATCH_CLASS] = "_MATCH_CLASS",
+ [_MATCH_KEYS] = "_MATCH_KEYS",
+ [_MATCH_MAPPING] = "_MATCH_MAPPING",
+ [_MATCH_SEQUENCE] = "_MATCH_SEQUENCE",
+ [_NOP] = "_NOP",
+ [_POP_EXCEPT] = "_POP_EXCEPT",
+ [_POP_FRAME] = "_POP_FRAME",
+ [_POP_TOP] = "_POP_TOP",
+ [_POP_TOP_LOAD_CONST_INLINE_BORROW] = "_POP_TOP_LOAD_CONST_INLINE_BORROW",
+ [_PUSH_EXC_INFO] = "_PUSH_EXC_INFO",
+ [_PUSH_FRAME] = "_PUSH_FRAME",
+ [_PUSH_NULL] = "_PUSH_NULL",
+ [_PY_FRAME_GENERAL] = "_PY_FRAME_GENERAL",
+ [_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE",
+ [_RESUME_CHECK] = "_RESUME_CHECK",
+ [_RETURN_GENERATOR] = "_RETURN_GENERATOR",
+ [_SAVE_RETURN_OFFSET] = "_SAVE_RETURN_OFFSET",
+ [_SETUP_ANNOTATIONS] = "_SETUP_ANNOTATIONS",
+ [_SET_ADD] = "_SET_ADD",
+ [_SET_FUNCTION_ATTRIBUTE] = "_SET_FUNCTION_ATTRIBUTE",
+ [_SET_IP] = "_SET_IP",
+ [_SET_UPDATE] = "_SET_UPDATE",
+ [_START_EXECUTOR] = "_START_EXECUTOR",
+ [_STORE_ATTR] = "_STORE_ATTR",
+ [_STORE_ATTR_INSTANCE_VALUE] = "_STORE_ATTR_INSTANCE_VALUE",
+ [_STORE_ATTR_SLOT] = "_STORE_ATTR_SLOT",
+ [_STORE_DEREF] = "_STORE_DEREF",
+ [_STORE_FAST] = "_STORE_FAST",
+ [_STORE_FAST_0] = "_STORE_FAST_0",
+ [_STORE_FAST_1] = "_STORE_FAST_1",
+ [_STORE_FAST_2] = "_STORE_FAST_2",
+ [_STORE_FAST_3] = "_STORE_FAST_3",
+ [_STORE_FAST_4] = "_STORE_FAST_4",
+ [_STORE_FAST_5] = "_STORE_FAST_5",
+ [_STORE_FAST_6] = "_STORE_FAST_6",
+ [_STORE_FAST_7] = "_STORE_FAST_7",
+ [_STORE_FAST_LOAD_FAST] = "_STORE_FAST_LOAD_FAST",
+ [_STORE_FAST_STORE_FAST] = "_STORE_FAST_STORE_FAST",
+ [_STORE_GLOBAL] = "_STORE_GLOBAL",
+ [_STORE_NAME] = "_STORE_NAME",
+ [_STORE_SLICE] = "_STORE_SLICE",
+ [_STORE_SUBSCR] = "_STORE_SUBSCR",
+ [_STORE_SUBSCR_DICT] = "_STORE_SUBSCR_DICT",
+ [_STORE_SUBSCR_LIST_INT] = "_STORE_SUBSCR_LIST_INT",
+ [_SWAP] = "_SWAP",
+ [_TIER2_RESUME_CHECK] = "_TIER2_RESUME_CHECK",
+ [_TO_BOOL] = "_TO_BOOL",
+ [_TO_BOOL_BOOL] = "_TO_BOOL_BOOL",
+ [_TO_BOOL_INT] = "_TO_BOOL_INT",
+ [_TO_BOOL_LIST] = "_TO_BOOL_LIST",
+ [_TO_BOOL_NONE] = "_TO_BOOL_NONE",
+ [_TO_BOOL_STR] = "_TO_BOOL_STR",
+ [_UNARY_INVERT] = "_UNARY_INVERT",
+ [_UNARY_NEGATIVE] = "_UNARY_NEGATIVE",
+ [_UNARY_NOT] = "_UNARY_NOT",
+ [_UNPACK_EX] = "_UNPACK_EX",
+ [_UNPACK_SEQUENCE] = "_UNPACK_SEQUENCE",
+ [_UNPACK_SEQUENCE_LIST] = "_UNPACK_SEQUENCE_LIST",
+ [_UNPACK_SEQUENCE_TUPLE] = "_UNPACK_SEQUENCE_TUPLE",
+ [_UNPACK_SEQUENCE_TWO_TUPLE] = "_UNPACK_SEQUENCE_TWO_TUPLE",
+ [_WITH_EXCEPT_START] = "_WITH_EXCEPT_START",
+ [_YIELD_VALUE] = "_YIELD_VALUE",
+};
+int _PyUop_num_popped(int opcode, int oparg)
+{
+ switch(opcode) {
+ case _NOP:
+ return 0;
+ case _RESUME_CHECK:
+ return 0;
+ case _LOAD_FAST_CHECK:
+ return 0;
+ case _LOAD_FAST_0:
+ return 0;
+ case _LOAD_FAST_1:
+ return 0;
+ case _LOAD_FAST_2:
+ return 0;
+ case _LOAD_FAST_3:
+ return 0;
+ case _LOAD_FAST_4:
+ return 0;
+ case _LOAD_FAST_5:
+ return 0;
+ case _LOAD_FAST_6:
+ return 0;
+ case _LOAD_FAST_7:
+ return 0;
+ case _LOAD_FAST:
+ return 0;
+ case _LOAD_FAST_AND_CLEAR:
+ return 0;
+ case _LOAD_FAST_LOAD_FAST:
+ return 0;
+ case _LOAD_CONST:
+ return 0;
+ case _STORE_FAST_0:
+ return 1;
+ case _STORE_FAST_1:
+ return 1;
+ case _STORE_FAST_2:
+ return 1;
+ case _STORE_FAST_3:
+ return 1;
+ case _STORE_FAST_4:
+ return 1;
+ case _STORE_FAST_5:
+ return 1;
+ case _STORE_FAST_6:
+ return 1;
+ case _STORE_FAST_7:
+ return 1;
+ case _STORE_FAST:
+ return 1;
+ case _STORE_FAST_LOAD_FAST:
+ return 1;
+ case _STORE_FAST_STORE_FAST:
+ return 2;
+ case _POP_TOP:
+ return 1;
+ case _PUSH_NULL:
+ return 0;
+ case _END_SEND:
+ return 2;
+ case _UNARY_NEGATIVE:
+ return 1;
+ case _UNARY_NOT:
+ return 1;
+ case _TO_BOOL:
+ return 1;
+ case _TO_BOOL_BOOL:
+ return 1;
+ case _TO_BOOL_INT:
+ return 1;
+ case _TO_BOOL_LIST:
+ return 1;
+ case _TO_BOOL_NONE:
+ return 1;
+ case _TO_BOOL_STR:
+ return 1;
+ case _REPLACE_WITH_TRUE:
+ return 1;
+ case _UNARY_INVERT:
+ return 1;
+ case _GUARD_BOTH_INT:
+ return 2;
+ case _GUARD_NOS_INT:
+ return 2;
+ case _GUARD_TOS_INT:
+ return 1;
+ case _BINARY_OP_MULTIPLY_INT:
+ return 2;
+ case _BINARY_OP_ADD_INT:
+ return 2;
+ case _BINARY_OP_SUBTRACT_INT:
+ return 2;
+ case _GUARD_BOTH_FLOAT:
+ return 2;
+ case _GUARD_NOS_FLOAT:
+ return 2;
+ case _GUARD_TOS_FLOAT:
+ return 1;
+ case _BINARY_OP_MULTIPLY_FLOAT:
+ return 2;
+ case _BINARY_OP_ADD_FLOAT:
+ return 2;
+ case _BINARY_OP_SUBTRACT_FLOAT:
+ return 2;
+ case _GUARD_BOTH_UNICODE:
+ return 2;
+ case _BINARY_OP_ADD_UNICODE:
+ return 2;
+ case _BINARY_SUBSCR:
+ return 2;
+ case _BINARY_SLICE:
+ return 3;
+ case _STORE_SLICE:
+ return 4;
+ case _BINARY_SUBSCR_LIST_INT:
+ return 2;
+ case _BINARY_SUBSCR_STR_INT:
+ return 2;
+ case _BINARY_SUBSCR_TUPLE_INT:
+ return 2;
+ case _BINARY_SUBSCR_DICT:
+ return 2;
+ case _LIST_APPEND:
+ return 2 + (oparg-1);
+ case _SET_ADD:
+ return 2 + (oparg-1);
+ case _STORE_SUBSCR:
+ return 3;
+ case _STORE_SUBSCR_LIST_INT:
+ return 3;
+ case _STORE_SUBSCR_DICT:
+ return 3;
+ case _DELETE_SUBSCR:
+ return 2;
+ case _CALL_INTRINSIC_1:
+ return 1;
+ case _CALL_INTRINSIC_2:
+ return 2;
+ case _POP_FRAME:
+ return 1;
+ case _GET_AITER:
+ return 1;
+ case _GET_ANEXT:
+ return 1;
+ case _GET_AWAITABLE:
+ return 1;
+ case _YIELD_VALUE:
+ return 1;
+ case _POP_EXCEPT:
+ return 1;
+ case _LOAD_ASSERTION_ERROR:
+ return 0;
+ case _LOAD_BUILD_CLASS:
+ return 0;
+ case _STORE_NAME:
+ return 1;
+ case _DELETE_NAME:
+ return 0;
+ case _UNPACK_SEQUENCE:
+ return 1;
+ case _UNPACK_SEQUENCE_TWO_TUPLE:
+ return 1;
+ case _UNPACK_SEQUENCE_TUPLE:
+ return 1;
+ case _UNPACK_SEQUENCE_LIST:
+ return 1;
+ case _UNPACK_EX:
+ return 1;
+ case _STORE_ATTR:
+ return 2;
+ case _DELETE_ATTR:
+ return 1;
+ case _STORE_GLOBAL:
+ return 1;
+ case _DELETE_GLOBAL:
+ return 0;
+ case _LOAD_LOCALS:
+ return 0;
+ case _LOAD_GLOBAL:
+ return 0;
+ case _GUARD_GLOBALS_VERSION:
+ return 0;
+ case _GUARD_BUILTINS_VERSION:
+ return 0;
+ case _LOAD_GLOBAL_MODULE:
+ return 0;
+ case _LOAD_GLOBAL_BUILTINS:
+ return 0;
+ case _DELETE_FAST:
+ return 0;
+ case _MAKE_CELL:
+ return 0;
+ case _DELETE_DEREF:
+ return 0;
+ case _LOAD_FROM_DICT_OR_DEREF:
+ return 1;
+ case _LOAD_DEREF:
+ return 0;
+ case _STORE_DEREF:
+ return 1;
+ case _COPY_FREE_VARS:
+ return 0;
+ case _BUILD_STRING:
+ return oparg;
+ case _BUILD_TUPLE:
+ return oparg;
+ case _BUILD_LIST:
+ return oparg;
+ case _LIST_EXTEND:
+ return 2 + (oparg-1);
+ case _SET_UPDATE:
+ return 2 + (oparg-1);
+ case _BUILD_MAP:
+ return oparg*2;
+ case _SETUP_ANNOTATIONS:
+ return 0;
+ case _BUILD_CONST_KEY_MAP:
+ return 1 + oparg;
+ case _DICT_UPDATE:
+ return 2 + (oparg - 1);
+ case _DICT_MERGE:
+ return 5 + (oparg - 1);
+ case _MAP_ADD:
+ return 3 + (oparg - 1);
+ case _LOAD_SUPER_ATTR_ATTR:
+ return 3;
+ case _LOAD_SUPER_ATTR_METHOD:
+ return 3;
+ case _LOAD_ATTR:
+ return 1;
+ case _GUARD_TYPE_VERSION:
+ return 1;
+ case _CHECK_MANAGED_OBJECT_HAS_VALUES:
+ return 1;
+ case _LOAD_ATTR_INSTANCE_VALUE_0:
+ return 1;
+ case _LOAD_ATTR_INSTANCE_VALUE_1:
+ return 1;
+ case _LOAD_ATTR_INSTANCE_VALUE:
+ return 1;
+ case _CHECK_ATTR_MODULE:
+ return 1;
+ case _LOAD_ATTR_MODULE:
+ return 1;
+ case _CHECK_ATTR_WITH_HINT:
+ return 1;
+ case _LOAD_ATTR_WITH_HINT:
+ return 1;
+ case _LOAD_ATTR_SLOT_0:
+ return 1;
+ case _LOAD_ATTR_SLOT_1:
+ return 1;
+ case _LOAD_ATTR_SLOT:
+ return 1;
+ case _CHECK_ATTR_CLASS:
+ return 1;
+ case _LOAD_ATTR_CLASS_0:
+ return 1;
+ case _LOAD_ATTR_CLASS_1:
+ return 1;
+ case _LOAD_ATTR_CLASS:
+ return 1;
+ case _GUARD_DORV_NO_DICT:
+ return 1;
+ case _STORE_ATTR_INSTANCE_VALUE:
+ return 2;
+ case _STORE_ATTR_SLOT:
+ return 2;
+ case _COMPARE_OP:
+ return 2;
+ case _COMPARE_OP_FLOAT:
+ return 2;
+ case _COMPARE_OP_INT:
+ return 2;
+ case _COMPARE_OP_STR:
+ return 2;
+ case _IS_OP:
+ return 2;
+ case _CONTAINS_OP:
+ return 2;
+ case _CONTAINS_OP_SET:
+ return 2;
+ case _CONTAINS_OP_DICT:
+ return 2;
+ case _CHECK_EG_MATCH:
+ return 2;
+ case _CHECK_EXC_MATCH:
+ return 2;
+ case _IS_NONE:
+ return 1;
+ case _GET_LEN:
+ return 1;
+ case _MATCH_CLASS:
+ return 3;
+ case _MATCH_MAPPING:
+ return 1;
+ case _MATCH_SEQUENCE:
+ return 1;
+ case _MATCH_KEYS:
+ return 2;
+ case _GET_ITER:
+ return 1;
+ case _GET_YIELD_FROM_ITER:
+ return 1;
+ case _FOR_ITER_TIER_TWO:
+ return 1;
+ case _ITER_CHECK_LIST:
+ return 1;
+ case _GUARD_NOT_EXHAUSTED_LIST:
+ return 1;
+ case _ITER_NEXT_LIST:
+ return 1;
+ case _ITER_CHECK_TUPLE:
+ return 1;
+ case _GUARD_NOT_EXHAUSTED_TUPLE:
+ return 1;
+ case _ITER_NEXT_TUPLE:
+ return 1;
+ case _ITER_CHECK_RANGE:
+ return 1;
+ case _GUARD_NOT_EXHAUSTED_RANGE:
+ return 1;
+ case _ITER_NEXT_RANGE:
+ return 1;
+ case _FOR_ITER_GEN_FRAME:
+ return 1;
+ case _WITH_EXCEPT_START:
+ return 4;
+ case _PUSH_EXC_INFO:
+ return 1;
+ case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT:
+ return 1;
+ case _GUARD_KEYS_VERSION:
+ return 1;
+ case _LOAD_ATTR_METHOD_WITH_VALUES:
+ return 1;
+ case _LOAD_ATTR_METHOD_NO_DICT:
+ return 1;
+ case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES:
+ return 1;
+ case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT:
+ return 1;
+ case _CHECK_ATTR_METHOD_LAZY_DICT:
+ return 1;
+ case _LOAD_ATTR_METHOD_LAZY_DICT:
+ return 1;
+ case _CHECK_PERIODIC:
+ return 0;
+ case _PY_FRAME_GENERAL:
+ return 2 + oparg;
+ case _CHECK_FUNCTION_VERSION:
+ return 2 + oparg;
+ case _CHECK_METHOD_VERSION:
+ return 2 + oparg;
+ case _EXPAND_METHOD:
+ return 2 + oparg;
+ case _CHECK_IS_NOT_PY_CALLABLE:
+ return 2 + oparg;
+ case _CALL_NON_PY_GENERAL:
+ return 2 + oparg;
+ case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS:
+ return 2 + oparg;
+ case _INIT_CALL_BOUND_METHOD_EXACT_ARGS:
+ return 2 + oparg;
+ case _CHECK_PEP_523:
+ return 0;
+ case _CHECK_FUNCTION_EXACT_ARGS:
+ return 2 + oparg;
+ case _CHECK_STACK_SPACE:
+ return 2 + oparg;
+ case _CHECK_RECURSION_REMAINING:
+ return 0;
+ case _INIT_CALL_PY_EXACT_ARGS_0:
+ return 2 + oparg;
+ case _INIT_CALL_PY_EXACT_ARGS_1:
+ return 2 + oparg;
+ case _INIT_CALL_PY_EXACT_ARGS_2:
+ return 2 + oparg;
+ case _INIT_CALL_PY_EXACT_ARGS_3:
+ return 2 + oparg;
+ case _INIT_CALL_PY_EXACT_ARGS_4:
+ return 2 + oparg;
+ case _INIT_CALL_PY_EXACT_ARGS:
+ return 2 + oparg;
+ case _PUSH_FRAME:
+ return 1;
+ case _CALL_TYPE_1:
+ return 3;
+ case _CALL_STR_1:
+ return 3;
+ case _CALL_TUPLE_1:
+ return 3;
+ case _EXIT_INIT_CHECK:
+ return 1;
+ case _CALL_BUILTIN_CLASS:
+ return 2 + oparg;
+ case _CALL_BUILTIN_O:
+ return 2 + oparg;
+ case _CALL_BUILTIN_FAST:
+ return 2 + oparg;
+ case _CALL_BUILTIN_FAST_WITH_KEYWORDS:
+ return 2 + oparg;
+ case _CALL_LEN:
+ return 2 + oparg;
+ case _CALL_ISINSTANCE:
+ return 2 + oparg;
+ case _CALL_METHOD_DESCRIPTOR_O:
+ return 2 + oparg;
+ case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
+ return 2 + oparg;
+ case _CALL_METHOD_DESCRIPTOR_NOARGS:
+ return 2 + oparg;
+ case _CALL_METHOD_DESCRIPTOR_FAST:
+ return 2 + oparg;
+ case _MAKE_FUNCTION:
+ return 1;
+ case _SET_FUNCTION_ATTRIBUTE:
+ return 2;
+ case _RETURN_GENERATOR:
+ return 0;
+ case _BUILD_SLICE:
+ return 2 + ((oparg == 3) ? 1 : 0);
+ case _CONVERT_VALUE:
+ return 1;
+ case _FORMAT_SIMPLE:
+ return 1;
+ case _FORMAT_WITH_SPEC:
+ return 2;
+ case _COPY:
+ return 1 + (oparg-1);
+ case _BINARY_OP:
+ return 2;
+ case _SWAP:
+ return 2 + (oparg-2);
+ case _GUARD_IS_TRUE_POP:
+ return 1;
+ case _GUARD_IS_FALSE_POP:
+ return 1;
+ case _GUARD_IS_NONE_POP:
+ return 1;
+ case _GUARD_IS_NOT_NONE_POP:
+ return 1;
+ case _JUMP_TO_TOP:
+ return 0;
+ case _SET_IP:
+ return 0;
+ case _CHECK_STACK_SPACE_OPERAND:
+ return 0;
+ case _SAVE_RETURN_OFFSET:
+ return 0;
+ case _EXIT_TRACE:
+ return 0;
+ case _CHECK_VALIDITY:
+ return 0;
+ case _LOAD_CONST_INLINE:
+ return 0;
+ case _LOAD_CONST_INLINE_BORROW:
+ return 0;
+ case _POP_TOP_LOAD_CONST_INLINE_BORROW:
+ return 1;
+ case _LOAD_CONST_INLINE_WITH_NULL:
+ return 0;
+ case _LOAD_CONST_INLINE_BORROW_WITH_NULL:
+ return 0;
+ case _CHECK_FUNCTION:
+ return 0;
+ case _INTERNAL_INCREMENT_OPT_COUNTER:
+ return 1;
+ case _COLD_EXIT:
+ return 0;
+ case _DYNAMIC_EXIT:
+ return 0;
+ case _START_EXECUTOR:
+ return 0;
+ case _FATAL_ERROR:
+ return 0;
+ case _CHECK_VALIDITY_AND_SET_IP:
+ return 0;
+ case _DEOPT:
+ return 0;
+ case _ERROR_POP_N:
+ return oparg;
+ case _TIER2_RESUME_CHECK:
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+#endif // NEED_OPCODE_METADATA
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CORE_UOP_METADATA_H */
diff --git a/contrib/tools/python3/Include/internal/pycore_warnings.h b/contrib/tools/python3/Include/internal/pycore_warnings.h
index efb4f1cd7ea..f9f6559312f 100644
--- a/contrib/tools/python3/Include/internal/pycore_warnings.h
+++ b/contrib/tools/python3/Include/internal/pycore_warnings.h
@@ -14,14 +14,16 @@ struct _warnings_runtime_state {
PyObject *filters; /* List */
PyObject *once_registry; /* Dict */
PyObject *default_action; /* String */
+ PyMutex mutex;
long filters_version;
};
extern int _PyWarnings_InitState(PyInterpreterState *interp);
-PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
+extern PyObject* _PyWarnings_Init(void);
extern void _PyErr_WarnUnawaitedCoroutine(PyObject *coro);
+extern void _PyErr_WarnUnawaitedAgenMethod(PyAsyncGenObject *agen, PyObject *method);
#ifdef __cplusplus
}
diff --git a/contrib/tools/python3/Include/internal/pycore_weakref.h b/contrib/tools/python3/Include/internal/pycore_weakref.h
new file mode 100644
index 00000000000..ff1395ea837
--- /dev/null
+++ b/contrib/tools/python3/Include/internal/pycore_weakref.h
@@ -0,0 +1,133 @@
+#ifndef Py_INTERNAL_WEAKREF_H
+#define Py_INTERNAL_WEAKREF_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
+#include "pycore_lock.h"
+#include "pycore_object.h" // _Py_REF_IS_MERGED()
+#include "pycore_pyatomic_ft_wrappers.h"
+
+#ifdef Py_GIL_DISABLED
+
+#define WEAKREF_LIST_LOCK(obj) \
+ _PyInterpreterState_GET() \
+ ->weakref_locks[((uintptr_t)obj) % NUM_WEAKREF_LIST_LOCKS]
+
+// Lock using the referenced object
+#define LOCK_WEAKREFS(obj) \
+ PyMutex_LockFlags(&WEAKREF_LIST_LOCK(obj), _Py_LOCK_DONT_DETACH)
+#define UNLOCK_WEAKREFS(obj) PyMutex_Unlock(&WEAKREF_LIST_LOCK(obj))
+
+// Lock using a weakref
+#define LOCK_WEAKREFS_FOR_WR(wr) \
+ PyMutex_LockFlags(wr->weakrefs_lock, _Py_LOCK_DONT_DETACH)
+#define UNLOCK_WEAKREFS_FOR_WR(wr) PyMutex_Unlock(wr->weakrefs_lock)
+
+#define FT_CLEAR_WEAKREFS(obj, weakref_list) \
+ do { \
+ assert(Py_REFCNT(obj) == 0); \
+ PyObject_ClearWeakRefs(obj); \
+ } while (0)
+
+#else
+
+#define LOCK_WEAKREFS(obj)
+#define UNLOCK_WEAKREFS(obj)
+
+#define LOCK_WEAKREFS_FOR_WR(wr)
+#define UNLOCK_WEAKREFS_FOR_WR(wr)
+
+#define FT_CLEAR_WEAKREFS(obj, weakref_list) \
+ do { \
+ assert(Py_REFCNT(obj) == 0); \
+ if (weakref_list != NULL) { \
+ PyObject_ClearWeakRefs(obj); \
+ } \
+ } while (0)
+
+#endif
+
+static inline int _is_dead(PyObject *obj)
+{
+ // Explanation for the Py_REFCNT() check: when a weakref's target is part
+ // of a long chain of deallocations which triggers the trashcan mechanism,
+ // clearing the weakrefs can be delayed long after the target's refcount
+ // has dropped to zero. In the meantime, code accessing the weakref will
+ // be able to "see" the target object even though it is supposed to be
+ // unreachable. See issue gh-60806.
+#if defined(Py_GIL_DISABLED)
+ Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&obj->ob_ref_shared);
+ return shared == _Py_REF_SHARED(0, _Py_REF_MERGED);
+#else
+ return (Py_REFCNT(obj) == 0);
+#endif
+}
+
+static inline PyObject* _PyWeakref_GET_REF(PyObject *ref_obj)
+{
+ assert(PyWeakref_Check(ref_obj));
+ PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj);
+
+ PyObject *obj = FT_ATOMIC_LOAD_PTR(ref->wr_object);
+ if (obj == Py_None) {
+ // clear_weakref() was called
+ return NULL;
+ }
+
+ LOCK_WEAKREFS(obj);
+#ifdef Py_GIL_DISABLED
+ if (ref->wr_object == Py_None) {
+ // clear_weakref() was called
+ UNLOCK_WEAKREFS(obj);
+ return NULL;
+ }
+#endif
+ if (_Py_TryIncref(obj)) {
+ UNLOCK_WEAKREFS(obj);
+ return obj;
+ }
+ UNLOCK_WEAKREFS(obj);
+ return NULL;
+}
+
+static inline int _PyWeakref_IS_DEAD(PyObject *ref_obj)
+{
+ assert(PyWeakref_Check(ref_obj));
+ int ret = 0;
+ PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj);
+ PyObject *obj = FT_ATOMIC_LOAD_PTR(ref->wr_object);
+ if (obj == Py_None) {
+ // clear_weakref() was called
+ ret = 1;
+ }
+ else {
+ LOCK_WEAKREFS(obj);
+ // See _PyWeakref_GET_REF() for the rationale of this test
+#ifdef Py_GIL_DISABLED
+ ret = (ref->wr_object == Py_None) || _is_dead(obj);
+#else
+ ret = _is_dead(obj);
+#endif
+ UNLOCK_WEAKREFS(obj);
+ }
+ return ret;
+}
+
+extern Py_ssize_t _PyWeakref_GetWeakrefCount(PyObject *obj);
+
+// Clear all the weak references to obj but leave their callbacks uncalled and
+// intact.
+extern void _PyWeakref_ClearWeakRefsNoCallbacks(PyObject *obj);
+
+PyAPI_FUNC(int) _PyWeakref_IsDead(PyObject *weakref);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_WEAKREF_H */