diff options
author | Mark Shannon <mark@hotpy.org> | 2025-01-20 17:09:23 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-20 17:09:23 +0000 |
commit | ab61d3f4303d14a413bc9ae6557c730ffdf7579e (patch) | |
tree | ec35e41ce467f4cb281208970cf453a680d82aed /Python/executor_cases.c.h | |
parent | 0a6412f9cc9e694e76299cfbd73ec969b7d47af6 (diff) | |
download | cpython-ab61d3f4303d14a413bc9ae6557c730ffdf7579e.tar.gz cpython-ab61d3f4303d14a413bc9ae6557c730ffdf7579e.zip |
GH-128914: Remove conditional stack effects from `bytecodes.c` and the code generators (GH-128918)
Diffstat (limited to 'Python/executor_cases.c.h')
-rw-r--r-- | Python/executor_cases.c.h | 306 |
1 files changed, 83 insertions, 223 deletions
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index e2eaca2c90f..049073162b6 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -406,9 +406,9 @@ } case _PUSH_NULL: { - _PyStackRef res; - res = PyStackRef_NULL; - stack_pointer[0] = res; + _PyStackRef null; + null = PyStackRef_NULL; + stack_pointer[0] = null; stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); break; @@ -1957,17 +1957,14 @@ case _LOAD_GLOBAL: { _PyStackRef *res; - _PyStackRef null = PyStackRef_NULL; oparg = CURRENT_OPARG(); res = &stack_pointer[0]; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); stack_pointer = _PyFrame_GetStackPointer(frame); if (PyStackRef_IsNull(*res)) JUMP_TO_ERROR(); - null = PyStackRef_NULL; - if (oparg & 1) stack_pointer[1] = null; - stack_pointer += 1 + (oparg & 1); + stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); break; } @@ -2033,8 +2030,6 @@ case _LOAD_GLOBAL_MODULE_FROM_KEYS: { PyDictKeysObject *globals_keys; _PyStackRef res; - _PyStackRef null = PyStackRef_NULL; - oparg = CURRENT_OPARG(); globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits; uint16_t index = (uint16_t)CURRENT_OPERAND0(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys); @@ -2056,10 +2051,8 @@ res = PyStackRef_FromPyObjectSteal(res_o); #endif STAT_INC(LOAD_GLOBAL, hit); - null = PyStackRef_NULL; stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; - stack_pointer += 1 + (oparg & 1); + stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); break; } @@ -2067,8 +2060,6 @@ case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: { PyDictKeysObject *builtins_keys; _PyStackRef res; - _PyStackRef null = PyStackRef_NULL; - oparg = CURRENT_OPARG(); builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits; uint16_t index = (uint16_t)CURRENT_OPERAND0(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys); @@ -2090,10 +2081,8 @@ res = PyStackRef_FromPyObjectSteal(res_o); #endif STAT_INC(LOAD_GLOBAL, hit); - null = PyStackRef_NULL; stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; - stack_pointer += 1 + (oparg & 1); + stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); break; } @@ -2519,6 +2508,8 @@ /* _INSTRUMENTED_LOAD_SUPER_ATTR is not a viable micro-op for tier 2 because it is instrumented */ + /* _INSTRUMENTED_LOAD_SUPER_METHOD is not a viable micro-op for tier 2 because it is instrumented */ + case _LOAD_SUPER_ATTR_ATTR: { _PyStackRef self_st; _PyStackRef class_st; @@ -2556,7 +2547,7 @@ break; } - case _LOAD_SUPER_ATTR_METHOD: { + case _LOAD_SUPER_METHOD_METHOD: { _PyStackRef self_st; _PyStackRef class_st; _PyStackRef global_super_st; @@ -2605,58 +2596,62 @@ break; } - case _LOAD_ATTR: { + case _LOAD_METHOD: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef self_or_null = PyStackRef_NULL; + _PyStackRef self_or_null; oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *attr_o; - if (oparg & 1) { - /* Designed to work in tandem with CALL, pushes two values. */ - attr_o = NULL; - _PyFrame_SetStackPointer(frame, stack_pointer); - int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o); - stack_pointer = _PyFrame_GetStackPointer(frame); - if (is_meth) { - /* We can bypass temporary bound method object. - meth is unbound method and obj is self. - meth | self | arg1 | ... | argN - */ - assert(attr_o != NULL); // No errors on this branch - self_or_null = owner; // Transfer ownership - } - else { - /* meth is not an unbound method (but a regular attr, or - something was returned by a descriptor protocol). Set - the second element of the stack to NULL, to signal - CALL that it's not a method call. - meth | NULL | arg1 | ... | argN - */ - PyStackRef_CLOSE(owner); - if (attr_o == NULL) JUMP_TO_ERROR(); - self_or_null = PyStackRef_NULL; - } + /* Designed to work in tandem with CALL, pushes two values. */ + attr_o = NULL; + _PyFrame_SetStackPointer(frame, stack_pointer); + int is_meth = _PyObject_GetMethod(PyStackRef_AsPyObjectBorrow(owner), name, &attr_o); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (is_meth) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + meth | self | arg1 | ... | argN + */ + assert(attr_o != NULL); // No errors on this branch + self_or_null = owner; // Transfer ownership } else { - /* Classic, pushes one value. */ - _PyFrame_SetStackPointer(frame, stack_pointer); - attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); - stack_pointer = _PyFrame_GetStackPointer(frame); + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + meth | NULL | arg1 | ... | argN + */ PyStackRef_CLOSE(owner); if (attr_o == NULL) JUMP_TO_ERROR(); - /* We need to define self_or_null on all paths */ self_or_null = PyStackRef_NULL; } attr = PyStackRef_FromPyObjectSteal(attr_o); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = self_or_null; - stack_pointer += (oparg & 1); + stack_pointer[0] = self_or_null; + stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); break; } + case _LOAD_ATTR: { + _PyStackRef owner; + _PyStackRef attr; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyObject *attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name); + stack_pointer = _PyFrame_GetStackPointer(frame); + PyStackRef_CLOSE(owner); + if (attr_o == NULL) JUMP_TO_ERROR(); + attr = PyStackRef_FromPyObjectSteal(attr_o); + stack_pointer[-1] = attr; + break; + } + case _GUARD_TYPE_VERSION: { _PyStackRef owner; owner = stack_pointer[-1]; @@ -2704,42 +2699,9 @@ break; } - case _LOAD_ATTR_INSTANCE_VALUE_0: { - _PyStackRef owner; - _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - (void)null; - owner = stack_pointer[-1]; - uint16_t offset = (uint16_t)CURRENT_OPERAND0(); - PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset); - PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr); - if (attr_o == NULL) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } - #ifdef Py_GIL_DISABLED - if (!_Py_TryIncrefCompareStackRef(value_ptr, attr_o, &attr)) { - if (true) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } - } - #else - attr = PyStackRef_FromPyObjectNew(attr_o); - #endif - STAT_INC(LOAD_ATTR, hit); - null = PyStackRef_NULL; - PyStackRef_CLOSE(owner); - stack_pointer[-1] = attr; - break; - } - - case _LOAD_ATTR_INSTANCE_VALUE_1: { + case _LOAD_ATTR_INSTANCE_VALUE: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - (void)null; owner = stack_pointer[-1]; uint16_t offset = (uint16_t)CURRENT_OPERAND0(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); @@ -2760,17 +2722,11 @@ attr = PyStackRef_FromPyObjectNew(attr_o); #endif STAT_INC(LOAD_ATTR, hit); - null = PyStackRef_NULL; PyStackRef_CLOSE(owner); stack_pointer[-1] = attr; - stack_pointer[0] = null; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); break; } - /* _LOAD_ATTR_INSTANCE_VALUE is split on (oparg & 1) */ - case _CHECK_ATTR_MODULE_PUSH_KEYS: { _PyStackRef owner; PyDictKeysObject *mod_keys; @@ -2799,8 +2755,6 @@ PyDictKeysObject *mod_keys; _PyStackRef owner; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - oparg = CURRENT_OPARG(); mod_keys = (PyDictKeysObject *)stack_pointer[-1].bits; owner = stack_pointer[-2]; uint16_t index = (uint16_t)CURRENT_OPERAND0(); @@ -2828,12 +2782,8 @@ attr = PyStackRef_FromPyObjectSteal(attr_o); #endif STAT_INC(LOAD_ATTR, hit); - null = PyStackRef_NULL; PyStackRef_CLOSE(owner); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; - stack_pointer += (oparg & 1); - assert(WITHIN_STACK_BOUNDS()); break; } @@ -2860,7 +2810,6 @@ PyDictObject *dict; _PyStackRef owner; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; oparg = CURRENT_OPARG(); dict = (PyDictObject *)stack_pointer[-1].bits; owner = stack_pointer[-2]; @@ -2883,7 +2832,7 @@ JUMP_TO_JUMP_TARGET(); } } - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) { UNLOCK_OBJECT(dict); stack_pointer += -1; @@ -2916,20 +2865,16 @@ STAT_INC(LOAD_ATTR, hit); attr = PyStackRef_FromPyObjectNew(attr_o); UNLOCK_OBJECT(dict); - null = PyStackRef_NULL; PyStackRef_CLOSE(owner); stack_pointer[-2] = attr; - if (oparg & 1) stack_pointer[-1] = null; - stack_pointer += -1 + (oparg & 1); + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); break; } - case _LOAD_ATTR_SLOT_0: { + case _LOAD_ATTR_SLOT: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - (void)null; owner = stack_pointer[-1]; uint16_t index = (uint16_t)CURRENT_OPERAND0(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); @@ -2949,47 +2894,11 @@ attr = PyStackRef_FromPyObjectNew(attr_o); #endif STAT_INC(LOAD_ATTR, hit); - null = PyStackRef_NULL; PyStackRef_CLOSE(owner); stack_pointer[-1] = attr; break; } - case _LOAD_ATTR_SLOT_1: { - _PyStackRef owner; - _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - (void)null; - owner = stack_pointer[-1]; - uint16_t index = (uint16_t)CURRENT_OPERAND0(); - PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - PyObject **addr = (PyObject **)((char *)owner_o + index); - PyObject *attr_o = FT_ATOMIC_LOAD_PTR(*addr); - if (attr_o == NULL) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } - #ifdef Py_GIL_DISABLED - int increfed = _Py_TryIncrefCompareStackRef(addr, attr_o, &attr); - if (!increfed) { - UOP_STAT_INC(uopcode, miss); - JUMP_TO_JUMP_TARGET(); - } - #else - attr = PyStackRef_FromPyObjectNew(attr_o); - #endif - STAT_INC(LOAD_ATTR, hit); - null = PyStackRef_NULL; - PyStackRef_CLOSE(owner); - stack_pointer[-1] = attr; - stack_pointer[0] = null; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - break; - } - - /* _LOAD_ATTR_SLOT is split on (oparg & 1) */ - case _CHECK_ATTR_CLASS: { _PyStackRef owner; owner = stack_pointer[-1]; @@ -3007,50 +2916,24 @@ break; } - case _LOAD_ATTR_CLASS_0: { + case _LOAD_ATTR_CLASS: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - (void)null; owner = stack_pointer[-1]; PyObject *descr = (PyObject *)CURRENT_OPERAND0(); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); attr = PyStackRef_FromPyObjectNew(descr); - null = PyStackRef_NULL; PyStackRef_CLOSE(owner); stack_pointer[-1] = attr; break; } - case _LOAD_ATTR_CLASS_1: { - _PyStackRef owner; - _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - (void)null; - owner = stack_pointer[-1]; - PyObject *descr = (PyObject *)CURRENT_OPERAND0(); - STAT_INC(LOAD_ATTR, hit); - assert(descr != NULL); - attr = PyStackRef_FromPyObjectNew(descr); - null = PyStackRef_NULL; - PyStackRef_CLOSE(owner); - stack_pointer[-1] = attr; - stack_pointer[0] = null; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - break; - } - - /* _LOAD_ATTR_CLASS is split on (oparg & 1) */ - case _LOAD_ATTR_PROPERTY_FRAME: { _PyStackRef owner; _PyInterpreterFrame *new_frame; - oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; PyObject *fget = (PyObject *)CURRENT_OPERAND0(); - assert((oparg & 1) == 0); assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; PyCodeObject *code = (PyCodeObject *)f->func_code; @@ -4056,14 +3939,12 @@ break; } - case _LOAD_ATTR_METHOD_WITH_VALUES: { + case _LOAD_METHOD_WITH_VALUES: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef self = PyStackRef_NULL; - oparg = CURRENT_OPARG(); + _PyStackRef self; owner = stack_pointer[-1]; PyObject *descr = (PyObject *)CURRENT_OPERAND0(); - assert(oparg & 1); /* Cached method object */ STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); @@ -4077,14 +3958,12 @@ break; } - case _LOAD_ATTR_METHOD_NO_DICT: { + case _LOAD_METHOD_NO_DICT: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef self = PyStackRef_NULL; - oparg = CURRENT_OPARG(); + _PyStackRef self; owner = stack_pointer[-1]; PyObject *descr = (PyObject *)CURRENT_OPERAND0(); - assert(oparg & 1); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); @@ -4101,10 +3980,8 @@ case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: { _PyStackRef owner; _PyStackRef attr; - oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; PyObject *descr = (PyObject *)CURRENT_OPERAND0(); - assert((oparg & 1) == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); PyStackRef_CLOSE(owner); @@ -4116,10 +3993,8 @@ case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: { _PyStackRef owner; _PyStackRef attr; - oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; PyObject *descr = (PyObject *)CURRENT_OPERAND0(); - assert((oparg & 1) == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); @@ -4143,14 +4018,12 @@ break; } - case _LOAD_ATTR_METHOD_LAZY_DICT: { + case _LOAD_METHOD_LAZY_DICT: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef self = PyStackRef_NULL; - oparg = CURRENT_OPARG(); + _PyStackRef self; owner = stack_pointer[-1]; PyObject *descr = (PyObject *)CURRENT_OPERAND0(); - assert(oparg & 1); STAT_INC(LOAD_ATTR, hit); assert(descr != NULL); assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); @@ -5644,15 +5517,14 @@ /* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */ case _MAKE_CALLARGS_A_TUPLE: { - _PyStackRef kwargs_in = PyStackRef_NULL; + _PyStackRef kwargs_in; _PyStackRef callargs; _PyStackRef func; _PyStackRef tuple; - _PyStackRef kwargs_out = PyStackRef_NULL; - oparg = CURRENT_OPARG(); - if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; } - callargs = stack_pointer[-1 - (oparg & 1)]; - func = stack_pointer[-3 - (oparg & 1)]; + _PyStackRef kwargs_out; + kwargs_in = stack_pointer[-1]; + callargs = stack_pointer[-2]; + func = stack_pointer[-4]; PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs); if (PyTuple_CheckExact(callargs_o)) { tuple = callargs; @@ -5675,8 +5547,8 @@ PyStackRef_CLOSE(callargs); tuple = PyStackRef_FromPyObjectSteal(tuple_o); } - stack_pointer[-1 - (oparg & 1)] = tuple; - if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out; + stack_pointer[-2] = tuple; + stack_pointer[-1] = kwargs_out; break; } @@ -5753,25 +5625,27 @@ } case _BUILD_SLICE: { - _PyStackRef step = PyStackRef_NULL; - _PyStackRef stop; - _PyStackRef start; + _PyStackRef *args; _PyStackRef slice; oparg = CURRENT_OPARG(); - if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; } - stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)]; - start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)]; + args = &stack_pointer[-oparg]; + assert(oparg == 2 || oparg == 3); + _PyStackRef start = args[0]; + _PyStackRef stop = args[1]; PyObject *start_o = PyStackRef_AsPyObjectBorrow(start); PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop); - PyObject *step_o = PyStackRef_AsPyObjectBorrow(step); + PyObject * step_o = NULL; + if (oparg == 3) { + step_o = PyStackRef_AsPyObjectBorrow(args[2]); + } PyObject *slice_o = PySlice_New(start_o, stop_o, step_o); - PyStackRef_CLOSE(start); - PyStackRef_CLOSE(stop); - PyStackRef_XCLOSE(step); + for (int _i = oparg; --_i >= 0;) { + PyStackRef_CLOSE(args[_i]); + } if (slice_o == NULL) JUMP_TO_ERROR(); slice = PyStackRef_FromPyObjectSteal(slice_o); - stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice; - stack_pointer += -1 - ((oparg == 3) ? 1 : 0); + stack_pointer[-oparg] = slice; + stack_pointer += 1 - oparg; assert(WITHIN_STACK_BOUNDS()); break; } @@ -6138,8 +6012,6 @@ case _LOAD_GLOBAL_MODULE: { _PyStackRef res; - _PyStackRef null = PyStackRef_NULL; - oparg = CURRENT_OPARG(); uint16_t index = (uint16_t)CURRENT_OPERAND0(); PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); @@ -6150,18 +6022,14 @@ } Py_INCREF(res_o); res = PyStackRef_FromPyObjectSteal(res_o); - null = PyStackRef_NULL; stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; - stack_pointer += 1 + (oparg & 1); + stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); break; } case _LOAD_GLOBAL_BUILTINS: { _PyStackRef res; - _PyStackRef null = PyStackRef_NULL; - oparg = CURRENT_OPARG(); uint16_t index = (uint16_t)CURRENT_OPERAND0(); PyDictObject *dict = (PyDictObject *)BUILTINS(); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); @@ -6172,10 +6040,8 @@ } Py_INCREF(res_o); res = PyStackRef_FromPyObjectSteal(res_o); - null = PyStackRef_NULL; stack_pointer[0] = res; - if (oparg & 1) stack_pointer[1] = null; - stack_pointer += 1 + (oparg & 1); + stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); break; } @@ -6183,8 +6049,6 @@ case _LOAD_ATTR_MODULE: { _PyStackRef owner; _PyStackRef attr; - _PyStackRef null = PyStackRef_NULL; - oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; uint16_t index = (uint16_t)CURRENT_OPERAND0(); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); @@ -6200,12 +6064,8 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(attr_o); attr = PyStackRef_FromPyObjectSteal(attr_o); - null = PyStackRef_NULL; PyStackRef_CLOSE(owner); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = null; - stack_pointer += (oparg & 1); - assert(WITHIN_STACK_BOUNDS()); break; } |