mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	GH-135379: Remove types from stack items in code generator. (GH-135384)
* Make casts explicit in the instruction definitions
This commit is contained in:
		
							parent
							
								
									49d72365cd
								
							
						
					
					
						commit
						c87b5b2cb6
					
				
					 13 changed files with 257 additions and 255 deletions
				
			
		|  | @ -264,6 +264,32 @@ PyStackRef_IsNullOrInt(_PyStackRef ref); | ||||||
| 
 | 
 | ||||||
| static const _PyStackRef PyStackRef_ERROR = { .bits = Py_TAG_INVALID }; | static const _PyStackRef PyStackRef_ERROR = { .bits = Py_TAG_INVALID }; | ||||||
| 
 | 
 | ||||||
|  | /* Wrap a pointer in a stack ref.
 | ||||||
|  |  * The resulting stack reference is not safe and should only be used | ||||||
|  |  * in the interpreter to pass values from one uop to another. | ||||||
|  |  * The GC should never see one of these stack refs. */ | ||||||
|  | static inline _PyStackRef | ||||||
|  | PyStackRef_Wrap(void *ptr) | ||||||
|  | { | ||||||
|  |     assert(ptr != NULL); | ||||||
|  | #ifdef Py_DEBUG | ||||||
|  |     return (_PyStackRef){ .bits = ((uintptr_t)ptr) | Py_TAG_INVALID }; | ||||||
|  | #else | ||||||
|  |     return (_PyStackRef){ .bits = (uintptr_t)ptr }; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void * | ||||||
|  | PyStackRef_Unwrap(_PyStackRef ref) | ||||||
|  | { | ||||||
|  | #ifdef Py_DEBUG | ||||||
|  |     assert ((ref.bits & Py_TAG_BITS) == Py_TAG_INVALID); | ||||||
|  |     return (void *)(ref.bits & ~Py_TAG_BITS); | ||||||
|  | #else | ||||||
|  |     return (void *)(ref.bits); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static inline bool | static inline bool | ||||||
| PyStackRef_IsError(_PyStackRef ref) | PyStackRef_IsError(_PyStackRef ref) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -56,14 +56,14 @@ class TestEffects(unittest.TestCase): | ||||||
|     def test_effect_sizes(self): |     def test_effect_sizes(self): | ||||||
|         stack = Stack() |         stack = Stack() | ||||||
|         inputs = [ |         inputs = [ | ||||||
|             x := StackItem("x", None, "1"), |             x := StackItem("x", "1"), | ||||||
|             y := StackItem("y", None, "oparg"), |             y := StackItem("y", "oparg"), | ||||||
|             z := StackItem("z", None, "oparg*2"), |             z := StackItem("z", "oparg*2"), | ||||||
|         ] |         ] | ||||||
|         outputs = [ |         outputs = [ | ||||||
|             StackItem("x", None, "1"), |             StackItem("x", "1"), | ||||||
|             StackItem("b", None, "oparg*4"), |             StackItem("b", "oparg*4"), | ||||||
|             StackItem("c", None, "1"), |             StackItem("c", "1"), | ||||||
|         ] |         ] | ||||||
|         null = CWriter.null() |         null = CWriter.null() | ||||||
|         stack.pop(z, null) |         stack.pop(z, null) | ||||||
|  | @ -1103,32 +1103,6 @@ def test_array_of_one(self): | ||||||
|         """ |         """ | ||||||
|         self.run_cases_test(input, output) |         self.run_cases_test(input, output) | ||||||
| 
 | 
 | ||||||
|     def test_pointer_to_stackref(self): |  | ||||||
|         input = """ |  | ||||||
|         inst(OP, (arg: _PyStackRef * -- out)) { |  | ||||||
|             out = *arg; |  | ||||||
|             DEAD(arg); |  | ||||||
|         } |  | ||||||
|         """ |  | ||||||
|         output = """ |  | ||||||
|         TARGET(OP) { |  | ||||||
|             #if Py_TAIL_CALL_INTERP |  | ||||||
|             int opcode = OP; |  | ||||||
|             (void)(opcode); |  | ||||||
|             #endif |  | ||||||
|             frame->instr_ptr = next_instr; |  | ||||||
|             next_instr += 1; |  | ||||||
|             INSTRUCTION_STATS(OP); |  | ||||||
|             _PyStackRef *arg; |  | ||||||
|             _PyStackRef out; |  | ||||||
|             arg = (_PyStackRef *)stack_pointer[-1].bits; |  | ||||||
|             out = *arg; |  | ||||||
|             stack_pointer[-1] = out; |  | ||||||
|             DISPATCH(); |  | ||||||
|         } |  | ||||||
|         """ |  | ||||||
|         self.run_cases_test(input, output) |  | ||||||
| 
 |  | ||||||
|     def test_unused_cached_value(self): |     def test_unused_cached_value(self): | ||||||
|         input = """ |         input = """ | ||||||
|         op(FIRST, (arg1 -- out)) { |         op(FIRST, (arg1 -- out)) { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | The cases generator no longer accepts type annotations on stack items. | ||||||
|  | Conversions to non-default types are now done explictly in bytecodes.c and | ||||||
|  | optimizer_bytecodes.c. This will simplify code generation for top-of-stack | ||||||
|  | caching and other future features. | ||||||
|  | @ -985,12 +985,13 @@ dummy_func( | ||||||
|             STAT_INC(BINARY_OP, hit); |             STAT_INC(BINARY_OP, hit); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame: _PyInterpreterFrame* )) { |         op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) { | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); |             _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||||
|             new_frame->localsplus[0] = container; |             pushed_frame->localsplus[0] = container; | ||||||
|             new_frame->localsplus[1] = sub; |             pushed_frame->localsplus[1] = sub; | ||||||
|             INPUTS_DEAD(); |             INPUTS_DEAD(); | ||||||
|             frame->return_offset = INSTRUCTION_SIZE; |             frame->return_offset = INSTRUCTION_SIZE; | ||||||
|  |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         macro(BINARY_OP_SUBSCR_GETITEM) = |         macro(BINARY_OP_SUBSCR_GETITEM) = | ||||||
|  | @ -1296,20 +1297,21 @@ dummy_func( | ||||||
| 
 | 
 | ||||||
|         macro(SEND) = _SPECIALIZE_SEND + _SEND; |         macro(SEND) = _SPECIALIZE_SEND + _SEND; | ||||||
| 
 | 
 | ||||||
|         op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame: _PyInterpreterFrame *)) { |         op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) { | ||||||
|             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver); |             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver); | ||||||
|             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type); |             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type); | ||||||
|             DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); |             DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); | ||||||
|             STAT_INC(SEND, hit); |             STAT_INC(SEND, hit); | ||||||
|             gen_frame = &gen->gi_iframe; |             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); |             _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); | ||||||
|             DEAD(v); |             DEAD(v); | ||||||
|             gen->gi_frame_state = FRAME_EXECUTING; |             gen->gi_frame_state = FRAME_EXECUTING; | ||||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; |             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||||
|             tstate->exc_info = &gen->gi_exc_state; |             tstate->exc_info = &gen->gi_exc_state; | ||||||
|             assert(INSTRUCTION_SIZE + oparg <= UINT16_MAX); |             assert(INSTRUCTION_SIZE + oparg <= UINT16_MAX); | ||||||
|             frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg); |             frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg); | ||||||
|             gen_frame->previous = frame; |             pushed_frame->previous = frame; | ||||||
|  |             gen_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         macro(SEND_GEN) = |         macro(SEND_GEN) = | ||||||
|  | @ -2463,7 +2465,7 @@ dummy_func( | ||||||
|             _LOAD_ATTR_CLASS + |             _LOAD_ATTR_CLASS + | ||||||
|             _PUSH_NULL_CONDITIONAL; |             _PUSH_NULL_CONDITIONAL; | ||||||
| 
 | 
 | ||||||
|         op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _PyInterpreterFrame *)) { |         op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame)) { | ||||||
|             assert((oparg & 1) == 0); |             assert((oparg & 1) == 0); | ||||||
|             assert(Py_IS_TYPE(fget, &PyFunction_Type)); |             assert(Py_IS_TYPE(fget, &PyFunction_Type)); | ||||||
|             PyFunctionObject *f = (PyFunctionObject *)fget; |             PyFunctionObject *f = (PyFunctionObject *)fget; | ||||||
|  | @ -2473,9 +2475,10 @@ dummy_func( | ||||||
|             DEOPT_IF(code->co_argcount != 1); |             DEOPT_IF(code->co_argcount != 1); | ||||||
|             DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); |             DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); | ||||||
|             STAT_INC(LOAD_ATTR, hit); |             STAT_INC(LOAD_ATTR, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||||
|             new_frame->localsplus[0] = owner; |             pushed_frame->localsplus[0] = owner; | ||||||
|             DEAD(owner); |             DEAD(owner); | ||||||
|  |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         macro(LOAD_ATTR_PROPERTY) = |         macro(LOAD_ATTR_PROPERTY) = | ||||||
|  | @ -3344,7 +3347,7 @@ dummy_func( | ||||||
|             _ITER_JUMP_RANGE + |             _ITER_JUMP_RANGE + | ||||||
|             _ITER_NEXT_RANGE; |             _ITER_NEXT_RANGE; | ||||||
| 
 | 
 | ||||||
|         op(_FOR_ITER_GEN_FRAME, (iter, null -- iter, null, gen_frame: _PyInterpreterFrame*)) { |         op(_FOR_ITER_GEN_FRAME, (iter, null -- iter, null, gen_frame)) { | ||||||
|             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); |             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); | ||||||
|             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type); |             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type); | ||||||
| #ifdef Py_GIL_DISABLED | #ifdef Py_GIL_DISABLED | ||||||
|  | @ -3356,14 +3359,15 @@ dummy_func( | ||||||
| #endif | #endif | ||||||
|             DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); |             DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); | ||||||
|             STAT_INC(FOR_ITER, hit); |             STAT_INC(FOR_ITER, hit); | ||||||
|             gen_frame = &gen->gi_iframe; |             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_None); |             _PyFrame_StackPush(pushed_frame, PyStackRef_None); | ||||||
|             gen->gi_frame_state = FRAME_EXECUTING; |             gen->gi_frame_state = FRAME_EXECUTING; | ||||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; |             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||||
|             tstate->exc_info = &gen->gi_exc_state; |             tstate->exc_info = &gen->gi_exc_state; | ||||||
|             gen_frame->previous = frame; |             pushed_frame->previous = frame; | ||||||
|             // oparg is the return offset from the next instruction.
 |             // oparg is the return offset from the next instruction.
 | ||||||
|             frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg); |             frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg); | ||||||
|  |             gen_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         macro(FOR_ITER_GEN) = |         macro(FOR_ITER_GEN) = | ||||||
|  | @ -3715,7 +3719,7 @@ dummy_func( | ||||||
|         macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC; |         macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC; | ||||||
|         macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC; |         macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC; | ||||||
| 
 | 
 | ||||||
|         op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) { |         op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) { | ||||||
|             PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); |             PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); | ||||||
| 
 | 
 | ||||||
|             // oparg counts all of the args, but *not* self:
 |             // oparg counts all of the args, but *not* self:
 | ||||||
|  | @ -3737,7 +3741,7 @@ dummy_func( | ||||||
|             if (temp == NULL) { |             if (temp == NULL) { | ||||||
|                 ERROR_NO_POP(); |                 ERROR_NO_POP(); | ||||||
|             } |             } | ||||||
|             new_frame = temp; |             new_frame = PyStackRef_Wrap(temp); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, unused, unused[oparg] -- callable, unused, unused[oparg])) { |         op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, unused, unused[oparg] -- callable, unused, unused[oparg])) { | ||||||
|  | @ -3874,27 +3878,26 @@ dummy_func( | ||||||
|             DEOPT_IF(tstate->py_recursion_remaining <= 1); |             DEOPT_IF(tstate->py_recursion_remaining <= 1); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         replicate(5) pure op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) { |         replicate(5) pure op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame)) { | ||||||
|             int has_self = !PyStackRef_IsNull(self_or_null); |             int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|             new_frame->localsplus[0] = self_or_null; |             pushed_frame->localsplus[0] = self_or_null; | ||||||
|             for (int i = 0; i < oparg; i++) { |             for (int i = 0; i < oparg; i++) { | ||||||
|                 first_non_self_local[i] = args[i]; |                 first_non_self_local[i] = args[i]; | ||||||
|             } |             } | ||||||
|             INPUTS_DEAD(); |             INPUTS_DEAD(); | ||||||
|  |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         op(_PUSH_FRAME, (new_frame: _PyInterpreterFrame* -- )) { |         op(_PUSH_FRAME, (new_frame -- )) { | ||||||
|             // Write it out explicitly because it's subtly different.
 |  | ||||||
|             // Eventually this should be the only occurrence of this code.
 |  | ||||||
|             assert(tstate->interp->eval_frame == NULL); |             assert(tstate->interp->eval_frame == NULL); | ||||||
|             _PyInterpreterFrame *temp = new_frame; |             _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|             DEAD(new_frame); |             DEAD(new_frame); | ||||||
|             SYNC_SP(); |             SYNC_SP(); | ||||||
|             _PyFrame_SetStackPointer(frame, stack_pointer); |             _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|             assert(new_frame->previous == frame || new_frame->previous->previous == frame); |             assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|             CALL_STAT_INC(inlined_py_calls); |             CALL_STAT_INC(inlined_py_calls); | ||||||
|             frame = tstate->current_frame = temp; |             frame = tstate->current_frame = temp; | ||||||
|             tstate->py_recursion_remaining--; |             tstate->py_recursion_remaining--; | ||||||
|  | @ -4046,7 +4049,7 @@ dummy_func( | ||||||
|             PyStackRef_CLOSE(temp); |             PyStackRef_CLOSE(temp); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame: _PyInterpreterFrame *)) { |         op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame)) { | ||||||
|             _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( |             _PyInterpreterFrame *shim = _PyFrame_PushTrampolineUnchecked( | ||||||
|                 tstate, (PyCodeObject *)&_Py_InitCleanup, 1, frame); |                 tstate, (PyCodeObject *)&_Py_InitCleanup, 1, frame); | ||||||
|             assert(_PyFrame_GetBytecode(shim)[0].op.code == EXIT_INIT_CHECK); |             assert(_PyFrame_GetBytecode(shim)[0].op.code == EXIT_INIT_CHECK); | ||||||
|  | @ -4063,12 +4066,12 @@ dummy_func( | ||||||
|                 _PyEval_FrameClearAndPop(tstate, shim); |                 _PyEval_FrameClearAndPop(tstate, shim); | ||||||
|                 ERROR_NO_POP(); |                 ERROR_NO_POP(); | ||||||
|             } |             } | ||||||
|             init_frame = temp; |  | ||||||
|             frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; |             frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; | ||||||
|             /* Account for pushing the extra frame.
 |             /* Account for pushing the extra frame.
 | ||||||
|              * We don't check recursion depth here, |              * We don't check recursion depth here, | ||||||
|              * as it will be checked after start_frame */ |              * as it will be checked after start_frame */ | ||||||
|             tstate->py_recursion_remaining--; |             tstate->py_recursion_remaining--; | ||||||
|  |             init_frame = PyStackRef_Wrap(temp); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         macro(CALL_ALLOC_AND_ENTER_INIT) = |         macro(CALL_ALLOC_AND_ENTER_INIT) = | ||||||
|  | @ -4594,7 +4597,7 @@ dummy_func( | ||||||
|             res = PyStackRef_FromPyObjectSteal(res_o); |             res = PyStackRef_FromPyObjectSteal(res_o); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame: _PyInterpreterFrame*)) { |         op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) { | ||||||
|             PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); |             PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); | ||||||
| 
 | 
 | ||||||
|             // oparg counts all of the args, but *not* self:
 |             // oparg counts all of the args, but *not* self:
 | ||||||
|  | @ -4621,7 +4624,7 @@ dummy_func( | ||||||
|             DEAD(callable); |             DEAD(callable); | ||||||
|             SYNC_SP(); |             SYNC_SP(); | ||||||
|             ERROR_IF(temp == NULL); |             ERROR_IF(temp == NULL); | ||||||
|             new_frame = temp; |             new_frame = PyStackRef_Wrap(temp); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         op(_CHECK_FUNCTION_VERSION_KW, (func_version/2, callable, unused, unused[oparg], unused -- callable, unused, unused[oparg], unused)) { |         op(_CHECK_FUNCTION_VERSION_KW, (func_version/2, callable, unused, unused[oparg], unused -- callable, unused, unused[oparg], unused)) { | ||||||
|  |  | ||||||
							
								
								
									
										134
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										134
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -1551,15 +1551,16 @@ | ||||||
|             _PyStackRef getitem; |             _PyStackRef getitem; | ||||||
|             _PyStackRef sub; |             _PyStackRef sub; | ||||||
|             _PyStackRef container; |             _PyStackRef container; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             getitem = stack_pointer[-1]; |             getitem = stack_pointer[-1]; | ||||||
|             sub = stack_pointer[-2]; |             sub = stack_pointer[-2]; | ||||||
|             container = stack_pointer[-3]; |             container = stack_pointer[-3]; | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); |             _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||||
|             new_frame->localsplus[0] = container; |             pushed_frame->localsplus[0] = container; | ||||||
|             new_frame->localsplus[1] = sub; |             pushed_frame->localsplus[1] = sub; | ||||||
|             frame->return_offset = 6 ; |             frame->return_offset = 6 ; | ||||||
|             stack_pointer[-3].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-3] = new_frame; | ||||||
|             stack_pointer += -2; |             stack_pointer += -2; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -1907,7 +1908,7 @@ | ||||||
|         case _SEND_GEN_FRAME: { |         case _SEND_GEN_FRAME: { | ||||||
|             _PyStackRef v; |             _PyStackRef v; | ||||||
|             _PyStackRef receiver; |             _PyStackRef receiver; | ||||||
|             _PyInterpreterFrame *gen_frame; |             _PyStackRef gen_frame; | ||||||
|             oparg = CURRENT_OPARG(); |             oparg = CURRENT_OPARG(); | ||||||
|             v = stack_pointer[-1]; |             v = stack_pointer[-1]; | ||||||
|             receiver = stack_pointer[-2]; |             receiver = stack_pointer[-2]; | ||||||
|  | @ -1921,15 +1922,16 @@ | ||||||
|                 JUMP_TO_JUMP_TARGET(); |                 JUMP_TO_JUMP_TARGET(); | ||||||
|             } |             } | ||||||
|             STAT_INC(SEND, hit); |             STAT_INC(SEND, hit); | ||||||
|             gen_frame = &gen->gi_iframe; |             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); |             _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); | ||||||
|             gen->gi_frame_state = FRAME_EXECUTING; |             gen->gi_frame_state = FRAME_EXECUTING; | ||||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; |             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||||
|             tstate->exc_info = &gen->gi_exc_state; |             tstate->exc_info = &gen->gi_exc_state; | ||||||
|             assert( 2 + oparg <= UINT16_MAX); |             assert( 2 + oparg <= UINT16_MAX); | ||||||
|             frame->return_offset = (uint16_t)( 2 + oparg); |             frame->return_offset = (uint16_t)( 2 + oparg); | ||||||
|             gen_frame->previous = frame; |             pushed_frame->previous = frame; | ||||||
|             stack_pointer[-1].bits = (uintptr_t)gen_frame; |             gen_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-1] = gen_frame; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -3471,7 +3473,7 @@ | ||||||
| 
 | 
 | ||||||
|         case _LOAD_ATTR_PROPERTY_FRAME: { |         case _LOAD_ATTR_PROPERTY_FRAME: { | ||||||
|             _PyStackRef owner; |             _PyStackRef owner; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = CURRENT_OPARG(); |             oparg = CURRENT_OPARG(); | ||||||
|             owner = stack_pointer[-1]; |             owner = stack_pointer[-1]; | ||||||
|             PyObject *fget = (PyObject *)CURRENT_OPERAND0(); |             PyObject *fget = (PyObject *)CURRENT_OPERAND0(); | ||||||
|  | @ -3496,9 +3498,10 @@ | ||||||
|                 JUMP_TO_JUMP_TARGET(); |                 JUMP_TO_JUMP_TARGET(); | ||||||
|             } |             } | ||||||
|             STAT_INC(LOAD_ATTR, hit); |             STAT_INC(LOAD_ATTR, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||||
|             new_frame->localsplus[0] = owner; |             pushed_frame->localsplus[0] = owner; | ||||||
|             stack_pointer[-1].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-1] = new_frame; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -4467,7 +4470,7 @@ | ||||||
| 
 | 
 | ||||||
|         case _FOR_ITER_GEN_FRAME: { |         case _FOR_ITER_GEN_FRAME: { | ||||||
|             _PyStackRef iter; |             _PyStackRef iter; | ||||||
|             _PyInterpreterFrame *gen_frame; |             _PyStackRef gen_frame; | ||||||
|             oparg = CURRENT_OPARG(); |             oparg = CURRENT_OPARG(); | ||||||
|             iter = stack_pointer[-2]; |             iter = stack_pointer[-2]; | ||||||
|             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); |             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); | ||||||
|  | @ -4487,14 +4490,15 @@ | ||||||
|                 JUMP_TO_JUMP_TARGET(); |                 JUMP_TO_JUMP_TARGET(); | ||||||
|             } |             } | ||||||
|             STAT_INC(FOR_ITER, hit); |             STAT_INC(FOR_ITER, hit); | ||||||
|             gen_frame = &gen->gi_iframe; |             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_None); |             _PyFrame_StackPush(pushed_frame, PyStackRef_None); | ||||||
|             gen->gi_frame_state = FRAME_EXECUTING; |             gen->gi_frame_state = FRAME_EXECUTING; | ||||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; |             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||||
|             tstate->exc_info = &gen->gi_exc_state; |             tstate->exc_info = &gen->gi_exc_state; | ||||||
|             gen_frame->previous = frame; |             pushed_frame->previous = frame; | ||||||
|             frame->return_offset = (uint16_t)( 2 + oparg); |             frame->return_offset = (uint16_t)( 2 + oparg); | ||||||
|             stack_pointer[0].bits = (uintptr_t)gen_frame; |             gen_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[0] = gen_frame; | ||||||
|             stack_pointer += 1; |             stack_pointer += 1; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -4775,7 +4779,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = CURRENT_OPARG(); |             oparg = CURRENT_OPARG(); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|             self_or_null = stack_pointer[-1 - oparg]; |             self_or_null = stack_pointer[-1 - oparg]; | ||||||
|  | @ -4800,8 +4804,8 @@ | ||||||
|             if (temp == NULL) { |             if (temp == NULL) { | ||||||
|                 JUMP_TO_ERROR(); |                 JUMP_TO_ERROR(); | ||||||
|             } |             } | ||||||
|             new_frame = temp; |             new_frame = PyStackRef_Wrap(temp); | ||||||
|             stack_pointer[0].bits = (uintptr_t)new_frame; |             stack_pointer[0] = new_frame; | ||||||
|             stack_pointer += 1; |             stack_pointer += 1; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -5067,7 +5071,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = 0; |             oparg = 0; | ||||||
|             assert(oparg == CURRENT_OPARG()); |             assert(oparg == CURRENT_OPARG()); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|  | @ -5075,13 +5079,14 @@ | ||||||
|             callable = stack_pointer[-2 - oparg]; |             callable = stack_pointer[-2 - oparg]; | ||||||
|             int has_self = !PyStackRef_IsNull(self_or_null); |             int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|             new_frame->localsplus[0] = self_or_null; |             pushed_frame->localsplus[0] = self_or_null; | ||||||
|             for (int i = 0; i < oparg; i++) { |             for (int i = 0; i < oparg; i++) { | ||||||
|                 first_non_self_local[i] = args[i]; |                 first_non_self_local[i] = args[i]; | ||||||
|             } |             } | ||||||
|             stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -5091,7 +5096,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = 1; |             oparg = 1; | ||||||
|             assert(oparg == CURRENT_OPARG()); |             assert(oparg == CURRENT_OPARG()); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|  | @ -5099,13 +5104,14 @@ | ||||||
|             callable = stack_pointer[-2 - oparg]; |             callable = stack_pointer[-2 - oparg]; | ||||||
|             int has_self = !PyStackRef_IsNull(self_or_null); |             int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|             new_frame->localsplus[0] = self_or_null; |             pushed_frame->localsplus[0] = self_or_null; | ||||||
|             for (int i = 0; i < oparg; i++) { |             for (int i = 0; i < oparg; i++) { | ||||||
|                 first_non_self_local[i] = args[i]; |                 first_non_self_local[i] = args[i]; | ||||||
|             } |             } | ||||||
|             stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -5115,7 +5121,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = 2; |             oparg = 2; | ||||||
|             assert(oparg == CURRENT_OPARG()); |             assert(oparg == CURRENT_OPARG()); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|  | @ -5123,13 +5129,14 @@ | ||||||
|             callable = stack_pointer[-2 - oparg]; |             callable = stack_pointer[-2 - oparg]; | ||||||
|             int has_self = !PyStackRef_IsNull(self_or_null); |             int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|             new_frame->localsplus[0] = self_or_null; |             pushed_frame->localsplus[0] = self_or_null; | ||||||
|             for (int i = 0; i < oparg; i++) { |             for (int i = 0; i < oparg; i++) { | ||||||
|                 first_non_self_local[i] = args[i]; |                 first_non_self_local[i] = args[i]; | ||||||
|             } |             } | ||||||
|             stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -5139,7 +5146,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = 3; |             oparg = 3; | ||||||
|             assert(oparg == CURRENT_OPARG()); |             assert(oparg == CURRENT_OPARG()); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|  | @ -5147,13 +5154,14 @@ | ||||||
|             callable = stack_pointer[-2 - oparg]; |             callable = stack_pointer[-2 - oparg]; | ||||||
|             int has_self = !PyStackRef_IsNull(self_or_null); |             int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|             new_frame->localsplus[0] = self_or_null; |             pushed_frame->localsplus[0] = self_or_null; | ||||||
|             for (int i = 0; i < oparg; i++) { |             for (int i = 0; i < oparg; i++) { | ||||||
|                 first_non_self_local[i] = args[i]; |                 first_non_self_local[i] = args[i]; | ||||||
|             } |             } | ||||||
|             stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -5163,7 +5171,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = 4; |             oparg = 4; | ||||||
|             assert(oparg == CURRENT_OPARG()); |             assert(oparg == CURRENT_OPARG()); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|  | @ -5171,13 +5179,14 @@ | ||||||
|             callable = stack_pointer[-2 - oparg]; |             callable = stack_pointer[-2 - oparg]; | ||||||
|             int has_self = !PyStackRef_IsNull(self_or_null); |             int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|             new_frame->localsplus[0] = self_or_null; |             pushed_frame->localsplus[0] = self_or_null; | ||||||
|             for (int i = 0; i < oparg; i++) { |             for (int i = 0; i < oparg; i++) { | ||||||
|                 first_non_self_local[i] = args[i]; |                 first_non_self_local[i] = args[i]; | ||||||
|             } |             } | ||||||
|             stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -5187,34 +5196,35 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = CURRENT_OPARG(); |             oparg = CURRENT_OPARG(); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|             self_or_null = stack_pointer[-1 - oparg]; |             self_or_null = stack_pointer[-1 - oparg]; | ||||||
|             callable = stack_pointer[-2 - oparg]; |             callable = stack_pointer[-2 - oparg]; | ||||||
|             int has_self = !PyStackRef_IsNull(self_or_null); |             int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|             STAT_INC(CALL, hit); |             STAT_INC(CALL, hit); | ||||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|             new_frame->localsplus[0] = self_or_null; |             pushed_frame->localsplus[0] = self_or_null; | ||||||
|             for (int i = 0; i < oparg; i++) { |             for (int i = 0; i < oparg; i++) { | ||||||
|                 first_non_self_local[i] = args[i]; |                 first_non_self_local[i] = args[i]; | ||||||
|             } |             } | ||||||
|             stack_pointer[-2 - oparg].bits = (uintptr_t)new_frame; |             new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|  |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case _PUSH_FRAME: { |         case _PUSH_FRAME: { | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             new_frame = (_PyInterpreterFrame *)stack_pointer[-1].bits; |             new_frame = stack_pointer[-1]; | ||||||
|             assert(tstate->interp->eval_frame == NULL); |             assert(tstate->interp->eval_frame == NULL); | ||||||
|             _PyInterpreterFrame *temp = new_frame; |             _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|             stack_pointer += -1; |             stack_pointer += -1; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             _PyFrame_SetStackPointer(frame, stack_pointer); |             _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|             assert(new_frame->previous == frame || new_frame->previous->previous == frame); |             assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|             CALL_STAT_INC(inlined_py_calls); |             CALL_STAT_INC(inlined_py_calls); | ||||||
|             frame = tstate->current_frame = temp; |             frame = tstate->current_frame = temp; | ||||||
|             tstate->py_recursion_remaining--; |             tstate->py_recursion_remaining--; | ||||||
|  | @ -5429,7 +5439,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self; |             _PyStackRef self; | ||||||
|             _PyStackRef init; |             _PyStackRef init; | ||||||
|             _PyInterpreterFrame *init_frame; |             _PyStackRef init_frame; | ||||||
|             oparg = CURRENT_OPARG(); |             oparg = CURRENT_OPARG(); | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|             self = stack_pointer[-1 - oparg]; |             self = stack_pointer[-1 - oparg]; | ||||||
|  | @ -5453,10 +5463,10 @@ | ||||||
|                 stack_pointer = _PyFrame_GetStackPointer(frame); |                 stack_pointer = _PyFrame_GetStackPointer(frame); | ||||||
|                 JUMP_TO_ERROR(); |                 JUMP_TO_ERROR(); | ||||||
|             } |             } | ||||||
|             init_frame = temp; |  | ||||||
|             frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; |             frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; | ||||||
|             tstate->py_recursion_remaining--; |             tstate->py_recursion_remaining--; | ||||||
|             stack_pointer[0].bits = (uintptr_t)init_frame; |             init_frame = PyStackRef_Wrap(temp); | ||||||
|  |             stack_pointer[0] = init_frame; | ||||||
|             stack_pointer += 1; |             stack_pointer += 1; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -6309,7 +6319,7 @@ | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             oparg = CURRENT_OPARG(); |             oparg = CURRENT_OPARG(); | ||||||
|             kwnames = stack_pointer[-1]; |             kwnames = stack_pointer[-1]; | ||||||
|             args = &stack_pointer[-1 - oparg]; |             args = &stack_pointer[-1 - oparg]; | ||||||
|  | @ -6343,8 +6353,8 @@ | ||||||
|             if (temp == NULL) { |             if (temp == NULL) { | ||||||
|                 JUMP_TO_ERROR(); |                 JUMP_TO_ERROR(); | ||||||
|             } |             } | ||||||
|             new_frame = temp; |             new_frame = PyStackRef_Wrap(temp); | ||||||
|             stack_pointer[0].bits = (uintptr_t)new_frame; |             stack_pointer[0] = new_frame; | ||||||
|             stack_pointer += 1; |             stack_pointer += 1; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
							
								
								
									
										122
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										122
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -604,7 +604,7 @@ | ||||||
|             _PyStackRef container; |             _PyStackRef container; | ||||||
|             _PyStackRef getitem; |             _PyStackRef getitem; | ||||||
|             _PyStackRef sub; |             _PyStackRef sub; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 5 cache entries */ |             /* Skip 5 cache entries */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -650,19 +650,20 @@ | ||||||
|             // _BINARY_OP_SUBSCR_INIT_CALL
 |             // _BINARY_OP_SUBSCR_INIT_CALL
 | ||||||
|             { |             { | ||||||
|                 sub = stack_pointer[-1]; |                 sub = stack_pointer[-1]; | ||||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); |                 _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||||
|                 new_frame->localsplus[0] = container; |                 pushed_frame->localsplus[0] = container; | ||||||
|                 new_frame->localsplus[1] = sub; |                 pushed_frame->localsplus[1] = sub; | ||||||
|                 frame->return_offset = 6 ; |                 frame->return_offset = 6 ; | ||||||
|  |                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|             } |             } | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 stack_pointer += -2; |                 stack_pointer += -2; | ||||||
|                 assert(WITHIN_STACK_BOUNDS()); |                 assert(WITHIN_STACK_BOUNDS()); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -1708,8 +1709,8 @@ | ||||||
|             _PyStackRef init; |             _PyStackRef init; | ||||||
|             _PyStackRef self; |             _PyStackRef self; | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyInterpreterFrame *init_frame; |             _PyStackRef init_frame; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -1792,17 +1793,17 @@ | ||||||
|                     stack_pointer = _PyFrame_GetStackPointer(frame); |                     stack_pointer = _PyFrame_GetStackPointer(frame); | ||||||
|                     JUMP_TO_LABEL(error); |                     JUMP_TO_LABEL(error); | ||||||
|                 } |                 } | ||||||
|                 init_frame = temp; |  | ||||||
|                 frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; |                 frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  |                 init_frame = PyStackRef_Wrap(temp); | ||||||
|             } |             } | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 new_frame = init_frame; |                 new_frame = init_frame; | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -1828,7 +1829,7 @@ | ||||||
|             _PyStackRef null; |             _PyStackRef null; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -1921,12 +1922,13 @@ | ||||||
|                 args = &stack_pointer[-oparg]; |                 args = &stack_pointer[-oparg]; | ||||||
|                 int has_self = !PyStackRef_IsNull(self_or_null); |                 int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|                 STAT_INC(CALL, hit); |                 STAT_INC(CALL, hit); | ||||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |                 _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|                 _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |                 _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|                 new_frame->localsplus[0] = self_or_null; |                 pushed_frame->localsplus[0] = self_or_null; | ||||||
|                 for (int i = 0; i < oparg; i++) { |                 for (int i = 0; i < oparg; i++) { | ||||||
|                     first_non_self_local[i] = args[i]; |                     first_non_self_local[i] = args[i]; | ||||||
|                 } |                 } | ||||||
|  |                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|             } |             } | ||||||
|             // _SAVE_RETURN_OFFSET
 |             // _SAVE_RETURN_OFFSET
 | ||||||
|             { |             { | ||||||
|  | @ -1940,11 +1942,11 @@ | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 stack_pointer += -2 - oparg; |                 stack_pointer += -2 - oparg; | ||||||
|                 assert(WITHIN_STACK_BOUNDS()); |                 assert(WITHIN_STACK_BOUNDS()); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -1970,7 +1972,7 @@ | ||||||
|             _PyStackRef null; |             _PyStackRef null; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -2056,7 +2058,7 @@ | ||||||
|                 if (temp == NULL) { |                 if (temp == NULL) { | ||||||
|                     JUMP_TO_LABEL(error); |                     JUMP_TO_LABEL(error); | ||||||
|                 } |                 } | ||||||
|                 new_frame = temp; |                 new_frame = PyStackRef_Wrap(temp); | ||||||
|             } |             } | ||||||
|             // _SAVE_RETURN_OFFSET
 |             // _SAVE_RETURN_OFFSET
 | ||||||
|             { |             { | ||||||
|  | @ -2070,9 +2072,9 @@ | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -3040,7 +3042,7 @@ | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef kwnames; |             _PyStackRef kwnames; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -3127,7 +3129,7 @@ | ||||||
|                 if (temp == NULL) { |                 if (temp == NULL) { | ||||||
|                     JUMP_TO_LABEL(error); |                     JUMP_TO_LABEL(error); | ||||||
|                 } |                 } | ||||||
|                 new_frame = temp; |                 new_frame = PyStackRef_Wrap(temp); | ||||||
|             } |             } | ||||||
|             // _SAVE_RETURN_OFFSET
 |             // _SAVE_RETURN_OFFSET
 | ||||||
|             { |             { | ||||||
|  | @ -3141,9 +3143,9 @@ | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -3304,7 +3306,7 @@ | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyStackRef kwnames; |             _PyStackRef kwnames; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -3364,7 +3366,7 @@ | ||||||
|                 if (temp == NULL) { |                 if (temp == NULL) { | ||||||
|                     JUMP_TO_LABEL(error); |                     JUMP_TO_LABEL(error); | ||||||
|                 } |                 } | ||||||
|                 new_frame = temp; |                 new_frame = PyStackRef_Wrap(temp); | ||||||
|             } |             } | ||||||
|             // _SAVE_RETURN_OFFSET
 |             // _SAVE_RETURN_OFFSET
 | ||||||
|             { |             { | ||||||
|  | @ -3378,9 +3380,9 @@ | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -4163,7 +4165,7 @@ | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -4227,12 +4229,13 @@ | ||||||
|                 args = &stack_pointer[-oparg]; |                 args = &stack_pointer[-oparg]; | ||||||
|                 int has_self = !PyStackRef_IsNull(self_or_null); |                 int has_self = !PyStackRef_IsNull(self_or_null); | ||||||
|                 STAT_INC(CALL, hit); |                 STAT_INC(CALL, hit); | ||||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); |                 _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||||
|                 _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; |                 _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||||
|                 new_frame->localsplus[0] = self_or_null; |                 pushed_frame->localsplus[0] = self_or_null; | ||||||
|                 for (int i = 0; i < oparg; i++) { |                 for (int i = 0; i < oparg; i++) { | ||||||
|                     first_non_self_local[i] = args[i]; |                     first_non_self_local[i] = args[i]; | ||||||
|                 } |                 } | ||||||
|  |                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|             } |             } | ||||||
|             // _SAVE_RETURN_OFFSET
 |             // _SAVE_RETURN_OFFSET
 | ||||||
|             { |             { | ||||||
|  | @ -4246,11 +4249,11 @@ | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 stack_pointer += -2 - oparg; |                 stack_pointer += -2 - oparg; | ||||||
|                 assert(WITHIN_STACK_BOUNDS()); |                 assert(WITHIN_STACK_BOUNDS()); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -4275,7 +4278,7 @@ | ||||||
|             _PyStackRef callable; |             _PyStackRef callable; | ||||||
|             _PyStackRef self_or_null; |             _PyStackRef self_or_null; | ||||||
|             _PyStackRef *args; |             _PyStackRef *args; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -4334,7 +4337,7 @@ | ||||||
|                 if (temp == NULL) { |                 if (temp == NULL) { | ||||||
|                     JUMP_TO_LABEL(error); |                     JUMP_TO_LABEL(error); | ||||||
|                 } |                 } | ||||||
|                 new_frame = temp; |                 new_frame = PyStackRef_Wrap(temp); | ||||||
|             } |             } | ||||||
|             // _SAVE_RETURN_OFFSET
 |             // _SAVE_RETURN_OFFSET
 | ||||||
|             { |             { | ||||||
|  | @ -4348,9 +4351,9 @@ | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -5785,8 +5788,8 @@ | ||||||
|             INSTRUCTION_STATS(FOR_ITER_GEN); |             INSTRUCTION_STATS(FOR_ITER_GEN); | ||||||
|             static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); |             static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); | ||||||
|             _PyStackRef iter; |             _PyStackRef iter; | ||||||
|             _PyInterpreterFrame *gen_frame; |             _PyStackRef gen_frame; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -5818,21 +5821,22 @@ | ||||||
|                     JUMP_TO_PREDICTED(FOR_ITER); |                     JUMP_TO_PREDICTED(FOR_ITER); | ||||||
|                 } |                 } | ||||||
|                 STAT_INC(FOR_ITER, hit); |                 STAT_INC(FOR_ITER, hit); | ||||||
|                 gen_frame = &gen->gi_iframe; |                 _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||||
|                 _PyFrame_StackPush(gen_frame, PyStackRef_None); |                 _PyFrame_StackPush(pushed_frame, PyStackRef_None); | ||||||
|                 gen->gi_frame_state = FRAME_EXECUTING; |                 gen->gi_frame_state = FRAME_EXECUTING; | ||||||
|                 gen->gi_exc_state.previous_item = tstate->exc_info; |                 gen->gi_exc_state.previous_item = tstate->exc_info; | ||||||
|                 tstate->exc_info = &gen->gi_exc_state; |                 tstate->exc_info = &gen->gi_exc_state; | ||||||
|                 gen_frame->previous = frame; |                 pushed_frame->previous = frame; | ||||||
|                 frame->return_offset = (uint16_t)( 2 + oparg); |                 frame->return_offset = (uint16_t)( 2 + oparg); | ||||||
|  |                 gen_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|             } |             } | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 new_frame = gen_frame; |                 new_frame = gen_frame; | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -8650,7 +8654,7 @@ | ||||||
|             INSTRUCTION_STATS(LOAD_ATTR_PROPERTY); |             INSTRUCTION_STATS(LOAD_ATTR_PROPERTY); | ||||||
|             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); |             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); | ||||||
|             _PyStackRef owner; |             _PyStackRef owner; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -8701,8 +8705,9 @@ | ||||||
|                     JUMP_TO_PREDICTED(LOAD_ATTR); |                     JUMP_TO_PREDICTED(LOAD_ATTR); | ||||||
|                 } |                 } | ||||||
|                 STAT_INC(LOAD_ATTR, hit); |                 STAT_INC(LOAD_ATTR, hit); | ||||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); |                 _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||||
|                 new_frame->localsplus[0] = owner; |                 pushed_frame->localsplus[0] = owner; | ||||||
|  |                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|             } |             } | ||||||
|             // _SAVE_RETURN_OFFSET
 |             // _SAVE_RETURN_OFFSET
 | ||||||
|             { |             { | ||||||
|  | @ -8716,11 +8721,11 @@ | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 stack_pointer += -1; |                 stack_pointer += -1; | ||||||
|                 assert(WITHIN_STACK_BOUNDS()); |                 assert(WITHIN_STACK_BOUNDS()); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  | @ -10661,8 +10666,8 @@ | ||||||
|             static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); |             static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); | ||||||
|             _PyStackRef receiver; |             _PyStackRef receiver; | ||||||
|             _PyStackRef v; |             _PyStackRef v; | ||||||
|             _PyInterpreterFrame *gen_frame; |             _PyStackRef gen_frame; | ||||||
|             _PyInterpreterFrame *new_frame; |             _PyStackRef new_frame; | ||||||
|             /* Skip 1 cache entry */ |             /* Skip 1 cache entry */ | ||||||
|             // _CHECK_PEP_523
 |             // _CHECK_PEP_523
 | ||||||
|             { |             { | ||||||
|  | @ -10688,24 +10693,25 @@ | ||||||
|                     JUMP_TO_PREDICTED(SEND); |                     JUMP_TO_PREDICTED(SEND); | ||||||
|                 } |                 } | ||||||
|                 STAT_INC(SEND, hit); |                 STAT_INC(SEND, hit); | ||||||
|                 gen_frame = &gen->gi_iframe; |                 _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||||
|                 _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); |                 _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); | ||||||
|                 gen->gi_frame_state = FRAME_EXECUTING; |                 gen->gi_frame_state = FRAME_EXECUTING; | ||||||
|                 gen->gi_exc_state.previous_item = tstate->exc_info; |                 gen->gi_exc_state.previous_item = tstate->exc_info; | ||||||
|                 tstate->exc_info = &gen->gi_exc_state; |                 tstate->exc_info = &gen->gi_exc_state; | ||||||
|                 assert( 2 + oparg <= UINT16_MAX); |                 assert( 2 + oparg <= UINT16_MAX); | ||||||
|                 frame->return_offset = (uint16_t)( 2 + oparg); |                 frame->return_offset = (uint16_t)( 2 + oparg); | ||||||
|                 gen_frame->previous = frame; |                 pushed_frame->previous = frame; | ||||||
|  |                 gen_frame = PyStackRef_Wrap(pushed_frame); | ||||||
|             } |             } | ||||||
|             // _PUSH_FRAME
 |             // _PUSH_FRAME
 | ||||||
|             { |             { | ||||||
|                 new_frame = gen_frame; |                 new_frame = gen_frame; | ||||||
|                 assert(tstate->interp->eval_frame == NULL); |                 assert(tstate->interp->eval_frame == NULL); | ||||||
|                 _PyInterpreterFrame *temp = new_frame; |                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||||
|                 stack_pointer += -1; |                 stack_pointer += -1; | ||||||
|                 assert(WITHIN_STACK_BOUNDS()); |                 assert(WITHIN_STACK_BOUNDS()); | ||||||
|                 _PyFrame_SetStackPointer(frame, stack_pointer); |                 _PyFrame_SetStackPointer(frame, stack_pointer); | ||||||
|                 assert(new_frame->previous == frame || new_frame->previous->previous == frame); |                 assert(temp->previous == frame || temp->previous->previous == frame); | ||||||
|                 CALL_STAT_INC(inlined_py_calls); |                 CALL_STAT_INC(inlined_py_calls); | ||||||
|                 frame = tstate->current_frame = temp; |                 frame = tstate->current_frame = temp; | ||||||
|                 tstate->py_recursion_remaining--; |                 tstate->py_recursion_remaining--; | ||||||
|  |  | ||||||
|  | @ -373,7 +373,7 @@ dummy_func(void) { | ||||||
|         GETLOCAL(this_instr->operand0) = res; |         GETLOCAL(this_instr->operand0) = res; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem  -- new_frame: _Py_UOpsAbstractFrame *)) { |     op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem  -- new_frame)) { | ||||||
|         new_frame = NULL; |         new_frame = NULL; | ||||||
|         ctx->done = true; |         ctx->done = true; | ||||||
|     } |     } | ||||||
|  | @ -697,7 +697,7 @@ dummy_func(void) { | ||||||
|         self = owner; |         self = owner; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _Py_UOpsAbstractFrame *)) { |     op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame)) { | ||||||
|         (void)fget; |         (void)fget; | ||||||
|         new_frame = NULL; |         new_frame = NULL; | ||||||
|         ctx->done = true; |         ctx->done = true; | ||||||
|  | @ -735,7 +735,7 @@ dummy_func(void) { | ||||||
|         sym_set_type(callable, &PyMethod_Type); |         sym_set_type(callable, &PyMethod_Type); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) { |     op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame)) { | ||||||
|         int argcount = oparg; |         int argcount = oparg; | ||||||
| 
 | 
 | ||||||
|         PyCodeObject *co = NULL; |         PyCodeObject *co = NULL; | ||||||
|  | @ -756,10 +756,9 @@ dummy_func(void) { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { |         if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { | ||||||
|             new_frame = frame_new(ctx, co, 0, args, argcount); |             new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, args, argcount); | ||||||
|         } else { |         } else { | ||||||
|             new_frame = frame_new(ctx, co, 0, NULL, 0); |             new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0); | ||||||
| 
 |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -769,7 +768,7 @@ dummy_func(void) { | ||||||
|         self_or_null = sym_new_not_null(ctx); |         self_or_null = sym_new_not_null(ctx); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) { |     op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) { | ||||||
|         PyCodeObject *co = NULL; |         PyCodeObject *co = NULL; | ||||||
|         assert((this_instr + 2)->opcode == _PUSH_FRAME); |         assert((this_instr + 2)->opcode == _PUSH_FRAME); | ||||||
|         co = get_code_with_logging((this_instr + 2)); |         co = get_code_with_logging((this_instr + 2)); | ||||||
|  | @ -778,10 +777,10 @@ dummy_func(void) { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         new_frame = frame_new(ctx, co, 0, NULL, 0); |         new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame: _Py_UOpsAbstractFrame *)) { |     op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) { | ||||||
|         new_frame = NULL; |         new_frame = NULL; | ||||||
|         ctx->done = true; |         ctx->done = true; | ||||||
|     } |     } | ||||||
|  | @ -793,7 +792,7 @@ dummy_func(void) { | ||||||
|         self_or_null = sym_new_not_null(ctx); |         self_or_null = sym_new_not_null(ctx); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame: _Py_UOpsAbstractFrame *)) { |     op(_CREATE_INIT_FRAME, (init, self, args[oparg] -- init_frame)) { | ||||||
|         init_frame = NULL; |         init_frame = NULL; | ||||||
|         ctx->done = true; |         ctx->done = true; | ||||||
|     } |     } | ||||||
|  | @ -860,13 +859,13 @@ dummy_func(void) { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_FOR_ITER_GEN_FRAME, (unused, unused -- unused, unused, gen_frame: _Py_UOpsAbstractFrame*)) { |     op(_FOR_ITER_GEN_FRAME, (unused, unused -- unused, unused, gen_frame)) { | ||||||
|         gen_frame = NULL; |         gen_frame = NULL; | ||||||
|         /* We are about to hit the end of the trace */ |         /* We are about to hit the end of the trace */ | ||||||
|         ctx->done = true; |         ctx->done = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_SEND_GEN_FRAME, (unused, unused -- unused, gen_frame: _Py_UOpsAbstractFrame *)) { |     op(_SEND_GEN_FRAME, (unused, unused -- unused, gen_frame)) { | ||||||
|         gen_frame = NULL; |         gen_frame = NULL; | ||||||
|         // We are about to hit the end of the trace:
 |         // We are about to hit the end of the trace:
 | ||||||
|         ctx->done = true; |         ctx->done = true; | ||||||
|  | @ -884,12 +883,12 @@ dummy_func(void) { | ||||||
|         Py_UNREACHABLE(); |         Py_UNREACHABLE(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- )) { |     op(_PUSH_FRAME, (new_frame -- )) { | ||||||
|         SYNC_SP(); |         SYNC_SP(); | ||||||
|         ctx->frame->stack_pointer = stack_pointer; |         ctx->frame->stack_pointer = stack_pointer; | ||||||
|         ctx->frame = new_frame; |         ctx->frame = (_Py_UOpsAbstractFrame *)new_frame; | ||||||
|         ctx->curr_frame_depth++; |         ctx->curr_frame_depth++; | ||||||
|         stack_pointer = new_frame->stack_pointer; |         stack_pointer = ctx->frame->stack_pointer; | ||||||
|         co = get_code(this_instr); |         co = get_code(this_instr); | ||||||
|         if (co == NULL) { |         if (co == NULL) { | ||||||
|             // should be about to _EXIT_TRACE anyway
 |             // should be about to _EXIT_TRACE anyway
 | ||||||
|  |  | ||||||
							
								
								
									
										46
									
								
								Python/optimizer_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										46
									
								
								Python/optimizer_cases.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -715,10 +715,10 @@ | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case _BINARY_OP_SUBSCR_INIT_CALL: { |         case _BINARY_OP_SUBSCR_INIT_CALL: { | ||||||
|             _Py_UOpsAbstractFrame *new_frame; |             JitOptSymbol *new_frame; | ||||||
|             new_frame = NULL; |             new_frame = NULL; | ||||||
|             ctx->done = true; |             ctx->done = true; | ||||||
|             stack_pointer[-3] = (JitOptSymbol *)new_frame; |             stack_pointer[-3] = new_frame; | ||||||
|             stack_pointer += -2; |             stack_pointer += -2; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -829,10 +829,10 @@ | ||||||
|         /* _SEND is not a viable micro-op for tier 2 */ |         /* _SEND is not a viable micro-op for tier 2 */ | ||||||
| 
 | 
 | ||||||
|         case _SEND_GEN_FRAME: { |         case _SEND_GEN_FRAME: { | ||||||
|             _Py_UOpsAbstractFrame *gen_frame; |             JitOptSymbol *gen_frame; | ||||||
|             gen_frame = NULL; |             gen_frame = NULL; | ||||||
|             ctx->done = true; |             ctx->done = true; | ||||||
|             stack_pointer[-1] = (JitOptSymbol *)gen_frame; |             stack_pointer[-1] = gen_frame; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -1323,12 +1323,12 @@ | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case _LOAD_ATTR_PROPERTY_FRAME: { |         case _LOAD_ATTR_PROPERTY_FRAME: { | ||||||
|             _Py_UOpsAbstractFrame *new_frame; |             JitOptSymbol *new_frame; | ||||||
|             PyObject *fget = (PyObject *)this_instr->operand0; |             PyObject *fget = (PyObject *)this_instr->operand0; | ||||||
|             (void)fget; |             (void)fget; | ||||||
|             new_frame = NULL; |             new_frame = NULL; | ||||||
|             ctx->done = true; |             ctx->done = true; | ||||||
|             stack_pointer[-1] = (JitOptSymbol *)new_frame; |             stack_pointer[-1] = new_frame; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -1685,10 +1685,10 @@ | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case _FOR_ITER_GEN_FRAME: { |         case _FOR_ITER_GEN_FRAME: { | ||||||
|             _Py_UOpsAbstractFrame *gen_frame; |             JitOptSymbol *gen_frame; | ||||||
|             gen_frame = NULL; |             gen_frame = NULL; | ||||||
|             ctx->done = true; |             ctx->done = true; | ||||||
|             stack_pointer[0] = (JitOptSymbol *)gen_frame; |             stack_pointer[0] = gen_frame; | ||||||
|             stack_pointer += 1; |             stack_pointer += 1; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -1857,7 +1857,7 @@ | ||||||
|         /* _MONITOR_CALL is not a viable micro-op for tier 2 */ |         /* _MONITOR_CALL is not a viable micro-op for tier 2 */ | ||||||
| 
 | 
 | ||||||
|         case _PY_FRAME_GENERAL: { |         case _PY_FRAME_GENERAL: { | ||||||
|             _Py_UOpsAbstractFrame *new_frame; |             JitOptSymbol *new_frame; | ||||||
|             PyCodeObject *co = NULL; |             PyCodeObject *co = NULL; | ||||||
|             assert((this_instr + 2)->opcode == _PUSH_FRAME); |             assert((this_instr + 2)->opcode == _PUSH_FRAME); | ||||||
|             co = get_code_with_logging((this_instr + 2)); |             co = get_code_with_logging((this_instr + 2)); | ||||||
|  | @ -1865,8 +1865,8 @@ | ||||||
|                 ctx->done = true; |                 ctx->done = true; | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             new_frame = frame_new(ctx, co, 0, NULL, 0); |             new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0); | ||||||
|             stack_pointer[-2 - oparg] = (JitOptSymbol *)new_frame; |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -1970,7 +1970,7 @@ | ||||||
|         case _INIT_CALL_PY_EXACT_ARGS: { |         case _INIT_CALL_PY_EXACT_ARGS: { | ||||||
|             JitOptSymbol **args; |             JitOptSymbol **args; | ||||||
|             JitOptSymbol *self_or_null; |             JitOptSymbol *self_or_null; | ||||||
|             _Py_UOpsAbstractFrame *new_frame; |             JitOptSymbol *new_frame; | ||||||
|             args = &stack_pointer[-oparg]; |             args = &stack_pointer[-oparg]; | ||||||
|             self_or_null = stack_pointer[-1 - oparg]; |             self_or_null = stack_pointer[-1 - oparg]; | ||||||
|             int argcount = oparg; |             int argcount = oparg; | ||||||
|  | @ -1988,25 +1988,25 @@ | ||||||
|                 argcount++; |                 argcount++; | ||||||
|             } |             } | ||||||
|             if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { |             if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { | ||||||
|                 new_frame = frame_new(ctx, co, 0, args, argcount); |                 new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, args, argcount); | ||||||
|             } else { |             } else { | ||||||
|                 new_frame = frame_new(ctx, co, 0, NULL, 0); |                 new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0); | ||||||
|             } |             } | ||||||
|             stack_pointer[-2 - oparg] = (JitOptSymbol *)new_frame; |             stack_pointer[-2 - oparg] = new_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case _PUSH_FRAME: { |         case _PUSH_FRAME: { | ||||||
|             _Py_UOpsAbstractFrame *new_frame; |             JitOptSymbol *new_frame; | ||||||
|             new_frame = (_Py_UOpsAbstractFrame *)stack_pointer[-1]; |             new_frame = stack_pointer[-1]; | ||||||
|             stack_pointer += -1; |             stack_pointer += -1; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             ctx->frame->stack_pointer = stack_pointer; |             ctx->frame->stack_pointer = stack_pointer; | ||||||
|             ctx->frame = new_frame; |             ctx->frame = (_Py_UOpsAbstractFrame *)new_frame; | ||||||
|             ctx->curr_frame_depth++; |             ctx->curr_frame_depth++; | ||||||
|             stack_pointer = new_frame->stack_pointer; |             stack_pointer = ctx->frame->stack_pointer; | ||||||
|             co = get_code(this_instr); |             co = get_code(this_instr); | ||||||
|             if (co == NULL) { |             if (co == NULL) { | ||||||
|                 ctx->done = true; |                 ctx->done = true; | ||||||
|  | @ -2159,10 +2159,10 @@ | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         case _CREATE_INIT_FRAME: { |         case _CREATE_INIT_FRAME: { | ||||||
|             _Py_UOpsAbstractFrame *init_frame; |             JitOptSymbol *init_frame; | ||||||
|             init_frame = NULL; |             init_frame = NULL; | ||||||
|             ctx->done = true; |             ctx->done = true; | ||||||
|             stack_pointer[-2 - oparg] = (JitOptSymbol *)init_frame; |             stack_pointer[-2 - oparg] = init_frame; | ||||||
|             stack_pointer += -1 - oparg; |             stack_pointer += -1 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  | @ -2326,10 +2326,10 @@ | ||||||
|         /* _DO_CALL_KW is not a viable micro-op for tier 2 */ |         /* _DO_CALL_KW is not a viable micro-op for tier 2 */ | ||||||
| 
 | 
 | ||||||
|         case _PY_FRAME_KW: { |         case _PY_FRAME_KW: { | ||||||
|             _Py_UOpsAbstractFrame *new_frame; |             JitOptSymbol *new_frame; | ||||||
|             new_frame = NULL; |             new_frame = NULL; | ||||||
|             ctx->done = true; |             ctx->done = true; | ||||||
|             stack_pointer[-3 - oparg] = (JitOptSymbol *)new_frame; |             stack_pointer[-3 - oparg] = new_frame; | ||||||
|             stack_pointer += -2 - oparg; |             stack_pointer += -2 - oparg; | ||||||
|             assert(WITHIN_STACK_BOUNDS()); |             assert(WITHIN_STACK_BOUNDS()); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|  | @ -135,15 +135,13 @@ def size(self) -> int: | ||||||
| @dataclass | @dataclass | ||||||
| class StackItem: | class StackItem: | ||||||
|     name: str |     name: str | ||||||
|     type: str | None |  | ||||||
|     size: str |     size: str | ||||||
|     peek: bool = False |     peek: bool = False | ||||||
|     used: bool = False |     used: bool = False | ||||||
| 
 | 
 | ||||||
|     def __str__(self) -> str: |     def __str__(self) -> str: | ||||||
|         size = f"[{self.size}]" if self.size else "" |         size = f"[{self.size}]" if self.size else "" | ||||||
|         type = "" if self.type is None else f"{self.type} " |         return f"{self.name}{size} {self.peek}" | ||||||
|         return f"{type}{self.name}{size} {self.peek}" |  | ||||||
| 
 | 
 | ||||||
|     def is_array(self) -> bool: |     def is_array(self) -> bool: | ||||||
|         return self.size != "" |         return self.size != "" | ||||||
|  | @ -345,7 +343,7 @@ def override_error( | ||||||
| def convert_stack_item( | def convert_stack_item( | ||||||
|     item: parser.StackEffect, replace_op_arg_1: str | None |     item: parser.StackEffect, replace_op_arg_1: str | None | ||||||
| ) -> StackItem: | ) -> StackItem: | ||||||
|     return StackItem(item.name, item.type, item.size) |     return StackItem(item.name, item.size) | ||||||
| 
 | 
 | ||||||
| def check_unused(stack: list[StackItem], input_names: dict[str, lexer.Token]) -> None: | def check_unused(stack: list[StackItem], input_names: dict[str, lexer.Token]) -> None: | ||||||
|     "Unused items cannot be on the stack above used, non-peek items" |     "Unused items cannot be on the stack above used, non-peek items" | ||||||
|  | @ -683,6 +681,8 @@ def has_error_without_pop(op: parser.CodeDef) -> bool: | ||||||
|     "PyStackRef_IsNullOrInt", |     "PyStackRef_IsNullOrInt", | ||||||
|     "PyStackRef_IsError", |     "PyStackRef_IsError", | ||||||
|     "PyStackRef_IsValid", |     "PyStackRef_IsValid", | ||||||
|  |     "PyStackRef_Wrap", | ||||||
|  |     "PyStackRef_Unwrap", | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -811,7 +811,7 @@ def stack_effect_only_peeks(instr: parser.InstDef) -> bool: | ||||||
|     if len(stack_inputs) == 0: |     if len(stack_inputs) == 0: | ||||||
|         return False |         return False | ||||||
|     return all( |     return all( | ||||||
|         (s.name == other.name and s.type == other.type and s.size == other.size) |         (s.name == other.name and s.size == other.size) | ||||||
|         for s, other in zip(stack_inputs, instr.outputs) |         for s, other in zip(stack_inputs, instr.outputs) | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -56,9 +56,7 @@ def root_relative_path(filename: str) -> str: | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def type_and_null(var: StackItem) -> tuple[str, str]: | def type_and_null(var: StackItem) -> tuple[str, str]: | ||||||
|     if var.type: |     if var.is_array(): | ||||||
|         return var.type, "NULL" |  | ||||||
|     elif var.is_array(): |  | ||||||
|         return "_PyStackRef *", "NULL" |         return "_PyStackRef *", "NULL" | ||||||
|     else: |     else: | ||||||
|         return "_PyStackRef", "PyStackRef_NULL" |         return "_PyStackRef", "PyStackRef_NULL" | ||||||
|  |  | ||||||
|  | @ -73,8 +73,6 @@ def validate_uop(override: Uop, uop: Uop) -> None: | ||||||
| def type_name(var: StackItem) -> str: | def type_name(var: StackItem) -> str: | ||||||
|     if var.is_array(): |     if var.is_array(): | ||||||
|         return "JitOptSymbol **" |         return "JitOptSymbol **" | ||||||
|     if var.type: |  | ||||||
|         return var.type |  | ||||||
|     return "JitOptSymbol *" |     return "JitOptSymbol *" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -230,7 +228,7 @@ def generate_abstract_interpreter( | ||||||
|             declare_variables(override, out, skip_inputs=False) |             declare_variables(override, out, skip_inputs=False) | ||||||
|         else: |         else: | ||||||
|             declare_variables(uop, out, skip_inputs=True) |             declare_variables(uop, out, skip_inputs=True) | ||||||
|         stack = Stack(extract_bits=False, cast_type="JitOptSymbol *") |         stack = Stack() | ||||||
|         write_uop(override, uop, out, stack, debug, skip_inputs=(override is None)) |         write_uop(override, uop, out, stack, debug, skip_inputs=(override is None)) | ||||||
|         out.start_line() |         out.start_line() | ||||||
|         out.emit("break;\n") |         out.emit("break;\n") | ||||||
|  |  | ||||||
|  | @ -247,12 +247,11 @@ def accept(self, visitor: Visitor) -> None: | ||||||
| @dataclass | @dataclass | ||||||
| class StackEffect(Node): | class StackEffect(Node): | ||||||
|     name: str = field(compare=False)  # __eq__ only uses type, cond, size |     name: str = field(compare=False)  # __eq__ only uses type, cond, size | ||||||
|     type: str = ""  # Optional `:type` |  | ||||||
|     size: str = ""  # Optional `[size]` |     size: str = ""  # Optional `[size]` | ||||||
|     # Note: size cannot be combined with type or cond |     # Note: size cannot be combined with type or cond | ||||||
| 
 | 
 | ||||||
|     def __repr__(self) -> str: |     def __repr__(self) -> str: | ||||||
|         items = [self.name, self.type, self.size] |         items = [self.name, self.size] | ||||||
|         while items and items[-1] == "": |         while items and items[-1] == "": | ||||||
|             del items[-1] |             del items[-1] | ||||||
|         return f"StackEffect({', '.join(repr(item) for item in items)})" |         return f"StackEffect({', '.join(repr(item) for item in items)})" | ||||||
|  | @ -463,20 +462,13 @@ def stack_effect(self) -> StackEffect | None: | ||||||
|         # IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')'] |         # IDENTIFIER [':' IDENTIFIER [TIMES]] ['if' '(' expression ')'] | ||||||
|         # | IDENTIFIER '[' expression ']' |         # | IDENTIFIER '[' expression ']' | ||||||
|         if tkn := self.expect(lx.IDENTIFIER): |         if tkn := self.expect(lx.IDENTIFIER): | ||||||
|             type_text = "" |  | ||||||
|             if self.expect(lx.COLON): |  | ||||||
|                 type_text = self.require(lx.IDENTIFIER).text.strip() |  | ||||||
|                 if self.expect(lx.TIMES): |  | ||||||
|                     type_text += " *" |  | ||||||
|             size_text = "" |             size_text = "" | ||||||
|             if self.expect(lx.LBRACKET): |             if self.expect(lx.LBRACKET): | ||||||
|                 if type_text: |  | ||||||
|                     raise self.make_syntax_error("Unexpected [") |  | ||||||
|                 if not (size := self.expression()): |                 if not (size := self.expression()): | ||||||
|                     raise self.make_syntax_error("Expected expression") |                     raise self.make_syntax_error("Expected expression") | ||||||
|                 self.require(lx.RBRACKET) |                 self.require(lx.RBRACKET) | ||||||
|                 size_text = size.text.strip() |                 size_text = size.text.strip() | ||||||
|             return StackEffect(tkn.text, type_text, size_text) |             return StackEffect(tkn.text, size_text) | ||||||
|         return None |         return None | ||||||
| 
 | 
 | ||||||
|     @contextual |     @contextual | ||||||
|  |  | ||||||
|  | @ -168,7 +168,7 @@ def from_memory(defn: StackItem, offset: PointerOffset) -> "Local": | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def register(name: str) -> "Local": |     def register(name: str) -> "Local": | ||||||
|         item = StackItem(name, None, "", False, True) |         item = StackItem(name, "", False, True) | ||||||
|         return Local(item, None, True) |         return Local(item, None, True) | ||||||
| 
 | 
 | ||||||
|     def kill(self) -> None: |     def kill(self) -> None: | ||||||
|  | @ -216,13 +216,11 @@ def array_or_scalar(var: StackItem | Local) -> str: | ||||||
|     return "array" if var.is_array() else "scalar" |     return "array" if var.is_array() else "scalar" | ||||||
| 
 | 
 | ||||||
| class Stack: | class Stack: | ||||||
|     def __init__(self, extract_bits: bool=True, cast_type: str = "uintptr_t") -> None: |     def __init__(self) -> None: | ||||||
|         self.base_offset = PointerOffset.zero() |         self.base_offset = PointerOffset.zero() | ||||||
|         self.physical_sp = PointerOffset.zero() |         self.physical_sp = PointerOffset.zero() | ||||||
|         self.logical_sp = PointerOffset.zero() |         self.logical_sp = PointerOffset.zero() | ||||||
|         self.variables: list[Local] = [] |         self.variables: list[Local] = [] | ||||||
|         self.extract_bits = extract_bits |  | ||||||
|         self.cast_type = cast_type |  | ||||||
| 
 | 
 | ||||||
|     def drop(self, var: StackItem, check_liveness: bool) -> None: |     def drop(self, var: StackItem, check_liveness: bool) -> None: | ||||||
|         self.logical_sp = self.logical_sp.pop(var) |         self.logical_sp = self.logical_sp.pop(var) | ||||||
|  | @ -268,10 +266,8 @@ def pop(self, var: StackItem, out: CWriter) -> Local: | ||||||
|         self.base_offset = self.logical_sp |         self.base_offset = self.logical_sp | ||||||
|         if var.name in UNUSED or not var.used: |         if var.name in UNUSED or not var.used: | ||||||
|             return Local.unused(var, self.base_offset) |             return Local.unused(var, self.base_offset) | ||||||
|         cast = f"({var.type})" if (not indirect and var.type) else "" |  | ||||||
|         bits = ".bits" if cast and self.extract_bits else "" |  | ||||||
|         c_offset = (self.base_offset - self.physical_sp).to_c() |         c_offset = (self.base_offset - self.physical_sp).to_c() | ||||||
|         assign = f"{var.name} = {cast}{indirect}stack_pointer[{c_offset}]{bits};\n" |         assign = f"{var.name} = {indirect}stack_pointer[{c_offset}];\n" | ||||||
|         out.emit(assign) |         out.emit(assign) | ||||||
|         self._print(out) |         self._print(out) | ||||||
|         return Local.from_memory(var, self.base_offset) |         return Local.from_memory(var, self.base_offset) | ||||||
|  | @ -292,12 +288,8 @@ def _do_emit( | ||||||
|         out: CWriter, |         out: CWriter, | ||||||
|         var: StackItem, |         var: StackItem, | ||||||
|         stack_offset: PointerOffset, |         stack_offset: PointerOffset, | ||||||
|         cast_type: str, |  | ||||||
|         extract_bits: bool, |  | ||||||
|     ) -> None: |     ) -> None: | ||||||
|         cast = f"({cast_type})" if var.type else "" |         out.emit(f"stack_pointer[{stack_offset.to_c()}] = {var.name};\n") | ||||||
|         bits = ".bits" if cast and extract_bits else "" |  | ||||||
|         out.emit(f"stack_pointer[{stack_offset.to_c()}]{bits} = {cast}{var.name};\n") |  | ||||||
| 
 | 
 | ||||||
|     def _save_physical_sp(self, out: CWriter) -> None: |     def _save_physical_sp(self, out: CWriter) -> None: | ||||||
|         if self.physical_sp != self.logical_sp: |         if self.physical_sp != self.logical_sp: | ||||||
|  | @ -320,7 +312,7 @@ def save_variables(self, out: CWriter) -> None: | ||||||
|                 self._print(out) |                 self._print(out) | ||||||
|                 var.memory_offset = var_offset |                 var.memory_offset = var_offset | ||||||
|                 stack_offset = var_offset - self.physical_sp |                 stack_offset = var_offset - self.physical_sp | ||||||
|                 Stack._do_emit(out, var.item, stack_offset, self.cast_type, self.extract_bits) |                 Stack._do_emit(out, var.item, stack_offset) | ||||||
|                 self._print(out) |                 self._print(out) | ||||||
|             var_offset = var_offset.push(var.item) |             var_offset = var_offset.push(var.item) | ||||||
| 
 | 
 | ||||||
|  | @ -350,7 +342,7 @@ def _print(self, out: CWriter) -> None: | ||||||
|             out.emit(self.as_comment() + "\n") |             out.emit(self.as_comment() + "\n") | ||||||
| 
 | 
 | ||||||
|     def copy(self) -> "Stack": |     def copy(self) -> "Stack": | ||||||
|         other = Stack(self.extract_bits, self.cast_type) |         other = Stack() | ||||||
|         other.base_offset = self.base_offset |         other.base_offset = self.base_offset | ||||||
|         other.physical_sp = self.physical_sp |         other.physical_sp = self.physical_sp | ||||||
|         other.logical_sp = self.logical_sp |         other.logical_sp = self.logical_sp | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mark Shannon
						Mark Shannon