mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +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 }; | ||||
| 
 | ||||
| /* 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 | ||||
| PyStackRef_IsError(_PyStackRef ref) | ||||
| { | ||||
|  |  | |||
|  | @ -56,14 +56,14 @@ class TestEffects(unittest.TestCase): | |||
|     def test_effect_sizes(self): | ||||
|         stack = Stack() | ||||
|         inputs = [ | ||||
|             x := StackItem("x", None, "1"), | ||||
|             y := StackItem("y", None, "oparg"), | ||||
|             z := StackItem("z", None, "oparg*2"), | ||||
|             x := StackItem("x", "1"), | ||||
|             y := StackItem("y", "oparg"), | ||||
|             z := StackItem("z", "oparg*2"), | ||||
|         ] | ||||
|         outputs = [ | ||||
|             StackItem("x", None, "1"), | ||||
|             StackItem("b", None, "oparg*4"), | ||||
|             StackItem("c", None, "1"), | ||||
|             StackItem("x", "1"), | ||||
|             StackItem("b", "oparg*4"), | ||||
|             StackItem("c", "1"), | ||||
|         ] | ||||
|         null = CWriter.null() | ||||
|         stack.pop(z, null) | ||||
|  | @ -1103,32 +1103,6 @@ def test_array_of_one(self): | |||
|         """ | ||||
|         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): | ||||
|         input = """ | ||||
|         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); | ||||
|         } | ||||
| 
 | ||||
|         op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame: _PyInterpreterFrame* )) { | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||
|             new_frame->localsplus[0] = container; | ||||
|             new_frame->localsplus[1] = sub; | ||||
|         op(_BINARY_OP_SUBSCR_INIT_CALL, (container, sub, getitem -- new_frame)) { | ||||
|             _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||
|             pushed_frame->localsplus[0] = container; | ||||
|             pushed_frame->localsplus[1] = sub; | ||||
|             INPUTS_DEAD(); | ||||
|             frame->return_offset = INSTRUCTION_SIZE; | ||||
|             new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|         } | ||||
| 
 | ||||
|         macro(BINARY_OP_SUBSCR_GETITEM) = | ||||
|  | @ -1296,20 +1297,21 @@ dummy_func( | |||
| 
 | ||||
|         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); | ||||
|             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type); | ||||
|             DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); | ||||
|             STAT_INC(SEND, hit); | ||||
|             gen_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); | ||||
|             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); | ||||
|             DEAD(v); | ||||
|             gen->gi_frame_state = FRAME_EXECUTING; | ||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||
|             tstate->exc_info = &gen->gi_exc_state; | ||||
|             assert(INSTRUCTION_SIZE + oparg <= UINT16_MAX); | ||||
|             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) = | ||||
|  | @ -2463,7 +2465,7 @@ dummy_func( | |||
|             _LOAD_ATTR_CLASS + | ||||
|             _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(Py_IS_TYPE(fget, &PyFunction_Type)); | ||||
|             PyFunctionObject *f = (PyFunctionObject *)fget; | ||||
|  | @ -2473,9 +2475,10 @@ dummy_func( | |||
|             DEOPT_IF(code->co_argcount != 1); | ||||
|             DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); | ||||
|             STAT_INC(LOAD_ATTR, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||
|             new_frame->localsplus[0] = owner; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||
|             pushed_frame->localsplus[0] = owner; | ||||
|             DEAD(owner); | ||||
|             new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|         } | ||||
| 
 | ||||
|         macro(LOAD_ATTR_PROPERTY) = | ||||
|  | @ -3344,7 +3347,7 @@ dummy_func( | |||
|             _ITER_JUMP_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); | ||||
|             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type); | ||||
| #ifdef Py_GIL_DISABLED | ||||
|  | @ -3356,14 +3359,15 @@ dummy_func( | |||
| #endif | ||||
|             DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); | ||||
|             STAT_INC(FOR_ITER, hit); | ||||
|             gen_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_None); | ||||
|             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(pushed_frame, PyStackRef_None); | ||||
|             gen->gi_frame_state = FRAME_EXECUTING; | ||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||
|             tstate->exc_info = &gen->gi_exc_state; | ||||
|             gen_frame->previous = frame; | ||||
|             pushed_frame->previous = frame; | ||||
|             // oparg is the return offset from the next instruction.
 | ||||
|             frame->return_offset = (uint16_t)(INSTRUCTION_SIZE + oparg); | ||||
|             gen_frame = PyStackRef_Wrap(pushed_frame); | ||||
|         } | ||||
| 
 | ||||
|         macro(FOR_ITER_GEN) = | ||||
|  | @ -3715,7 +3719,7 @@ dummy_func( | |||
|         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; | ||||
| 
 | ||||
|         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); | ||||
| 
 | ||||
|             // oparg counts all of the args, but *not* self:
 | ||||
|  | @ -3737,7 +3741,7 @@ dummy_func( | |||
|             if (temp == NULL) { | ||||
|                 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])) { | ||||
|  | @ -3874,27 +3878,26 @@ dummy_func( | |||
|             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); | ||||
|             STAT_INC(CALL, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|             new_frame->localsplus[0] = self_or_null; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|             pushed_frame->localsplus[0] = self_or_null; | ||||
|             for (int i = 0; i < oparg; i++) { | ||||
|                 first_non_self_local[i] = args[i]; | ||||
|             } | ||||
|             INPUTS_DEAD(); | ||||
|             new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|         } | ||||
| 
 | ||||
|         op(_PUSH_FRAME, (new_frame: _PyInterpreterFrame* -- )) { | ||||
|             // Write it out explicitly because it's subtly different.
 | ||||
|             // Eventually this should be the only occurrence of this code.
 | ||||
|         op(_PUSH_FRAME, (new_frame -- )) { | ||||
|             assert(tstate->interp->eval_frame == NULL); | ||||
|             _PyInterpreterFrame *temp = new_frame; | ||||
|             _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|             DEAD(new_frame); | ||||
|             SYNC_SP(); | ||||
|             _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); | ||||
|             frame = tstate->current_frame = temp; | ||||
|             tstate->py_recursion_remaining--; | ||||
|  | @ -4046,7 +4049,7 @@ dummy_func( | |||
|             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( | ||||
|                 tstate, (PyCodeObject *)&_Py_InitCleanup, 1, frame); | ||||
|             assert(_PyFrame_GetBytecode(shim)[0].op.code == EXIT_INIT_CHECK); | ||||
|  | @ -4063,12 +4066,12 @@ dummy_func( | |||
|                 _PyEval_FrameClearAndPop(tstate, shim); | ||||
|                 ERROR_NO_POP(); | ||||
|             } | ||||
|             init_frame = temp; | ||||
|             frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; | ||||
|             /* Account for pushing the extra frame.
 | ||||
|              * We don't check recursion depth here, | ||||
|              * as it will be checked after start_frame */ | ||||
|             tstate->py_recursion_remaining--; | ||||
|             init_frame = PyStackRef_Wrap(temp); | ||||
|         } | ||||
| 
 | ||||
|         macro(CALL_ALLOC_AND_ENTER_INIT) = | ||||
|  | @ -4594,7 +4597,7 @@ dummy_func( | |||
|             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); | ||||
| 
 | ||||
|             // oparg counts all of the args, but *not* self:
 | ||||
|  | @ -4621,7 +4624,7 @@ dummy_func( | |||
|             DEAD(callable); | ||||
|             SYNC_SP(); | ||||
|             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)) { | ||||
|  |  | |||
							
								
								
									
										134
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										134
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -1551,15 +1551,16 @@ | |||
|             _PyStackRef getitem; | ||||
|             _PyStackRef sub; | ||||
|             _PyStackRef container; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             getitem = stack_pointer[-1]; | ||||
|             sub = stack_pointer[-2]; | ||||
|             container = stack_pointer[-3]; | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||
|             new_frame->localsplus[0] = container; | ||||
|             new_frame->localsplus[1] = sub; | ||||
|             _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||
|             pushed_frame->localsplus[0] = container; | ||||
|             pushed_frame->localsplus[1] = sub; | ||||
|             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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -1907,7 +1908,7 @@ | |||
|         case _SEND_GEN_FRAME: { | ||||
|             _PyStackRef v; | ||||
|             _PyStackRef receiver; | ||||
|             _PyInterpreterFrame *gen_frame; | ||||
|             _PyStackRef gen_frame; | ||||
|             oparg = CURRENT_OPARG(); | ||||
|             v = stack_pointer[-1]; | ||||
|             receiver = stack_pointer[-2]; | ||||
|  | @ -1921,15 +1922,16 @@ | |||
|                 JUMP_TO_JUMP_TARGET(); | ||||
|             } | ||||
|             STAT_INC(SEND, hit); | ||||
|             gen_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); | ||||
|             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); | ||||
|             gen->gi_frame_state = FRAME_EXECUTING; | ||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||
|             tstate->exc_info = &gen->gi_exc_state; | ||||
|             assert( 2 + oparg <= UINT16_MAX); | ||||
|             frame->return_offset = (uint16_t)( 2 + oparg); | ||||
|             gen_frame->previous = frame; | ||||
|             stack_pointer[-1].bits = (uintptr_t)gen_frame; | ||||
|             pushed_frame->previous = frame; | ||||
|             gen_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             stack_pointer[-1] = gen_frame; | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|  | @ -3471,7 +3473,7 @@ | |||
| 
 | ||||
|         case _LOAD_ATTR_PROPERTY_FRAME: { | ||||
|             _PyStackRef owner; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = CURRENT_OPARG(); | ||||
|             owner = stack_pointer[-1]; | ||||
|             PyObject *fget = (PyObject *)CURRENT_OPERAND0(); | ||||
|  | @ -3496,9 +3498,10 @@ | |||
|                 JUMP_TO_JUMP_TARGET(); | ||||
|             } | ||||
|             STAT_INC(LOAD_ATTR, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||
|             new_frame->localsplus[0] = owner; | ||||
|             stack_pointer[-1].bits = (uintptr_t)new_frame; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||
|             pushed_frame->localsplus[0] = owner; | ||||
|             new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             stack_pointer[-1] = new_frame; | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|  | @ -4467,7 +4470,7 @@ | |||
| 
 | ||||
|         case _FOR_ITER_GEN_FRAME: { | ||||
|             _PyStackRef iter; | ||||
|             _PyInterpreterFrame *gen_frame; | ||||
|             _PyStackRef gen_frame; | ||||
|             oparg = CURRENT_OPARG(); | ||||
|             iter = stack_pointer[-2]; | ||||
|             PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); | ||||
|  | @ -4487,14 +4490,15 @@ | |||
|                 JUMP_TO_JUMP_TARGET(); | ||||
|             } | ||||
|             STAT_INC(FOR_ITER, hit); | ||||
|             gen_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(gen_frame, PyStackRef_None); | ||||
|             _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||
|             _PyFrame_StackPush(pushed_frame, PyStackRef_None); | ||||
|             gen->gi_frame_state = FRAME_EXECUTING; | ||||
|             gen->gi_exc_state.previous_item = tstate->exc_info; | ||||
|             tstate->exc_info = &gen->gi_exc_state; | ||||
|             gen_frame->previous = frame; | ||||
|             pushed_frame->previous = frame; | ||||
|             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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -4775,7 +4779,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = CURRENT_OPARG(); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|             self_or_null = stack_pointer[-1 - oparg]; | ||||
|  | @ -4800,8 +4804,8 @@ | |||
|             if (temp == NULL) { | ||||
|                 JUMP_TO_ERROR(); | ||||
|             } | ||||
|             new_frame = temp; | ||||
|             stack_pointer[0].bits = (uintptr_t)new_frame; | ||||
|             new_frame = PyStackRef_Wrap(temp); | ||||
|             stack_pointer[0] = new_frame; | ||||
|             stack_pointer += 1; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -5067,7 +5071,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = 0; | ||||
|             assert(oparg == CURRENT_OPARG()); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|  | @ -5075,13 +5079,14 @@ | |||
|             callable = stack_pointer[-2 - oparg]; | ||||
|             int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|             STAT_INC(CALL, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|             new_frame->localsplus[0] = self_or_null; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|             pushed_frame->localsplus[0] = self_or_null; | ||||
|             for (int i = 0; i < oparg; 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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -5091,7 +5096,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = 1; | ||||
|             assert(oparg == CURRENT_OPARG()); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|  | @ -5099,13 +5104,14 @@ | |||
|             callable = stack_pointer[-2 - oparg]; | ||||
|             int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|             STAT_INC(CALL, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|             new_frame->localsplus[0] = self_or_null; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|             pushed_frame->localsplus[0] = self_or_null; | ||||
|             for (int i = 0; i < oparg; 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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -5115,7 +5121,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = 2; | ||||
|             assert(oparg == CURRENT_OPARG()); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|  | @ -5123,13 +5129,14 @@ | |||
|             callable = stack_pointer[-2 - oparg]; | ||||
|             int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|             STAT_INC(CALL, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|             new_frame->localsplus[0] = self_or_null; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|             pushed_frame->localsplus[0] = self_or_null; | ||||
|             for (int i = 0; i < oparg; 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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -5139,7 +5146,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = 3; | ||||
|             assert(oparg == CURRENT_OPARG()); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|  | @ -5147,13 +5154,14 @@ | |||
|             callable = stack_pointer[-2 - oparg]; | ||||
|             int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|             STAT_INC(CALL, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|             new_frame->localsplus[0] = self_or_null; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|             pushed_frame->localsplus[0] = self_or_null; | ||||
|             for (int i = 0; i < oparg; 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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -5163,7 +5171,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = 4; | ||||
|             assert(oparg == CURRENT_OPARG()); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|  | @ -5171,13 +5179,14 @@ | |||
|             callable = stack_pointer[-2 - oparg]; | ||||
|             int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|             STAT_INC(CALL, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|             new_frame->localsplus[0] = self_or_null; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|             pushed_frame->localsplus[0] = self_or_null; | ||||
|             for (int i = 0; i < oparg; 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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -5187,34 +5196,35 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = CURRENT_OPARG(); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|             self_or_null = stack_pointer[-1 - oparg]; | ||||
|             callable = stack_pointer[-2 - oparg]; | ||||
|             int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|             STAT_INC(CALL, hit); | ||||
|             new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|             new_frame->localsplus[0] = self_or_null; | ||||
|             _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|             _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|             pushed_frame->localsplus[0] = self_or_null; | ||||
|             for (int i = 0; i < oparg; 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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case _PUSH_FRAME: { | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             new_frame = (_PyInterpreterFrame *)stack_pointer[-1].bits; | ||||
|             _PyStackRef new_frame; | ||||
|             new_frame = stack_pointer[-1]; | ||||
|             assert(tstate->interp->eval_frame == NULL); | ||||
|             _PyInterpreterFrame *temp = new_frame; | ||||
|             _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|             stack_pointer += -1; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             _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); | ||||
|             frame = tstate->current_frame = temp; | ||||
|             tstate->py_recursion_remaining--; | ||||
|  | @ -5429,7 +5439,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self; | ||||
|             _PyStackRef init; | ||||
|             _PyInterpreterFrame *init_frame; | ||||
|             _PyStackRef init_frame; | ||||
|             oparg = CURRENT_OPARG(); | ||||
|             args = &stack_pointer[-oparg]; | ||||
|             self = stack_pointer[-1 - oparg]; | ||||
|  | @ -5453,10 +5463,10 @@ | |||
|                 stack_pointer = _PyFrame_GetStackPointer(frame); | ||||
|                 JUMP_TO_ERROR(); | ||||
|             } | ||||
|             init_frame = temp; | ||||
|             frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; | ||||
|             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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -6309,7 +6319,7 @@ | |||
|             _PyStackRef *args; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef callable; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             oparg = CURRENT_OPARG(); | ||||
|             kwnames = stack_pointer[-1]; | ||||
|             args = &stack_pointer[-1 - oparg]; | ||||
|  | @ -6343,8 +6353,8 @@ | |||
|             if (temp == NULL) { | ||||
|                 JUMP_TO_ERROR(); | ||||
|             } | ||||
|             new_frame = temp; | ||||
|             stack_pointer[0].bits = (uintptr_t)new_frame; | ||||
|             new_frame = PyStackRef_Wrap(temp); | ||||
|             stack_pointer[0] = new_frame; | ||||
|             stack_pointer += 1; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  |  | |||
							
								
								
									
										122
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										122
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							|  | @ -604,7 +604,7 @@ | |||
|             _PyStackRef container; | ||||
|             _PyStackRef getitem; | ||||
|             _PyStackRef sub; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 5 cache entries */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -650,19 +650,20 @@ | |||
|             // _BINARY_OP_SUBSCR_INIT_CALL
 | ||||
|             { | ||||
|                 sub = stack_pointer[-1]; | ||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||
|                 new_frame->localsplus[0] = container; | ||||
|                 new_frame->localsplus[1] = sub; | ||||
|                 _PyInterpreterFrame* pushed_frame = _PyFrame_PushUnchecked(tstate, getitem, 2, frame); | ||||
|                 pushed_frame->localsplus[0] = container; | ||||
|                 pushed_frame->localsplus[1] = sub; | ||||
|                 frame->return_offset = 6 ; | ||||
|                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             } | ||||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 stack_pointer += -2; | ||||
|                 assert(WITHIN_STACK_BOUNDS()); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -1708,8 +1709,8 @@ | |||
|             _PyStackRef init; | ||||
|             _PyStackRef self; | ||||
|             _PyStackRef *args; | ||||
|             _PyInterpreterFrame *init_frame; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef init_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -1792,17 +1793,17 @@ | |||
|                     stack_pointer = _PyFrame_GetStackPointer(frame); | ||||
|                     JUMP_TO_LABEL(error); | ||||
|                 } | ||||
|                 init_frame = temp; | ||||
|                 frame->return_offset = 1 + INLINE_CACHE_ENTRIES_CALL; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|                 init_frame = PyStackRef_Wrap(temp); | ||||
|             } | ||||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 new_frame = init_frame; | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -1828,7 +1829,7 @@ | |||
|             _PyStackRef null; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef *args; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -1921,12 +1922,13 @@ | |||
|                 args = &stack_pointer[-oparg]; | ||||
|                 int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|                 STAT_INC(CALL, hit); | ||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|                 _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|                 new_frame->localsplus[0] = self_or_null; | ||||
|                 _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|                 _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|                 pushed_frame->localsplus[0] = self_or_null; | ||||
|                 for (int i = 0; i < oparg; i++) { | ||||
|                     first_non_self_local[i] = args[i]; | ||||
|                 } | ||||
|                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             } | ||||
|             // _SAVE_RETURN_OFFSET
 | ||||
|             { | ||||
|  | @ -1940,11 +1942,11 @@ | |||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 stack_pointer += -2 - oparg; | ||||
|                 assert(WITHIN_STACK_BOUNDS()); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -1970,7 +1972,7 @@ | |||
|             _PyStackRef null; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef *args; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -2056,7 +2058,7 @@ | |||
|                 if (temp == NULL) { | ||||
|                     JUMP_TO_LABEL(error); | ||||
|                 } | ||||
|                 new_frame = temp; | ||||
|                 new_frame = PyStackRef_Wrap(temp); | ||||
|             } | ||||
|             // _SAVE_RETURN_OFFSET
 | ||||
|             { | ||||
|  | @ -2070,9 +2072,9 @@ | |||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -3040,7 +3042,7 @@ | |||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef *args; | ||||
|             _PyStackRef kwnames; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -3127,7 +3129,7 @@ | |||
|                 if (temp == NULL) { | ||||
|                     JUMP_TO_LABEL(error); | ||||
|                 } | ||||
|                 new_frame = temp; | ||||
|                 new_frame = PyStackRef_Wrap(temp); | ||||
|             } | ||||
|             // _SAVE_RETURN_OFFSET
 | ||||
|             { | ||||
|  | @ -3141,9 +3143,9 @@ | |||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -3304,7 +3306,7 @@ | |||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef *args; | ||||
|             _PyStackRef kwnames; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -3364,7 +3366,7 @@ | |||
|                 if (temp == NULL) { | ||||
|                     JUMP_TO_LABEL(error); | ||||
|                 } | ||||
|                 new_frame = temp; | ||||
|                 new_frame = PyStackRef_Wrap(temp); | ||||
|             } | ||||
|             // _SAVE_RETURN_OFFSET
 | ||||
|             { | ||||
|  | @ -3378,9 +3380,9 @@ | |||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -4163,7 +4165,7 @@ | |||
|             _PyStackRef callable; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef *args; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -4227,12 +4229,13 @@ | |||
|                 args = &stack_pointer[-oparg]; | ||||
|                 int has_self = !PyStackRef_IsNull(self_or_null); | ||||
|                 STAT_INC(CALL, hit); | ||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|                 _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; | ||||
|                 new_frame->localsplus[0] = self_or_null; | ||||
|                 _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, callable, oparg + has_self, frame); | ||||
|                 _PyStackRef *first_non_self_local = pushed_frame->localsplus + has_self; | ||||
|                 pushed_frame->localsplus[0] = self_or_null; | ||||
|                 for (int i = 0; i < oparg; i++) { | ||||
|                     first_non_self_local[i] = args[i]; | ||||
|                 } | ||||
|                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             } | ||||
|             // _SAVE_RETURN_OFFSET
 | ||||
|             { | ||||
|  | @ -4246,11 +4249,11 @@ | |||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 stack_pointer += -2 - oparg; | ||||
|                 assert(WITHIN_STACK_BOUNDS()); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -4275,7 +4278,7 @@ | |||
|             _PyStackRef callable; | ||||
|             _PyStackRef self_or_null; | ||||
|             _PyStackRef *args; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -4334,7 +4337,7 @@ | |||
|                 if (temp == NULL) { | ||||
|                     JUMP_TO_LABEL(error); | ||||
|                 } | ||||
|                 new_frame = temp; | ||||
|                 new_frame = PyStackRef_Wrap(temp); | ||||
|             } | ||||
|             // _SAVE_RETURN_OFFSET
 | ||||
|             { | ||||
|  | @ -4348,9 +4351,9 @@ | |||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -5785,8 +5788,8 @@ | |||
|             INSTRUCTION_STATS(FOR_ITER_GEN); | ||||
|             static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); | ||||
|             _PyStackRef iter; | ||||
|             _PyInterpreterFrame *gen_frame; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef gen_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -5818,21 +5821,22 @@ | |||
|                     JUMP_TO_PREDICTED(FOR_ITER); | ||||
|                 } | ||||
|                 STAT_INC(FOR_ITER, hit); | ||||
|                 gen_frame = &gen->gi_iframe; | ||||
|                 _PyFrame_StackPush(gen_frame, PyStackRef_None); | ||||
|                 _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||
|                 _PyFrame_StackPush(pushed_frame, PyStackRef_None); | ||||
|                 gen->gi_frame_state = FRAME_EXECUTING; | ||||
|                 gen->gi_exc_state.previous_item = tstate->exc_info; | ||||
|                 tstate->exc_info = &gen->gi_exc_state; | ||||
|                 gen_frame->previous = frame; | ||||
|                 pushed_frame->previous = frame; | ||||
|                 frame->return_offset = (uint16_t)( 2 + oparg); | ||||
|                 gen_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             } | ||||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 new_frame = gen_frame; | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -8650,7 +8654,7 @@ | |||
|             INSTRUCTION_STATS(LOAD_ATTR_PROPERTY); | ||||
|             static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); | ||||
|             _PyStackRef owner; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -8701,8 +8705,9 @@ | |||
|                     JUMP_TO_PREDICTED(LOAD_ATTR); | ||||
|                 } | ||||
|                 STAT_INC(LOAD_ATTR, hit); | ||||
|                 new_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||
|                 new_frame->localsplus[0] = owner; | ||||
|                 _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); | ||||
|                 pushed_frame->localsplus[0] = owner; | ||||
|                 new_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             } | ||||
|             // _SAVE_RETURN_OFFSET
 | ||||
|             { | ||||
|  | @ -8716,11 +8721,11 @@ | |||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 stack_pointer += -1; | ||||
|                 assert(WITHIN_STACK_BOUNDS()); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  | @ -10661,8 +10666,8 @@ | |||
|             static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); | ||||
|             _PyStackRef receiver; | ||||
|             _PyStackRef v; | ||||
|             _PyInterpreterFrame *gen_frame; | ||||
|             _PyInterpreterFrame *new_frame; | ||||
|             _PyStackRef gen_frame; | ||||
|             _PyStackRef new_frame; | ||||
|             /* Skip 1 cache entry */ | ||||
|             // _CHECK_PEP_523
 | ||||
|             { | ||||
|  | @ -10688,24 +10693,25 @@ | |||
|                     JUMP_TO_PREDICTED(SEND); | ||||
|                 } | ||||
|                 STAT_INC(SEND, hit); | ||||
|                 gen_frame = &gen->gi_iframe; | ||||
|                 _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); | ||||
|                 _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; | ||||
|                 _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); | ||||
|                 gen->gi_frame_state = FRAME_EXECUTING; | ||||
|                 gen->gi_exc_state.previous_item = tstate->exc_info; | ||||
|                 tstate->exc_info = &gen->gi_exc_state; | ||||
|                 assert( 2 + oparg <= UINT16_MAX); | ||||
|                 frame->return_offset = (uint16_t)( 2 + oparg); | ||||
|                 gen_frame->previous = frame; | ||||
|                 pushed_frame->previous = frame; | ||||
|                 gen_frame = PyStackRef_Wrap(pushed_frame); | ||||
|             } | ||||
|             // _PUSH_FRAME
 | ||||
|             { | ||||
|                 new_frame = gen_frame; | ||||
|                 assert(tstate->interp->eval_frame == NULL); | ||||
|                 _PyInterpreterFrame *temp = new_frame; | ||||
|                 _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); | ||||
|                 stack_pointer += -1; | ||||
|                 assert(WITHIN_STACK_BOUNDS()); | ||||
|                 _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); | ||||
|                 frame = tstate->current_frame = temp; | ||||
|                 tstate->py_recursion_remaining--; | ||||
|  |  | |||
|  | @ -373,7 +373,7 @@ dummy_func(void) { | |||
|         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; | ||||
|         ctx->done = true; | ||||
|     } | ||||
|  | @ -697,7 +697,7 @@ dummy_func(void) { | |||
|         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; | ||||
|         new_frame = NULL; | ||||
|         ctx->done = true; | ||||
|  | @ -735,7 +735,7 @@ dummy_func(void) { | |||
|         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; | ||||
| 
 | ||||
|         PyCodeObject *co = NULL; | ||||
|  | @ -756,10 +756,9 @@ dummy_func(void) { | |||
|         } | ||||
| 
 | ||||
|         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 { | ||||
|             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); | ||||
|     } | ||||
| 
 | ||||
|     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; | ||||
|         assert((this_instr + 2)->opcode == _PUSH_FRAME); | ||||
|         co = get_code_with_logging((this_instr + 2)); | ||||
|  | @ -778,10 +777,10 @@ dummy_func(void) { | |||
|             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; | ||||
|         ctx->done = true; | ||||
|     } | ||||
|  | @ -793,7 +792,7 @@ dummy_func(void) { | |||
|         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; | ||||
|         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; | ||||
|         /* We are about to hit the end of the trace */ | ||||
|         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; | ||||
|         // We are about to hit the end of the trace:
 | ||||
|         ctx->done = true; | ||||
|  | @ -884,12 +883,12 @@ dummy_func(void) { | |||
|         Py_UNREACHABLE(); | ||||
|     } | ||||
| 
 | ||||
|     op(_PUSH_FRAME, (new_frame: _Py_UOpsAbstractFrame * -- )) { | ||||
|     op(_PUSH_FRAME, (new_frame -- )) { | ||||
|         SYNC_SP(); | ||||
|         ctx->frame->stack_pointer = stack_pointer; | ||||
|         ctx->frame = new_frame; | ||||
|         ctx->frame = (_Py_UOpsAbstractFrame *)new_frame; | ||||
|         ctx->curr_frame_depth++; | ||||
|         stack_pointer = new_frame->stack_pointer; | ||||
|         stack_pointer = ctx->frame->stack_pointer; | ||||
|         co = get_code(this_instr); | ||||
|         if (co == NULL) { | ||||
|             // 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: { | ||||
|             _Py_UOpsAbstractFrame *new_frame; | ||||
|             JitOptSymbol *new_frame; | ||||
|             new_frame = NULL; | ||||
|             ctx->done = true; | ||||
|             stack_pointer[-3] = (JitOptSymbol *)new_frame; | ||||
|             stack_pointer[-3] = new_frame; | ||||
|             stack_pointer += -2; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -829,10 +829,10 @@ | |||
|         /* _SEND is not a viable micro-op for tier 2 */ | ||||
| 
 | ||||
|         case _SEND_GEN_FRAME: { | ||||
|             _Py_UOpsAbstractFrame *gen_frame; | ||||
|             JitOptSymbol *gen_frame; | ||||
|             gen_frame = NULL; | ||||
|             ctx->done = true; | ||||
|             stack_pointer[-1] = (JitOptSymbol *)gen_frame; | ||||
|             stack_pointer[-1] = gen_frame; | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|  | @ -1323,12 +1323,12 @@ | |||
|         } | ||||
| 
 | ||||
|         case _LOAD_ATTR_PROPERTY_FRAME: { | ||||
|             _Py_UOpsAbstractFrame *new_frame; | ||||
|             JitOptSymbol *new_frame; | ||||
|             PyObject *fget = (PyObject *)this_instr->operand0; | ||||
|             (void)fget; | ||||
|             new_frame = NULL; | ||||
|             ctx->done = true; | ||||
|             stack_pointer[-1] = (JitOptSymbol *)new_frame; | ||||
|             stack_pointer[-1] = new_frame; | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|  | @ -1685,10 +1685,10 @@ | |||
|         } | ||||
| 
 | ||||
|         case _FOR_ITER_GEN_FRAME: { | ||||
|             _Py_UOpsAbstractFrame *gen_frame; | ||||
|             JitOptSymbol *gen_frame; | ||||
|             gen_frame = NULL; | ||||
|             ctx->done = true; | ||||
|             stack_pointer[0] = (JitOptSymbol *)gen_frame; | ||||
|             stack_pointer[0] = gen_frame; | ||||
|             stack_pointer += 1; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -1857,7 +1857,7 @@ | |||
|         /* _MONITOR_CALL is not a viable micro-op for tier 2 */ | ||||
| 
 | ||||
|         case _PY_FRAME_GENERAL: { | ||||
|             _Py_UOpsAbstractFrame *new_frame; | ||||
|             JitOptSymbol *new_frame; | ||||
|             PyCodeObject *co = NULL; | ||||
|             assert((this_instr + 2)->opcode == _PUSH_FRAME); | ||||
|             co = get_code_with_logging((this_instr + 2)); | ||||
|  | @ -1865,8 +1865,8 @@ | |||
|                 ctx->done = true; | ||||
|                 break; | ||||
|             } | ||||
|             new_frame = frame_new(ctx, co, 0, NULL, 0); | ||||
|             stack_pointer[-2 - oparg] = (JitOptSymbol *)new_frame; | ||||
|             new_frame = (JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0); | ||||
|             stack_pointer[-2 - oparg] = new_frame; | ||||
|             stack_pointer += -1 - oparg; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -1970,7 +1970,7 @@ | |||
|         case _INIT_CALL_PY_EXACT_ARGS: { | ||||
|             JitOptSymbol **args; | ||||
|             JitOptSymbol *self_or_null; | ||||
|             _Py_UOpsAbstractFrame *new_frame; | ||||
|             JitOptSymbol *new_frame; | ||||
|             args = &stack_pointer[-oparg]; | ||||
|             self_or_null = stack_pointer[-1 - oparg]; | ||||
|             int argcount = oparg; | ||||
|  | @ -1988,25 +1988,25 @@ | |||
|                 argcount++; | ||||
|             } | ||||
|             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 { | ||||
|                 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; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case _PUSH_FRAME: { | ||||
|             _Py_UOpsAbstractFrame *new_frame; | ||||
|             new_frame = (_Py_UOpsAbstractFrame *)stack_pointer[-1]; | ||||
|             JitOptSymbol *new_frame; | ||||
|             new_frame = stack_pointer[-1]; | ||||
|             stack_pointer += -1; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             ctx->frame->stack_pointer = stack_pointer; | ||||
|             ctx->frame = new_frame; | ||||
|             ctx->frame = (_Py_UOpsAbstractFrame *)new_frame; | ||||
|             ctx->curr_frame_depth++; | ||||
|             stack_pointer = new_frame->stack_pointer; | ||||
|             stack_pointer = ctx->frame->stack_pointer; | ||||
|             co = get_code(this_instr); | ||||
|             if (co == NULL) { | ||||
|                 ctx->done = true; | ||||
|  | @ -2159,10 +2159,10 @@ | |||
|         } | ||||
| 
 | ||||
|         case _CREATE_INIT_FRAME: { | ||||
|             _Py_UOpsAbstractFrame *init_frame; | ||||
|             JitOptSymbol *init_frame; | ||||
|             init_frame = NULL; | ||||
|             ctx->done = true; | ||||
|             stack_pointer[-2 - oparg] = (JitOptSymbol *)init_frame; | ||||
|             stack_pointer[-2 - oparg] = init_frame; | ||||
|             stack_pointer += -1 - oparg; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  | @ -2326,10 +2326,10 @@ | |||
|         /* _DO_CALL_KW is not a viable micro-op for tier 2 */ | ||||
| 
 | ||||
|         case _PY_FRAME_KW: { | ||||
|             _Py_UOpsAbstractFrame *new_frame; | ||||
|             JitOptSymbol *new_frame; | ||||
|             new_frame = NULL; | ||||
|             ctx->done = true; | ||||
|             stack_pointer[-3 - oparg] = (JitOptSymbol *)new_frame; | ||||
|             stack_pointer[-3 - oparg] = new_frame; | ||||
|             stack_pointer += -2 - oparg; | ||||
|             assert(WITHIN_STACK_BOUNDS()); | ||||
|             break; | ||||
|  |  | |||
|  | @ -135,15 +135,13 @@ def size(self) -> int: | |||
| @dataclass | ||||
| class StackItem: | ||||
|     name: str | ||||
|     type: str | None | ||||
|     size: str | ||||
|     peek: bool = False | ||||
|     used: bool = False | ||||
| 
 | ||||
|     def __str__(self) -> str: | ||||
|         size = f"[{self.size}]" if self.size else "" | ||||
|         type = "" if self.type is None else f"{self.type} " | ||||
|         return f"{type}{self.name}{size} {self.peek}" | ||||
|         return f"{self.name}{size} {self.peek}" | ||||
| 
 | ||||
|     def is_array(self) -> bool: | ||||
|         return self.size != "" | ||||
|  | @ -345,7 +343,7 @@ def override_error( | |||
| def convert_stack_item( | ||||
|     item: parser.StackEffect, replace_op_arg_1: str | None | ||||
| ) -> 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: | ||||
|     "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_IsError", | ||||
|     "PyStackRef_IsValid", | ||||
|     "PyStackRef_Wrap", | ||||
|     "PyStackRef_Unwrap", | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -811,7 +811,7 @@ def stack_effect_only_peeks(instr: parser.InstDef) -> bool: | |||
|     if len(stack_inputs) == 0: | ||||
|         return False | ||||
|     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) | ||||
|     ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -56,9 +56,7 @@ def root_relative_path(filename: str) -> str: | |||
| 
 | ||||
| 
 | ||||
| def type_and_null(var: StackItem) -> tuple[str, str]: | ||||
|     if var.type: | ||||
|         return var.type, "NULL" | ||||
|     elif var.is_array(): | ||||
|     if var.is_array(): | ||||
|         return "_PyStackRef *", "NULL" | ||||
|     else: | ||||
|         return "_PyStackRef", "PyStackRef_NULL" | ||||
|  |  | |||
|  | @ -73,8 +73,6 @@ def validate_uop(override: Uop, uop: Uop) -> None: | |||
| def type_name(var: StackItem) -> str: | ||||
|     if var.is_array(): | ||||
|         return "JitOptSymbol **" | ||||
|     if var.type: | ||||
|         return var.type | ||||
|     return "JitOptSymbol *" | ||||
| 
 | ||||
| 
 | ||||
|  | @ -230,7 +228,7 @@ def generate_abstract_interpreter( | |||
|             declare_variables(override, out, skip_inputs=False) | ||||
|         else: | ||||
|             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)) | ||||
|         out.start_line() | ||||
|         out.emit("break;\n") | ||||
|  |  | |||
|  | @ -247,12 +247,11 @@ def accept(self, visitor: Visitor) -> None: | |||
| @dataclass | ||||
| class StackEffect(Node): | ||||
|     name: str = field(compare=False)  # __eq__ only uses type, cond, size | ||||
|     type: str = ""  # Optional `:type` | ||||
|     size: str = ""  # Optional `[size]` | ||||
|     # Note: size cannot be combined with type or cond | ||||
| 
 | ||||
|     def __repr__(self) -> str: | ||||
|         items = [self.name, self.type, self.size] | ||||
|         items = [self.name, self.size] | ||||
|         while items and items[-1] == "": | ||||
|             del items[-1] | ||||
|         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 '[' expression ']' | ||||
|         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 = "" | ||||
|             if self.expect(lx.LBRACKET): | ||||
|                 if type_text: | ||||
|                     raise self.make_syntax_error("Unexpected [") | ||||
|                 if not (size := self.expression()): | ||||
|                     raise self.make_syntax_error("Expected expression") | ||||
|                 self.require(lx.RBRACKET) | ||||
|                 size_text = size.text.strip() | ||||
|             return StackEffect(tkn.text, type_text, size_text) | ||||
|             return StackEffect(tkn.text, size_text) | ||||
|         return None | ||||
| 
 | ||||
|     @contextual | ||||
|  |  | |||
|  | @ -168,7 +168,7 @@ def from_memory(defn: StackItem, offset: PointerOffset) -> "Local": | |||
| 
 | ||||
|     @staticmethod | ||||
|     def register(name: str) -> "Local": | ||||
|         item = StackItem(name, None, "", False, True) | ||||
|         item = StackItem(name, "", False, True) | ||||
|         return Local(item, None, True) | ||||
| 
 | ||||
|     def kill(self) -> None: | ||||
|  | @ -216,13 +216,11 @@ def array_or_scalar(var: StackItem | Local) -> str: | |||
|     return "array" if var.is_array() else "scalar" | ||||
| 
 | ||||
| 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.physical_sp = PointerOffset.zero() | ||||
|         self.logical_sp = PointerOffset.zero() | ||||
|         self.variables: list[Local] = [] | ||||
|         self.extract_bits = extract_bits | ||||
|         self.cast_type = cast_type | ||||
| 
 | ||||
|     def drop(self, var: StackItem, check_liveness: bool) -> None: | ||||
|         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 | ||||
|         if var.name in UNUSED or not var.used: | ||||
|             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() | ||||
|         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) | ||||
|         self._print(out) | ||||
|         return Local.from_memory(var, self.base_offset) | ||||
|  | @ -292,12 +288,8 @@ def _do_emit( | |||
|         out: CWriter, | ||||
|         var: StackItem, | ||||
|         stack_offset: PointerOffset, | ||||
|         cast_type: str, | ||||
|         extract_bits: bool, | ||||
|     ) -> None: | ||||
|         cast = f"({cast_type})" if var.type else "" | ||||
|         bits = ".bits" if cast and extract_bits else "" | ||||
|         out.emit(f"stack_pointer[{stack_offset.to_c()}]{bits} = {cast}{var.name};\n") | ||||
|         out.emit(f"stack_pointer[{stack_offset.to_c()}] = {var.name};\n") | ||||
| 
 | ||||
|     def _save_physical_sp(self, out: CWriter) -> None: | ||||
|         if self.physical_sp != self.logical_sp: | ||||
|  | @ -320,7 +312,7 @@ def save_variables(self, out: CWriter) -> None: | |||
|                 self._print(out) | ||||
|                 var.memory_offset = var_offset | ||||
|                 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) | ||||
|             var_offset = var_offset.push(var.item) | ||||
| 
 | ||||
|  | @ -350,7 +342,7 @@ def _print(self, out: CWriter) -> None: | |||
|             out.emit(self.as_comment() + "\n") | ||||
| 
 | ||||
|     def copy(self) -> "Stack": | ||||
|         other = Stack(self.extract_bits, self.cast_type) | ||||
|         other = Stack() | ||||
|         other.base_offset = self.base_offset | ||||
|         other.physical_sp = self.physical_sp | ||||
|         other.logical_sp = self.logical_sp | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mark Shannon
						Mark Shannon