crosshair-tool 0.0.99__cp312-cp312-macosx_10_13_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. _crosshair_tracers.cpython-312-darwin.so +0 -0
  2. crosshair/__init__.py +42 -0
  3. crosshair/__main__.py +8 -0
  4. crosshair/_mark_stacks.h +790 -0
  5. crosshair/_preliminaries_test.py +18 -0
  6. crosshair/_tracers.h +94 -0
  7. crosshair/_tracers_pycompat.h +522 -0
  8. crosshair/_tracers_test.py +138 -0
  9. crosshair/abcstring.py +245 -0
  10. crosshair/auditwall.py +190 -0
  11. crosshair/auditwall_test.py +77 -0
  12. crosshair/codeconfig.py +113 -0
  13. crosshair/codeconfig_test.py +117 -0
  14. crosshair/condition_parser.py +1237 -0
  15. crosshair/condition_parser_test.py +497 -0
  16. crosshair/conftest.py +30 -0
  17. crosshair/copyext.py +155 -0
  18. crosshair/copyext_test.py +84 -0
  19. crosshair/core.py +1763 -0
  20. crosshair/core_and_libs.py +149 -0
  21. crosshair/core_regestered_types_test.py +82 -0
  22. crosshair/core_test.py +1316 -0
  23. crosshair/diff_behavior.py +314 -0
  24. crosshair/diff_behavior_test.py +261 -0
  25. crosshair/dynamic_typing.py +346 -0
  26. crosshair/dynamic_typing_test.py +210 -0
  27. crosshair/enforce.py +282 -0
  28. crosshair/enforce_test.py +182 -0
  29. crosshair/examples/PEP316/__init__.py +1 -0
  30. crosshair/examples/PEP316/bugs_detected/__init__.py +0 -0
  31. crosshair/examples/PEP316/bugs_detected/getattr_magic.py +16 -0
  32. crosshair/examples/PEP316/bugs_detected/hash_consistent_with_equals.py +31 -0
  33. crosshair/examples/PEP316/bugs_detected/shopping_cart.py +24 -0
  34. crosshair/examples/PEP316/bugs_detected/showcase.py +39 -0
  35. crosshair/examples/PEP316/correct_code/__init__.py +0 -0
  36. crosshair/examples/PEP316/correct_code/arith.py +60 -0
  37. crosshair/examples/PEP316/correct_code/chess.py +77 -0
  38. crosshair/examples/PEP316/correct_code/nesting_inference.py +17 -0
  39. crosshair/examples/PEP316/correct_code/numpy_examples.py +132 -0
  40. crosshair/examples/PEP316/correct_code/rolling_average.py +35 -0
  41. crosshair/examples/PEP316/correct_code/showcase.py +104 -0
  42. crosshair/examples/__init__.py +0 -0
  43. crosshair/examples/check_examples_test.py +146 -0
  44. crosshair/examples/deal/__init__.py +1 -0
  45. crosshair/examples/icontract/__init__.py +1 -0
  46. crosshair/examples/icontract/bugs_detected/__init__.py +0 -0
  47. crosshair/examples/icontract/bugs_detected/showcase.py +41 -0
  48. crosshair/examples/icontract/bugs_detected/wrong_sign.py +8 -0
  49. crosshair/examples/icontract/correct_code/__init__.py +0 -0
  50. crosshair/examples/icontract/correct_code/arith.py +51 -0
  51. crosshair/examples/icontract/correct_code/showcase.py +94 -0
  52. crosshair/fnutil.py +391 -0
  53. crosshair/fnutil_test.py +75 -0
  54. crosshair/fuzz_core_test.py +516 -0
  55. crosshair/libimpl/__init__.py +0 -0
  56. crosshair/libimpl/arraylib.py +161 -0
  57. crosshair/libimpl/binascii_ch_test.py +30 -0
  58. crosshair/libimpl/binascii_test.py +67 -0
  59. crosshair/libimpl/binasciilib.py +150 -0
  60. crosshair/libimpl/bisectlib_test.py +23 -0
  61. crosshair/libimpl/builtinslib.py +5228 -0
  62. crosshair/libimpl/builtinslib_ch_test.py +1191 -0
  63. crosshair/libimpl/builtinslib_test.py +3735 -0
  64. crosshair/libimpl/codecslib.py +86 -0
  65. crosshair/libimpl/codecslib_test.py +86 -0
  66. crosshair/libimpl/collectionslib.py +264 -0
  67. crosshair/libimpl/collectionslib_ch_test.py +252 -0
  68. crosshair/libimpl/collectionslib_test.py +332 -0
  69. crosshair/libimpl/copylib.py +23 -0
  70. crosshair/libimpl/copylib_test.py +18 -0
  71. crosshair/libimpl/datetimelib.py +2559 -0
  72. crosshair/libimpl/datetimelib_ch_test.py +354 -0
  73. crosshair/libimpl/datetimelib_test.py +112 -0
  74. crosshair/libimpl/decimallib.py +5257 -0
  75. crosshair/libimpl/decimallib_ch_test.py +78 -0
  76. crosshair/libimpl/decimallib_test.py +76 -0
  77. crosshair/libimpl/encodings/__init__.py +23 -0
  78. crosshair/libimpl/encodings/_encutil.py +187 -0
  79. crosshair/libimpl/encodings/ascii.py +44 -0
  80. crosshair/libimpl/encodings/latin_1.py +40 -0
  81. crosshair/libimpl/encodings/utf_8.py +93 -0
  82. crosshair/libimpl/encodings_ch_test.py +83 -0
  83. crosshair/libimpl/fractionlib.py +16 -0
  84. crosshair/libimpl/fractionlib_test.py +80 -0
  85. crosshair/libimpl/functoolslib.py +34 -0
  86. crosshair/libimpl/functoolslib_test.py +56 -0
  87. crosshair/libimpl/hashliblib.py +30 -0
  88. crosshair/libimpl/hashliblib_test.py +18 -0
  89. crosshair/libimpl/heapqlib.py +47 -0
  90. crosshair/libimpl/heapqlib_test.py +21 -0
  91. crosshair/libimpl/importliblib.py +18 -0
  92. crosshair/libimpl/importliblib_test.py +38 -0
  93. crosshair/libimpl/iolib.py +216 -0
  94. crosshair/libimpl/iolib_ch_test.py +128 -0
  95. crosshair/libimpl/iolib_test.py +19 -0
  96. crosshair/libimpl/ipaddresslib.py +8 -0
  97. crosshair/libimpl/itertoolslib.py +44 -0
  98. crosshair/libimpl/itertoolslib_test.py +44 -0
  99. crosshair/libimpl/jsonlib.py +984 -0
  100. crosshair/libimpl/jsonlib_ch_test.py +42 -0
  101. crosshair/libimpl/jsonlib_test.py +51 -0
  102. crosshair/libimpl/mathlib.py +179 -0
  103. crosshair/libimpl/mathlib_ch_test.py +44 -0
  104. crosshair/libimpl/mathlib_test.py +67 -0
  105. crosshair/libimpl/oslib.py +7 -0
  106. crosshair/libimpl/pathliblib_test.py +10 -0
  107. crosshair/libimpl/randomlib.py +178 -0
  108. crosshair/libimpl/randomlib_test.py +120 -0
  109. crosshair/libimpl/relib.py +846 -0
  110. crosshair/libimpl/relib_ch_test.py +169 -0
  111. crosshair/libimpl/relib_test.py +493 -0
  112. crosshair/libimpl/timelib.py +72 -0
  113. crosshair/libimpl/timelib_test.py +82 -0
  114. crosshair/libimpl/typeslib.py +15 -0
  115. crosshair/libimpl/typeslib_test.py +36 -0
  116. crosshair/libimpl/unicodedatalib.py +75 -0
  117. crosshair/libimpl/unicodedatalib_test.py +42 -0
  118. crosshair/libimpl/urlliblib.py +23 -0
  119. crosshair/libimpl/urlliblib_test.py +19 -0
  120. crosshair/libimpl/weakreflib.py +13 -0
  121. crosshair/libimpl/weakreflib_test.py +69 -0
  122. crosshair/libimpl/zliblib.py +15 -0
  123. crosshair/libimpl/zliblib_test.py +13 -0
  124. crosshair/lsp_server.py +261 -0
  125. crosshair/lsp_server_test.py +30 -0
  126. crosshair/main.py +973 -0
  127. crosshair/main_test.py +543 -0
  128. crosshair/objectproxy.py +376 -0
  129. crosshair/objectproxy_test.py +41 -0
  130. crosshair/opcode_intercept.py +601 -0
  131. crosshair/opcode_intercept_test.py +304 -0
  132. crosshair/options.py +218 -0
  133. crosshair/options_test.py +10 -0
  134. crosshair/patch_equivalence_test.py +75 -0
  135. crosshair/path_cover.py +209 -0
  136. crosshair/path_cover_test.py +138 -0
  137. crosshair/path_search.py +161 -0
  138. crosshair/path_search_test.py +52 -0
  139. crosshair/pathing_oracle.py +271 -0
  140. crosshair/pathing_oracle_test.py +21 -0
  141. crosshair/pure_importer.py +27 -0
  142. crosshair/pure_importer_test.py +16 -0
  143. crosshair/py.typed +0 -0
  144. crosshair/register_contract.py +273 -0
  145. crosshair/register_contract_test.py +190 -0
  146. crosshair/simplestructs.py +1165 -0
  147. crosshair/simplestructs_test.py +283 -0
  148. crosshair/smtlib.py +24 -0
  149. crosshair/smtlib_test.py +14 -0
  150. crosshair/statespace.py +1199 -0
  151. crosshair/statespace_test.py +108 -0
  152. crosshair/stubs_parser.py +352 -0
  153. crosshair/stubs_parser_test.py +43 -0
  154. crosshair/test_util.py +329 -0
  155. crosshair/test_util_test.py +26 -0
  156. crosshair/tools/__init__.py +0 -0
  157. crosshair/tools/check_help_in_doc.py +264 -0
  158. crosshair/tools/check_init_and_setup_coincide.py +119 -0
  159. crosshair/tools/generate_demo_table.py +127 -0
  160. crosshair/tracers.py +544 -0
  161. crosshair/tracers_test.py +154 -0
  162. crosshair/type_repo.py +151 -0
  163. crosshair/unicode_categories.py +589 -0
  164. crosshair/unicode_categories_test.py +27 -0
  165. crosshair/util.py +741 -0
  166. crosshair/util_test.py +173 -0
  167. crosshair/watcher.py +307 -0
  168. crosshair/watcher_test.py +107 -0
  169. crosshair/z3util.py +76 -0
  170. crosshair/z3util_test.py +11 -0
  171. crosshair_tool-0.0.99.dist-info/METADATA +144 -0
  172. crosshair_tool-0.0.99.dist-info/RECORD +176 -0
  173. crosshair_tool-0.0.99.dist-info/WHEEL +6 -0
  174. crosshair_tool-0.0.99.dist-info/entry_points.txt +3 -0
  175. crosshair_tool-0.0.99.dist-info/licenses/LICENSE +93 -0
  176. crosshair_tool-0.0.99.dist-info/top_level.txt +2 -0
@@ -0,0 +1,790 @@
1
+ #include "_tracers_pycompat.h"
2
+ #include "internal/pycore_code.h"
3
+
4
+
5
+ // This file includes a modified version of CPython's mark_stacks
6
+ // implementation from:
7
+ // https://github.com/python/cpython/blob/v3.12.0/Objects/frameobject.c
8
+
9
+ // The shared source code is licensed under the PSF license and is
10
+ // copyright © 2001-2023 Python Software Foundation; All Rights Reserved
11
+
12
+ // See the "LICENSE" file for complete license details on CrossHair.
13
+
14
+
15
+
16
+ #define UNINITIALIZED -9
17
+ #define OVERFLOWED -8
18
+ #define EMPTY_STACK 0
19
+
20
+ static int64_t
21
+ _ch_pop_to_level(int64_t stack, int level) {
22
+ if (level == 0) {
23
+ return EMPTY_STACK;
24
+ }
25
+ if (level < stack) {
26
+ return level;
27
+ } else {
28
+ return stack;
29
+ }
30
+ }
31
+
32
+
33
+ #if PY_VERSION_HEX >= 0x030D0000
34
+ #if PY_VERSION_HEX < 0x030E0000
35
+ // ===========
36
+ // Python 3.13
37
+ // ===========
38
+
39
+ // from Include/internal/pycore_opcode_metadata.h
40
+ const uint8_t _ch_PyOpcode_Caches[256] = {
41
+ [JUMP_BACKWARD] = 1,
42
+ [TO_BOOL] = 3,
43
+ [BINARY_SUBSCR] = 1,
44
+ [STORE_SUBSCR] = 1,
45
+ [SEND] = 1,
46
+ [UNPACK_SEQUENCE] = 1,
47
+ [STORE_ATTR] = 4,
48
+ [LOAD_GLOBAL] = 4,
49
+ [LOAD_SUPER_ATTR] = 1,
50
+ [LOAD_ATTR] = 9,
51
+ [COMPARE_OP] = 1,
52
+ [CONTAINS_OP] = 1,
53
+ [POP_JUMP_IF_TRUE] = 1,
54
+ [POP_JUMP_IF_FALSE] = 1,
55
+ [POP_JUMP_IF_NONE] = 1,
56
+ [POP_JUMP_IF_NOT_NONE] = 1,
57
+ [FOR_ITER] = 1,
58
+ [CALL] = 3,
59
+ [BINARY_OP] = 1,
60
+ };
61
+
62
+ // from Include/internal/pycore_opcode_metadata.h
63
+ const uint8_t _ch_PyOpcode_Deopt[256] = {
64
+ [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH,
65
+ [BEFORE_WITH] = BEFORE_WITH,
66
+ [BINARY_OP] = BINARY_OP,
67
+ [BINARY_OP_ADD_FLOAT] = BINARY_OP,
68
+ [BINARY_OP_ADD_INT] = BINARY_OP,
69
+ [BINARY_OP_ADD_UNICODE] = BINARY_OP,
70
+ [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP,
71
+ [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP,
72
+ [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
73
+ [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
74
+ [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
75
+ [BINARY_SLICE] = BINARY_SLICE,
76
+ [BINARY_SUBSCR] = BINARY_SUBSCR,
77
+ [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
78
+ [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
79
+ [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
80
+ [BINARY_SUBSCR_STR_INT] = BINARY_SUBSCR,
81
+ [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
82
+ [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
83
+ [BUILD_LIST] = BUILD_LIST,
84
+ [BUILD_MAP] = BUILD_MAP,
85
+ [BUILD_SET] = BUILD_SET,
86
+ [BUILD_SLICE] = BUILD_SLICE,
87
+ [BUILD_STRING] = BUILD_STRING,
88
+ [BUILD_TUPLE] = BUILD_TUPLE,
89
+ [CACHE] = CACHE,
90
+ [CALL] = CALL,
91
+ [CALL_ALLOC_AND_ENTER_INIT] = CALL,
92
+ [CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
93
+ [CALL_BOUND_METHOD_GENERAL] = CALL,
94
+ [CALL_BUILTIN_CLASS] = CALL,
95
+ [CALL_BUILTIN_FAST] = CALL,
96
+ [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
97
+ [CALL_BUILTIN_O] = CALL,
98
+ [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
99
+ [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
100
+ [CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
101
+ [CALL_ISINSTANCE] = CALL,
102
+ [CALL_KW] = CALL_KW,
103
+ [CALL_LEN] = CALL,
104
+ [CALL_LIST_APPEND] = CALL,
105
+ [CALL_METHOD_DESCRIPTOR_FAST] = CALL,
106
+ [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
107
+ [CALL_METHOD_DESCRIPTOR_NOARGS] = CALL,
108
+ [CALL_METHOD_DESCRIPTOR_O] = CALL,
109
+ [CALL_NON_PY_GENERAL] = CALL,
110
+ [CALL_PY_EXACT_ARGS] = CALL,
111
+ [CALL_PY_GENERAL] = CALL,
112
+ [CALL_STR_1] = CALL,
113
+ [CALL_TUPLE_1] = CALL,
114
+ [CALL_TYPE_1] = CALL,
115
+ [CHECK_EG_MATCH] = CHECK_EG_MATCH,
116
+ [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
117
+ [CLEANUP_THROW] = CLEANUP_THROW,
118
+ [COMPARE_OP] = COMPARE_OP,
119
+ [COMPARE_OP_FLOAT] = COMPARE_OP,
120
+ [COMPARE_OP_INT] = COMPARE_OP,
121
+ [COMPARE_OP_STR] = COMPARE_OP,
122
+ [CONTAINS_OP] = CONTAINS_OP,
123
+ [CONTAINS_OP_DICT] = CONTAINS_OP,
124
+ [CONTAINS_OP_SET] = CONTAINS_OP,
125
+ [CONVERT_VALUE] = CONVERT_VALUE,
126
+ [COPY] = COPY,
127
+ [COPY_FREE_VARS] = COPY_FREE_VARS,
128
+ [DELETE_ATTR] = DELETE_ATTR,
129
+ [DELETE_DEREF] = DELETE_DEREF,
130
+ [DELETE_FAST] = DELETE_FAST,
131
+ [DELETE_GLOBAL] = DELETE_GLOBAL,
132
+ [DELETE_NAME] = DELETE_NAME,
133
+ [DELETE_SUBSCR] = DELETE_SUBSCR,
134
+ [DICT_MERGE] = DICT_MERGE,
135
+ [DICT_UPDATE] = DICT_UPDATE,
136
+ [END_ASYNC_FOR] = END_ASYNC_FOR,
137
+ [END_FOR] = END_FOR,
138
+ [END_SEND] = END_SEND,
139
+ [ENTER_EXECUTOR] = ENTER_EXECUTOR,
140
+ [EXIT_INIT_CHECK] = EXIT_INIT_CHECK,
141
+ [EXTENDED_ARG] = EXTENDED_ARG,
142
+ [FORMAT_SIMPLE] = FORMAT_SIMPLE,
143
+ [FORMAT_WITH_SPEC] = FORMAT_WITH_SPEC,
144
+ [FOR_ITER] = FOR_ITER,
145
+ [FOR_ITER_GEN] = FOR_ITER,
146
+ [FOR_ITER_LIST] = FOR_ITER,
147
+ [FOR_ITER_RANGE] = FOR_ITER,
148
+ [FOR_ITER_TUPLE] = FOR_ITER,
149
+ [GET_AITER] = GET_AITER,
150
+ [GET_ANEXT] = GET_ANEXT,
151
+ [GET_AWAITABLE] = GET_AWAITABLE,
152
+ [GET_ITER] = GET_ITER,
153
+ [GET_LEN] = GET_LEN,
154
+ [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
155
+ [IMPORT_FROM] = IMPORT_FROM,
156
+ [IMPORT_NAME] = IMPORT_NAME,
157
+ [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
158
+ [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
159
+ [INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW,
160
+ [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
161
+ [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
162
+ [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
163
+ [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
164
+ [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
165
+ [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
166
+ [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
167
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
168
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
169
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
170
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
171
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
172
+ [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME,
173
+ [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
174
+ [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
175
+ [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
176
+ [INTERPRETER_EXIT] = INTERPRETER_EXIT,
177
+ [IS_OP] = IS_OP,
178
+ [JUMP_BACKWARD] = JUMP_BACKWARD,
179
+ [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
180
+ [JUMP_FORWARD] = JUMP_FORWARD,
181
+ [LIST_APPEND] = LIST_APPEND,
182
+ [LIST_EXTEND] = LIST_EXTEND,
183
+ [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
184
+ [LOAD_ATTR] = LOAD_ATTR,
185
+ [LOAD_ATTR_CLASS] = LOAD_ATTR,
186
+ [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
187
+ [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
188
+ [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
189
+ [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
190
+ [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
191
+ [LOAD_ATTR_MODULE] = LOAD_ATTR,
192
+ [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR,
193
+ [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR,
194
+ [LOAD_ATTR_PROPERTY] = LOAD_ATTR,
195
+ [LOAD_ATTR_SLOT] = LOAD_ATTR,
196
+ [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
197
+ [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
198
+ [LOAD_CONST] = LOAD_CONST,
199
+ [LOAD_DEREF] = LOAD_DEREF,
200
+ [LOAD_FAST] = LOAD_FAST,
201
+ [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR,
202
+ [LOAD_FAST_CHECK] = LOAD_FAST_CHECK,
203
+ [LOAD_FAST_LOAD_FAST] = LOAD_FAST_LOAD_FAST,
204
+ [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF,
205
+ [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS,
206
+ [LOAD_GLOBAL] = LOAD_GLOBAL,
207
+ [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
208
+ [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
209
+ [LOAD_LOCALS] = LOAD_LOCALS,
210
+ [LOAD_NAME] = LOAD_NAME,
211
+ [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
212
+ [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
213
+ [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
214
+ [MAKE_CELL] = MAKE_CELL,
215
+ [MAKE_FUNCTION] = MAKE_FUNCTION,
216
+ [MAP_ADD] = MAP_ADD,
217
+ [MATCH_CLASS] = MATCH_CLASS,
218
+ [MATCH_KEYS] = MATCH_KEYS,
219
+ [MATCH_MAPPING] = MATCH_MAPPING,
220
+ [MATCH_SEQUENCE] = MATCH_SEQUENCE,
221
+ [NOP] = NOP,
222
+ [POP_EXCEPT] = POP_EXCEPT,
223
+ [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
224
+ [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
225
+ [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
226
+ [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
227
+ [POP_TOP] = POP_TOP,
228
+ [PUSH_EXC_INFO] = PUSH_EXC_INFO,
229
+ [PUSH_NULL] = PUSH_NULL,
230
+ [RAISE_VARARGS] = RAISE_VARARGS,
231
+ [RERAISE] = RERAISE,
232
+ [RESERVED] = RESERVED,
233
+ [RESUME] = RESUME,
234
+ [RESUME_CHECK] = RESUME,
235
+ [RETURN_CONST] = RETURN_CONST,
236
+ [RETURN_GENERATOR] = RETURN_GENERATOR,
237
+ [RETURN_VALUE] = RETURN_VALUE,
238
+ [SEND] = SEND,
239
+ [SEND_GEN] = SEND,
240
+ [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
241
+ [SET_ADD] = SET_ADD,
242
+ [SET_FUNCTION_ATTRIBUTE] = SET_FUNCTION_ATTRIBUTE,
243
+ [SET_UPDATE] = SET_UPDATE,
244
+ [STORE_ATTR] = STORE_ATTR,
245
+ [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
246
+ [STORE_ATTR_SLOT] = STORE_ATTR,
247
+ [STORE_ATTR_WITH_HINT] = STORE_ATTR,
248
+ [STORE_DEREF] = STORE_DEREF,
249
+ [STORE_FAST] = STORE_FAST,
250
+ [STORE_FAST_LOAD_FAST] = STORE_FAST_LOAD_FAST,
251
+ [STORE_FAST_STORE_FAST] = STORE_FAST_STORE_FAST,
252
+ [STORE_GLOBAL] = STORE_GLOBAL,
253
+ [STORE_NAME] = STORE_NAME,
254
+ [STORE_SLICE] = STORE_SLICE,
255
+ [STORE_SUBSCR] = STORE_SUBSCR,
256
+ [STORE_SUBSCR_DICT] = STORE_SUBSCR,
257
+ [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR,
258
+ [SWAP] = SWAP,
259
+ [TO_BOOL] = TO_BOOL,
260
+ [TO_BOOL_ALWAYS_TRUE] = TO_BOOL,
261
+ [TO_BOOL_BOOL] = TO_BOOL,
262
+ [TO_BOOL_INT] = TO_BOOL,
263
+ [TO_BOOL_LIST] = TO_BOOL,
264
+ [TO_BOOL_NONE] = TO_BOOL,
265
+ [TO_BOOL_STR] = TO_BOOL,
266
+ [UNARY_INVERT] = UNARY_INVERT,
267
+ [UNARY_NEGATIVE] = UNARY_NEGATIVE,
268
+ [UNARY_NOT] = UNARY_NOT,
269
+ [UNPACK_EX] = UNPACK_EX,
270
+ [UNPACK_SEQUENCE] = UNPACK_SEQUENCE,
271
+ [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE,
272
+ [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE,
273
+ [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
274
+ [WITH_EXCEPT_START] = WITH_EXCEPT_START,
275
+ [YIELD_VALUE] = YIELD_VALUE,
276
+ };
277
+
278
+ // from Python/instrumentation.c
279
+ static const uint8_t _ch_DE_INSTRUMENT[256] = {
280
+ [INSTRUMENTED_RESUME] = RESUME,
281
+ [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE,
282
+ [INSTRUMENTED_RETURN_CONST] = RETURN_CONST,
283
+ [INSTRUMENTED_CALL] = CALL,
284
+ [INSTRUMENTED_CALL_KW] = CALL_KW,
285
+ [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
286
+ [INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE,
287
+ [INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD,
288
+ [INSTRUMENTED_JUMP_BACKWARD] = JUMP_BACKWARD,
289
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
290
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
291
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
292
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
293
+ [INSTRUMENTED_FOR_ITER] = FOR_ITER,
294
+ [INSTRUMENTED_END_FOR] = END_FOR,
295
+ [INSTRUMENTED_END_SEND] = END_SEND,
296
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
297
+ };
298
+
299
+ #endif
300
+ #endif
301
+
302
+ #if PY_VERSION_HEX >= 0x030C0000
303
+ #if PY_VERSION_HEX < 0x030D0000
304
+ // ===========
305
+ // Python 3.12
306
+ // ===========
307
+
308
+ const uint8_t _ch_PyOpcode_Caches[256] = {
309
+ [BINARY_SUBSCR] = 1,
310
+ [STORE_SUBSCR] = 1,
311
+ [UNPACK_SEQUENCE] = 1,
312
+ [FOR_ITER] = 1,
313
+ [STORE_ATTR] = 4,
314
+ [LOAD_ATTR] = 9,
315
+ [COMPARE_OP] = 1,
316
+ [LOAD_GLOBAL] = 4,
317
+ [BINARY_OP] = 1,
318
+ [SEND] = 1,
319
+ [LOAD_SUPER_ATTR] = 1,
320
+ [CALL] = 3,
321
+ };
322
+
323
+ const uint8_t _ch_PyOpcode_Deopt[256] = {
324
+ [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH,
325
+ [BEFORE_WITH] = BEFORE_WITH,
326
+ [BINARY_OP] = BINARY_OP,
327
+ [BINARY_OP_ADD_FLOAT] = BINARY_OP,
328
+ [BINARY_OP_ADD_INT] = BINARY_OP,
329
+ [BINARY_OP_ADD_UNICODE] = BINARY_OP,
330
+ [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP,
331
+ [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP,
332
+ [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
333
+ [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
334
+ [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
335
+ [BINARY_SLICE] = BINARY_SLICE,
336
+ [BINARY_SUBSCR] = BINARY_SUBSCR,
337
+ [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
338
+ [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
339
+ [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
340
+ [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
341
+ [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
342
+ [BUILD_LIST] = BUILD_LIST,
343
+ [BUILD_MAP] = BUILD_MAP,
344
+ [BUILD_SET] = BUILD_SET,
345
+ [BUILD_SLICE] = BUILD_SLICE,
346
+ [BUILD_STRING] = BUILD_STRING,
347
+ [BUILD_TUPLE] = BUILD_TUPLE,
348
+ [CACHE] = CACHE,
349
+ [CALL] = CALL,
350
+ [CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
351
+ [CALL_BUILTIN_CLASS] = CALL,
352
+ [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
353
+ [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
354
+ [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
355
+ [CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
356
+ [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
357
+ [CALL_NO_KW_BUILTIN_FAST] = CALL,
358
+ [CALL_NO_KW_BUILTIN_O] = CALL,
359
+ [CALL_NO_KW_ISINSTANCE] = CALL,
360
+ [CALL_NO_KW_LEN] = CALL,
361
+ [CALL_NO_KW_LIST_APPEND] = CALL,
362
+ [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL,
363
+ [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL,
364
+ [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL,
365
+ [CALL_NO_KW_STR_1] = CALL,
366
+ [CALL_NO_KW_TUPLE_1] = CALL,
367
+ [CALL_NO_KW_TYPE_1] = CALL,
368
+ [CALL_PY_EXACT_ARGS] = CALL,
369
+ [CALL_PY_WITH_DEFAULTS] = CALL,
370
+ [CHECK_EG_MATCH] = CHECK_EG_MATCH,
371
+ [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
372
+ [CLEANUP_THROW] = CLEANUP_THROW,
373
+ [COMPARE_OP] = COMPARE_OP,
374
+ [COMPARE_OP_FLOAT] = COMPARE_OP,
375
+ [COMPARE_OP_INT] = COMPARE_OP,
376
+ [COMPARE_OP_STR] = COMPARE_OP,
377
+ [CONTAINS_OP] = CONTAINS_OP,
378
+ [COPY] = COPY,
379
+ [COPY_FREE_VARS] = COPY_FREE_VARS,
380
+ [DELETE_ATTR] = DELETE_ATTR,
381
+ [DELETE_DEREF] = DELETE_DEREF,
382
+ [DELETE_FAST] = DELETE_FAST,
383
+ [DELETE_GLOBAL] = DELETE_GLOBAL,
384
+ [DELETE_NAME] = DELETE_NAME,
385
+ [DELETE_SUBSCR] = DELETE_SUBSCR,
386
+ [DICT_MERGE] = DICT_MERGE,
387
+ [DICT_UPDATE] = DICT_UPDATE,
388
+ [END_ASYNC_FOR] = END_ASYNC_FOR,
389
+ [END_FOR] = END_FOR,
390
+ [END_SEND] = END_SEND,
391
+ [EXTENDED_ARG] = EXTENDED_ARG,
392
+ [FORMAT_VALUE] = FORMAT_VALUE,
393
+ [FOR_ITER] = FOR_ITER,
394
+ [FOR_ITER_GEN] = FOR_ITER,
395
+ [FOR_ITER_LIST] = FOR_ITER,
396
+ [FOR_ITER_RANGE] = FOR_ITER,
397
+ [FOR_ITER_TUPLE] = FOR_ITER,
398
+ [GET_AITER] = GET_AITER,
399
+ [GET_ANEXT] = GET_ANEXT,
400
+ [GET_AWAITABLE] = GET_AWAITABLE,
401
+ [GET_ITER] = GET_ITER,
402
+ [GET_LEN] = GET_LEN,
403
+ [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
404
+ [IMPORT_FROM] = IMPORT_FROM,
405
+ [IMPORT_NAME] = IMPORT_NAME,
406
+ [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
407
+ [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
408
+ [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
409
+ [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
410
+ [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
411
+ [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
412
+ [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
413
+ [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
414
+ [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
415
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
416
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
417
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
418
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
419
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
420
+ [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME,
421
+ [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
422
+ [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
423
+ [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
424
+ [INTERPRETER_EXIT] = INTERPRETER_EXIT,
425
+ [IS_OP] = IS_OP,
426
+ [JUMP_BACKWARD] = JUMP_BACKWARD,
427
+ [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
428
+ [JUMP_FORWARD] = JUMP_FORWARD,
429
+ [KW_NAMES] = KW_NAMES,
430
+ [LIST_APPEND] = LIST_APPEND,
431
+ [LIST_EXTEND] = LIST_EXTEND,
432
+ [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
433
+ [LOAD_ATTR] = LOAD_ATTR,
434
+ [LOAD_ATTR_CLASS] = LOAD_ATTR,
435
+ [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
436
+ [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
437
+ [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
438
+ [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
439
+ [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
440
+ [LOAD_ATTR_MODULE] = LOAD_ATTR,
441
+ [LOAD_ATTR_PROPERTY] = LOAD_ATTR,
442
+ [LOAD_ATTR_SLOT] = LOAD_ATTR,
443
+ [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
444
+ [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
445
+ [LOAD_CLOSURE] = LOAD_CLOSURE,
446
+ [LOAD_CONST] = LOAD_CONST,
447
+ [LOAD_CONST__LOAD_FAST] = LOAD_CONST,
448
+ [LOAD_DEREF] = LOAD_DEREF,
449
+ [LOAD_FAST] = LOAD_FAST,
450
+ [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR,
451
+ [LOAD_FAST_CHECK] = LOAD_FAST_CHECK,
452
+ [LOAD_FAST__LOAD_CONST] = LOAD_FAST,
453
+ [LOAD_FAST__LOAD_FAST] = LOAD_FAST,
454
+ [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF,
455
+ [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS,
456
+ [LOAD_GLOBAL] = LOAD_GLOBAL,
457
+ [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
458
+ [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
459
+ [LOAD_LOCALS] = LOAD_LOCALS,
460
+ [LOAD_NAME] = LOAD_NAME,
461
+ [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
462
+ [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
463
+ [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
464
+ [MAKE_CELL] = MAKE_CELL,
465
+ [MAKE_FUNCTION] = MAKE_FUNCTION,
466
+ [MAP_ADD] = MAP_ADD,
467
+ [MATCH_CLASS] = MATCH_CLASS,
468
+ [MATCH_KEYS] = MATCH_KEYS,
469
+ [MATCH_MAPPING] = MATCH_MAPPING,
470
+ [MATCH_SEQUENCE] = MATCH_SEQUENCE,
471
+ [NOP] = NOP,
472
+ [POP_EXCEPT] = POP_EXCEPT,
473
+ [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
474
+ [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
475
+ [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
476
+ [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
477
+ [POP_TOP] = POP_TOP,
478
+ [PUSH_EXC_INFO] = PUSH_EXC_INFO,
479
+ [PUSH_NULL] = PUSH_NULL,
480
+ [RAISE_VARARGS] = RAISE_VARARGS,
481
+ [RERAISE] = RERAISE,
482
+ [RESERVED] = RESERVED,
483
+ [RESUME] = RESUME,
484
+ [RETURN_CONST] = RETURN_CONST,
485
+ [RETURN_GENERATOR] = RETURN_GENERATOR,
486
+ [RETURN_VALUE] = RETURN_VALUE,
487
+ [SEND] = SEND,
488
+ [SEND_GEN] = SEND,
489
+ [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
490
+ [SET_ADD] = SET_ADD,
491
+ [SET_UPDATE] = SET_UPDATE,
492
+ [STORE_ATTR] = STORE_ATTR,
493
+ [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
494
+ [STORE_ATTR_SLOT] = STORE_ATTR,
495
+ [STORE_ATTR_WITH_HINT] = STORE_ATTR,
496
+ [STORE_DEREF] = STORE_DEREF,
497
+ [STORE_FAST] = STORE_FAST,
498
+ [STORE_FAST__LOAD_FAST] = STORE_FAST,
499
+ [STORE_FAST__STORE_FAST] = STORE_FAST,
500
+ [STORE_GLOBAL] = STORE_GLOBAL,
501
+ [STORE_NAME] = STORE_NAME,
502
+ [STORE_SLICE] = STORE_SLICE,
503
+ [STORE_SUBSCR] = STORE_SUBSCR,
504
+ [STORE_SUBSCR_DICT] = STORE_SUBSCR,
505
+ [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR,
506
+ [SWAP] = SWAP,
507
+ [UNARY_INVERT] = UNARY_INVERT,
508
+ [UNARY_NEGATIVE] = UNARY_NEGATIVE,
509
+ [UNARY_NOT] = UNARY_NOT,
510
+ [UNPACK_EX] = UNPACK_EX,
511
+ [UNPACK_SEQUENCE] = UNPACK_SEQUENCE,
512
+ [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE,
513
+ [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE,
514
+ [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
515
+ [WITH_EXCEPT_START] = WITH_EXCEPT_START,
516
+ [YIELD_VALUE] = YIELD_VALUE,
517
+ };
518
+
519
+ static const uint8_t _ch_DE_INSTRUMENT[256] = {
520
+ [INSTRUMENTED_RESUME] = RESUME,
521
+ [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE,
522
+ [INSTRUMENTED_RETURN_CONST] = RETURN_CONST,
523
+ [INSTRUMENTED_CALL] = CALL,
524
+ [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
525
+ [INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE,
526
+ [INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD,
527
+ [INSTRUMENTED_JUMP_BACKWARD] = JUMP_BACKWARD,
528
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
529
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
530
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
531
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
532
+ [INSTRUMENTED_FOR_ITER] = FOR_ITER,
533
+ [INSTRUMENTED_END_FOR] = END_FOR,
534
+ [INSTRUMENTED_END_SEND] = END_SEND,
535
+ [INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
536
+ };
537
+
538
+ #endif
539
+ #endif
540
+
541
+ static int64_t *
542
+ _ch_mark_stacks(PyCodeObject *code_obj, int len)
543
+ {
544
+ // This differs from the corresponding function in CPython in a few ways:
545
+ // 1) The returned stack values represent stack depths, not stack content types.
546
+ // 2) The low bit of each depth is a flag that indicates whether this is an
547
+ // instruction that we trace, or it could follow an instruction that we trace.
548
+ PyObject *co_code = PyCode_GetCode(code_obj);
549
+ // printf("co_code %d\n", co_code);
550
+ if (co_code == NULL) {
551
+ return NULL;
552
+ }
553
+ _Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(co_code);
554
+ int64_t *stacks = PyMem_New(int64_t, len+1);
555
+ if (stacks == NULL) {
556
+ PyErr_NoMemory();
557
+ Py_DECREF(co_code);
558
+ return NULL;
559
+ }
560
+ uint8_t *enabled_tracing = PyMem_New(uint8_t, len+1);
561
+ if (enabled_tracing == NULL) {
562
+ PyErr_NoMemory();
563
+ PyMem_Free(stacks);
564
+ Py_DECREF(co_code);
565
+ return NULL;
566
+ }
567
+ int i, j, opcode;
568
+
569
+ for (int i = 1; i <= len; i++) {
570
+ stacks[i] = UNINITIALIZED;
571
+ enabled_tracing[i] = 0;
572
+ }
573
+ stacks[0] = EMPTY_STACK;
574
+ #if PY_VERSION_HEX < 0x030D0000
575
+ // Python 3.12
576
+ if (code_obj->co_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR))
577
+ {
578
+ // Generators get sent None while starting:
579
+ stacks[0]++;
580
+ }
581
+ #endif
582
+ int todo = 1;
583
+ while (todo) {
584
+ todo = 0;
585
+ /* Scan instructions */
586
+ for (i = 0; i < len;) {
587
+ int64_t next_stack = stacks[i];
588
+ opcode = code[i].op.code;
589
+ uint8_t trace_enabled_here = _ch_TRACABLE_INSTRUCTIONS[opcode];
590
+ enabled_tracing[i] |= trace_enabled_here;
591
+ int oparg = 0;
592
+ while (opcode == EXTENDED_ARG) {
593
+ oparg = (oparg << 8) | code[i].op.arg;
594
+ i++;
595
+ opcode = code[i].op.code;
596
+ stacks[i] = next_stack;
597
+ }
598
+ int next_i = i + _ch_PyOpcode_Caches[opcode] + 1;
599
+ if (next_stack == UNINITIALIZED) {
600
+ i = next_i;
601
+ continue;
602
+ }
603
+ oparg = (oparg << 8) | code[i].op.arg;
604
+ // printf("at %d opcode %d oparg %d priorstack %d\n", i, opcode, oparg, next_stack);
605
+ switch (opcode) {
606
+ case POP_JUMP_IF_FALSE:
607
+ case POP_JUMP_IF_TRUE:
608
+ case POP_JUMP_IF_NONE:
609
+ case POP_JUMP_IF_NOT_NONE:
610
+ {
611
+ int64_t target_stack;
612
+ int j = next_i + oparg;
613
+ assert(j < len);
614
+ next_stack--;
615
+ target_stack = next_stack;
616
+ assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack);
617
+ stacks[j] = target_stack;
618
+ enabled_tracing[j] |= trace_enabled_here;
619
+ stacks[next_i] = next_stack;
620
+ break;
621
+ }
622
+ case SEND:
623
+ j = oparg + i + INLINE_CACHE_ENTRIES_SEND + 1;
624
+ assert(j < len);
625
+ assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
626
+ stacks[j] = next_stack;
627
+ enabled_tracing[j] |= trace_enabled_here;
628
+ stacks[next_i] = next_stack;
629
+ break;
630
+ case JUMP_FORWARD:
631
+ j = oparg + i + 1;
632
+ assert(j < len);
633
+ assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
634
+ stacks[j] = next_stack;
635
+ enabled_tracing[j] |= trace_enabled_here;
636
+ break;
637
+ case JUMP_BACKWARD:
638
+ case JUMP_BACKWARD_NO_INTERRUPT:
639
+ j = next_i - oparg;
640
+ assert(j >= 0);
641
+ assert(j < len);
642
+ if (stacks[j] == UNINITIALIZED && j < i) {
643
+ todo = 1;
644
+ }
645
+ assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack);
646
+ stacks[j] = next_stack;
647
+ enabled_tracing[j] |= trace_enabled_here;
648
+ break;
649
+ case GET_ITER:
650
+ case GET_AITER:
651
+ stacks[next_i] = next_stack;
652
+ break;
653
+ case FOR_ITER:
654
+ {
655
+ int64_t target_stack = next_stack + 1;
656
+ stacks[next_i] = target_stack;
657
+ j = oparg + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + i;
658
+ assert(j < len);
659
+ assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack);
660
+ stacks[j] = target_stack;
661
+ enabled_tracing[j] |= trace_enabled_here;
662
+ break;
663
+ }
664
+ case END_ASYNC_FOR:
665
+ #if PY_VERSION_HEX < 0x030D0000
666
+ // Python 3.12
667
+ next_stack--;
668
+ #else
669
+ // Python 3.13+
670
+ next_stack--;
671
+ next_stack--;
672
+ #endif
673
+ stacks[next_i] = next_stack;
674
+ break;
675
+ case PUSH_EXC_INFO:
676
+ next_stack++;
677
+ stacks[next_i] = next_stack;
678
+ break;
679
+ case POP_EXCEPT:
680
+ next_stack--;
681
+ stacks[next_i] = next_stack;
682
+ break;
683
+ case RETURN_VALUE:
684
+ break;
685
+ case RETURN_CONST:
686
+ break;
687
+ case RAISE_VARARGS:
688
+ break;
689
+ case RERAISE:
690
+ /* End of block */
691
+ break;
692
+ case PUSH_NULL:
693
+ next_stack++;
694
+ stacks[next_i] = next_stack;
695
+ break;
696
+ case LOAD_GLOBAL:
697
+ {
698
+ int j = oparg;
699
+ next_stack++;
700
+ if (j & 1) {
701
+ next_stack++;
702
+ }
703
+ stacks[next_i] = next_stack;
704
+ break;
705
+ }
706
+ case LOAD_ATTR:
707
+ {
708
+ int j = oparg;
709
+ if (j & 1) {
710
+ next_stack--;
711
+ next_stack++;
712
+ next_stack++;
713
+ }
714
+ stacks[next_i] = next_stack;
715
+ break;
716
+ }
717
+ case SWAP:
718
+ {
719
+ stacks[next_i] = next_stack;
720
+ break;
721
+ }
722
+ case COPY:
723
+ {
724
+ next_stack++;
725
+ stacks[next_i] = next_stack;
726
+ break;
727
+ }
728
+ case CACHE:
729
+ case RESERVED:
730
+ {
731
+ assert(0);
732
+ }
733
+ default:
734
+ {
735
+ int delta = PyCompile_OpcodeStackEffect(opcode, oparg);
736
+ assert(delta != PY_INVALID_STACK_EFFECT);
737
+ while (delta < 0) {
738
+ next_stack--;
739
+ delta++;
740
+ }
741
+ while (delta > 0) {
742
+ next_stack++;
743
+ delta--;
744
+ }
745
+ stacks[next_i] = next_stack;
746
+ }
747
+ }
748
+ enabled_tracing[next_i] |= trace_enabled_here;
749
+ i = next_i;
750
+ }
751
+ /* Scan exception table */
752
+ unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code_obj->co_exceptiontable);
753
+ unsigned char *end = start + PyBytes_GET_SIZE(code_obj->co_exceptiontable);
754
+ unsigned char *scan = start;
755
+ while (scan < end) {
756
+ int start_offset, size, handler;
757
+ scan = parse_varint(scan, &start_offset);
758
+ assert(start_offset >= 0 && start_offset < len);
759
+ scan = parse_varint(scan, &size);
760
+ assert(size >= 0 && start_offset+size <= len);
761
+ scan = parse_varint(scan, &handler);
762
+ assert(handler >= 0 && handler < len);
763
+ int depth_and_lasti;
764
+ scan = parse_varint(scan, &depth_and_lasti);
765
+ int level = depth_and_lasti >> 1;
766
+ int lasti = depth_and_lasti & 1;
767
+ // printf("scan %d, end %d, start_offset %d, size %d, handler %d, level %d, lasti %d\n",
768
+ // scan, end, start_offset, size, handler, level, lasti);
769
+ if (stacks[start_offset] != UNINITIALIZED) {
770
+ if (stacks[handler] == UNINITIALIZED) {
771
+ todo = 1;
772
+ uint64_t target_stack = _ch_pop_to_level(stacks[start_offset], level);
773
+ if (lasti) {
774
+ target_stack++;
775
+ }
776
+ target_stack++;
777
+ stacks[handler] = target_stack;
778
+ }
779
+ }
780
+ }
781
+ }
782
+ Py_DECREF(co_code);
783
+ for (i = 0; i < len; i++) {
784
+ if (stacks[i] >= 0) {
785
+ stacks[i] = (stacks[i] << 1) | enabled_tracing[i];
786
+ }
787
+ }
788
+ PyMem_Free(enabled_tracing);
789
+ return stacks;
790
+ }