diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index 7f821810aea..5d20e3c30bc 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -1110,6 +1110,44 @@ def test_push_then_error(self): """ self.run_cases_test(input, output) + def test_scalar_array_inconsistency(self): + + input = """ + op(FIRST, ( -- a)) { + a = 1; + } + + op(SECOND, (a[1] -- b)) { + b = 1; + } + + macro(TEST) = FIRST + SECOND; + """ + + output = """ + """ + with self.assertRaises(SyntaxError): + self.run_cases_test(input, output) + + def test_array_size_inconsistency(self): + + input = """ + op(FIRST, ( -- a[2])) { + a[0] = 1; + } + + op(SECOND, (a[1] -- b)) { + b = 1; + } + + macro(TEST) = FIRST + SECOND; + """ + + output = """ + """ + with self.assertRaises(SyntaxError): + self.run_cases_test(input, output) + class TestGeneratedAbstractCases(unittest.TestCase): def setUp(self) -> None: diff --git a/Python/bytecodes.c b/Python/bytecodes.c index b5a642dccd2..e8cf636656e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3207,11 +3207,11 @@ dummy_func( CALL_NON_PY_GENERAL, }; - specializing op(_SPECIALIZE_CALL, (counter/1, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) { + specializing op(_SPECIALIZE_CALL, (counter/1, callable, self_or_null[1], args[oparg] -- callable, self_or_null[1], args[oparg])) { #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { next_instr = this_instr; - _Py_Specialize_Call(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null)); + _Py_Specialize_Call(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null[0])); DISPATCH_SAME_OPARG(); } OPCODE_DEFERRED_INC(CALL); @@ -3219,31 +3219,27 @@ dummy_func( #endif /* ENABLE_SPECIALIZATION */ } - op(_MAYBE_EXPAND_METHOD, (callable, self_or_null, args[oparg] -- func, maybe_self, args[oparg])) { - if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) { + op(_MAYBE_EXPAND_METHOD, (callable, self_or_null[1], args[oparg] -- func, maybe_self[1], args[oparg])) { + if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *self = ((PyMethodObject *)callable_o)->im_self; - maybe_self = PyStackRef_FromPyObjectNew(self); + maybe_self[0] = PyStackRef_FromPyObjectNew(self); PyObject *method = ((PyMethodObject *)callable_o)->im_func; func = PyStackRef_FromPyObjectNew(method); - /* Make sure that callable and all args are in memory */ - args[-2] = func; - args[-1] = maybe_self; PyStackRef_CLOSE(callable); } else { func = callable; - maybe_self = self_or_null; } } // When calling Python, inline the call using DISPATCH_INLINED(). - op(_DO_CALL, (callable, self_or_null, args[oparg] -- res)) { + op(_DO_CALL, (callable, self_or_null[1], args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3308,12 +3304,12 @@ dummy_func( res = PyStackRef_FromPyObjectSteal(res_o); } - op(_MONITOR_CALL, (func, maybe_self, args[oparg] -- func, maybe_self, args[oparg])) { - int is_meth = !PyStackRef_IsNull(maybe_self); + op(_MONITOR_CALL, (func, maybe_self[1], args[oparg] -- func, maybe_self[1], args[oparg])) { + int is_meth = !PyStackRef_IsNull(maybe_self[0]); PyObject *function = PyStackRef_AsPyObjectBorrow(func); PyObject *arg0; if (is_meth) { - arg0 = PyStackRef_AsPyObjectBorrow(maybe_self); + arg0 = PyStackRef_AsPyObjectBorrow(maybe_self[0]); } else if (oparg) { arg0 = PyStackRef_AsPyObjectBorrow(args[0]); @@ -3331,13 +3327,12 @@ 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[1], args[oparg] -- new_frame: _PyInterpreterFrame*)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3356,7 +3351,7 @@ dummy_func( } } - op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { + op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null[1], unused[oparg] -- callable, self_or_null[1], unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); EXIT_IF(!PyFunction_Check(callable_o)); PyFunctionObject *func = (PyFunctionObject *)callable_o; @@ -3371,22 +3366,22 @@ dummy_func( _SAVE_RETURN_OFFSET + _PUSH_FRAME; - op(_CHECK_METHOD_VERSION, (func_version/2, callable, null, unused[oparg] -- callable, null, unused[oparg])) { + op(_CHECK_METHOD_VERSION, (func_version/2, callable, null[1], unused[oparg] -- callable, null[1], unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); EXIT_IF(Py_TYPE(callable_o) != &PyMethod_Type); PyObject *func = ((PyMethodObject *)callable_o)->im_func; EXIT_IF(!PyFunction_Check(func)); EXIT_IF(((PyFunctionObject *)func)->func_version != func_version); - EXIT_IF(!PyStackRef_IsNull(null)); + EXIT_IF(!PyStackRef_IsNull(null[0])); } - op(_EXPAND_METHOD, (callable, null, unused[oparg] -- method, self, unused[oparg])) { + op(_EXPAND_METHOD, (callable, null[1], unused[oparg] -- method, self[1], unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - assert(PyStackRef_IsNull(null)); + assert(PyStackRef_IsNull(null[0])); assert(Py_TYPE(callable_o) == &PyMethod_Type); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); assert(PyStackRef_FunctionCheck(method)); PyStackRef_CLOSE(callable); @@ -3402,21 +3397,20 @@ dummy_func( _SAVE_RETURN_OFFSET + _PUSH_FRAME; - op(_CHECK_IS_NOT_PY_CALLABLE, (callable, unused, unused[oparg] -- callable, unused, unused[oparg])) { + op(_CHECK_IS_NOT_PY_CALLABLE, (callable, unused[1], unused[oparg] -- callable, unused[1], unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); EXIT_IF(PyFunction_Check(callable_o)); EXIT_IF(Py_TYPE(callable_o) == &PyMethod_Type); } - op(_CALL_NON_PY_GENERAL, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_NON_PY_GENERAL, (callable, self_or_null[1], args[oparg] -- res)) { #if TIER_ONE assert(opcode != INSTRUMENTED_CALL); #endif PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3447,15 +3441,15 @@ dummy_func( _CALL_NON_PY_GENERAL + _CHECK_PERIODIC; - op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) { - EXIT_IF(!PyStackRef_IsNull(null)); + op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null[1], unused[oparg] -- callable, null[1], unused[oparg])) { + EXIT_IF(!PyStackRef_IsNull(null[0])); EXIT_IF(Py_TYPE(PyStackRef_AsPyObjectBorrow(callable)) != &PyMethod_Type); } - op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- func, self, unused[oparg])) { + op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null[1], unused[oparg] -- func, self[1], unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); STAT_INC(CALL, hit); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); PyStackRef_CLOSE(callable); } @@ -3464,15 +3458,15 @@ dummy_func( DEOPT_IF(tstate->interp->eval_frame); } - op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { + op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null[1], unused[oparg] -- callable, self_or_null[1], unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); assert(PyFunction_Check(callable_o)); PyFunctionObject *func = (PyFunctionObject *)callable_o; PyCodeObject *code = (PyCodeObject *)func->func_code; - EXIT_IF(code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null))); + EXIT_IF(code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null[0]))); } - op(_CHECK_STACK_SPACE, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { + op(_CHECK_STACK_SPACE, (callable, self_or_null[1], unused[oparg] -- callable, self_or_null[1], unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyFunctionObject *func = (PyFunctionObject *)callable_o; PyCodeObject *code = (PyCodeObject *)func->func_code; @@ -3480,14 +3474,14 @@ 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[1], args[oparg] -- new_frame: _PyInterpreterFrame*)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -3640,11 +3634,11 @@ dummy_func( } } - op(_CALL_BUILTIN_CLASS, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_BUILTIN_CLASS, (callable, self_or_null[1], args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3674,12 +3668,12 @@ dummy_func( _CALL_BUILTIN_CLASS + _CHECK_PERIODIC; - op(_CALL_BUILTIN_O, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_BUILTIN_O, (callable, self_or_null[1], args[oparg] -- res)) { /* Builtin METH_O functions */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3708,12 +3702,12 @@ dummy_func( _CALL_BUILTIN_O + _CHECK_PERIODIC; - op(_CALL_BUILTIN_FAST, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_BUILTIN_FAST, (callable, self_or_null[1], args[oparg] -- res)) { /* Builtin METH_FASTCALL functions, without keywords */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3749,12 +3743,12 @@ dummy_func( _CALL_BUILTIN_FAST + _CHECK_PERIODIC; - op(_CALL_BUILTIN_FAST_WITH_KEYWORDS, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_BUILTIN_FAST_WITH_KEYWORDS, (callable, self_or_null[1], args[oparg] -- res)) { /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3791,12 +3785,12 @@ dummy_func( _CALL_BUILTIN_FAST_WITH_KEYWORDS + _CHECK_PERIODIC; - inst(CALL_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { + inst(CALL_LEN, (unused/1, unused/2, callable, self_or_null[1], args[oparg] -- res)) { /* len(o) */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3820,12 +3814,12 @@ dummy_func( res = PyStackRef_FromPyObjectSteal(res_o); } - inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { + inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null[1], args[oparg] -- res)) { /* isinstance(o, o2) */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3869,11 +3863,11 @@ dummy_func( #endif } - op(_CALL_METHOD_DESCRIPTOR_O, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_METHOD_DESCRIPTOR_O, (callable, self_or_null[1], args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3910,11 +3904,11 @@ dummy_func( _CALL_METHOD_DESCRIPTOR_O + _CHECK_PERIODIC; - op(_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (callable, self_or_null[1], args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3954,12 +3948,12 @@ dummy_func( _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS + _CHECK_PERIODIC; - op(_CALL_METHOD_DESCRIPTOR_NOARGS, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_METHOD_DESCRIPTOR_NOARGS, (callable, self_or_null[1], args[oparg] -- res)) { assert(oparg == 0 || oparg == 1); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3991,11 +3985,11 @@ dummy_func( _CALL_METHOD_DESCRIPTOR_NOARGS + _CHECK_PERIODIC; - op(_CALL_METHOD_DESCRIPTOR_FAST, (callable, self_or_null, args[oparg] -- res)) { + op(_CALL_METHOD_DESCRIPTOR_FAST, (callable, self_or_null[1], args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4056,18 +4050,17 @@ dummy_func( GO_TO_INSTRUCTION(CALL_KW); } - op(_DO_CALL_KW, (callable, self_or_null, args[oparg], kwnames -- res)) { + op(_DO_CALL_KW, (callable, self_or_null[1], args[oparg], kwnames -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } - if (self_or_null_o == NULL && Py_TYPE(callable_o) == &PyMethod_Type) { + else if (Py_TYPE(callable_o) == &PyMethod_Type) { args--; total_args++; PyObject *self = ((PyMethodObject *)callable_o)->im_self; @@ -4140,13 +4133,12 @@ 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[1], args[oparg], kwnames -- new_frame: _PyInterpreterFrame*)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4168,7 +4160,7 @@ dummy_func( } } - op(_CHECK_FUNCTION_VERSION_KW, (func_version/2, callable, self_or_null, unused[oparg], kwnames -- callable, self_or_null, unused[oparg], kwnames)) { + op(_CHECK_FUNCTION_VERSION_KW, (func_version/2, callable, self_or_null[1], unused[oparg], kwnames -- callable, self_or_null[1], unused[oparg], kwnames)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); EXIT_IF(!PyFunction_Check(callable_o)); PyFunctionObject *func = (PyFunctionObject *)callable_o; @@ -4183,22 +4175,22 @@ dummy_func( _SAVE_RETURN_OFFSET + _PUSH_FRAME; - op(_CHECK_METHOD_VERSION_KW, (func_version/2, callable, null, unused[oparg], kwnames -- callable, null, unused[oparg], kwnames)) { + op(_CHECK_METHOD_VERSION_KW, (func_version/2, callable, null[1], unused[oparg], kwnames -- callable, null[1], unused[oparg], kwnames)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); EXIT_IF(Py_TYPE(callable_o) != &PyMethod_Type); PyObject *func = ((PyMethodObject *)callable_o)->im_func; EXIT_IF(!PyFunction_Check(func)); EXIT_IF(((PyFunctionObject *)func)->func_version != func_version); - EXIT_IF(!PyStackRef_IsNull(null)); + EXIT_IF(!PyStackRef_IsNull(null[0])); } - op(_EXPAND_METHOD_KW, (callable, null, unused[oparg], kwnames -- method, self, unused[oparg], kwnames)) { + op(_EXPAND_METHOD_KW, (callable, null[1], unused[oparg], kwnames -- method, self[1], unused[oparg], kwnames)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - assert(PyStackRef_IsNull(null)); + assert(PyStackRef_IsNull(null[0])); assert(Py_TYPE(callable_o) == &PyMethod_Type); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); assert(PyStackRef_FunctionCheck(method)); PyStackRef_CLOSE(callable); @@ -4214,11 +4206,11 @@ dummy_func( _SAVE_RETURN_OFFSET + _PUSH_FRAME; - specializing op(_SPECIALIZE_CALL_KW, (counter/1, callable, self_or_null, args[oparg], kwnames -- callable, self_or_null, args[oparg], kwnames)) { + specializing op(_SPECIALIZE_CALL_KW, (counter/1, callable, self_or_null[1], args[oparg], kwnames -- callable, self_or_null[1], args[oparg], kwnames)) { #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { next_instr = this_instr; - _Py_Specialize_CallKw(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null)); + _Py_Specialize_CallKw(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null[0])); DISPATCH_SAME_OPARG(); } OPCODE_DEFERRED_INC(CALL_KW); @@ -4231,22 +4223,21 @@ dummy_func( unused/2 + _DO_CALL_KW; - op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable, unused, unused[oparg], kwnames -- callable, unused, unused[oparg], kwnames)) { + op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable, unused[1], unused[oparg], kwnames -- callable, unused[1], unused[oparg], kwnames)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); EXIT_IF(PyFunction_Check(callable_o)); EXIT_IF(Py_TYPE(callable_o) == &PyMethod_Type); } - op(_CALL_KW_NON_PY, (callable, self_or_null, args[oparg], kwnames -- res)) { + op(_CALL_KW_NON_PY, (callable, self_or_null[1], args[oparg], kwnames -- res)) { #if TIER_ONE assert(opcode != INSTRUMENTED_CALL); #endif PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 6d687bbb48b..b9f532f9b11 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -3556,31 +3556,26 @@ case _MAYBE_EXPAND_METHOD: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef func; - _PyStackRef maybe_self; + _PyStackRef *maybe_self; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; - args = &stack_pointer[-oparg]; - if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) { + maybe_self = &stack_pointer[-1 - oparg]; + if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *self = ((PyMethodObject *)callable_o)->im_self; - maybe_self = PyStackRef_FromPyObjectNew(self); - stack_pointer[-1 - oparg] = maybe_self; + maybe_self[0] = PyStackRef_FromPyObjectNew(self); PyObject *method = ((PyMethodObject *)callable_o)->im_func; func = PyStackRef_FromPyObjectNew(method); stack_pointer[-2 - oparg] = func; - /* Make sure that callable and all args are in memory */ - args[-2] = func; - args[-1] = maybe_self; PyStackRef_CLOSE(callable); } else { func = callable; - maybe_self = self_or_null; } break; } @@ -3591,18 +3586,17 @@ case _PY_FRAME_GENERAL: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3645,10 +3639,10 @@ } case _CHECK_METHOD_VERSION: { - _PyStackRef null; + _PyStackRef *null; _PyStackRef callable; oparg = CURRENT_OPARG(); - null = stack_pointer[-1 - oparg]; + null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; uint32_t func_version = (uint32_t)CURRENT_OPERAND(); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); @@ -3665,7 +3659,7 @@ UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } - if (!PyStackRef_IsNull(null)) { + if (!PyStackRef_IsNull(null[0])) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -3673,18 +3667,18 @@ } case _EXPAND_METHOD: { - _PyStackRef null; + _PyStackRef *null; _PyStackRef callable; _PyStackRef method; - _PyStackRef self; + _PyStackRef *self; oparg = CURRENT_OPARG(); - null = stack_pointer[-1 - oparg]; + null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; + self = &stack_pointer[-1 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - assert(PyStackRef_IsNull(null)); + assert(PyStackRef_IsNull(null[0])); assert(Py_TYPE(callable_o) == &PyMethod_Type); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); - stack_pointer[-1 - oparg] = self; + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); stack_pointer[-2 - oparg] = method; assert(PyStackRef_FunctionCheck(method)); @@ -3710,20 +3704,19 @@ case _CALL_NON_PY_GENERAL: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; #if TIER_ONE assert(opcode != INSTRUMENTED_CALL); #endif PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -3731,7 +3724,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -3756,12 +3749,12 @@ } case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: { - _PyStackRef null; + _PyStackRef *null; _PyStackRef callable; oparg = CURRENT_OPARG(); - null = stack_pointer[-1 - oparg]; + null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; - if (!PyStackRef_IsNull(null)) { + if (!PyStackRef_IsNull(null[0])) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -3775,13 +3768,13 @@ case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: { _PyStackRef callable; _PyStackRef func; - _PyStackRef self; + _PyStackRef *self; oparg = CURRENT_OPARG(); callable = stack_pointer[-2 - oparg]; + self = &stack_pointer[-1 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); STAT_INC(CALL, hit); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); - stack_pointer[-1 - oparg] = self; + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); stack_pointer[-2 - oparg] = func; PyStackRef_CLOSE(callable); @@ -3797,16 +3790,16 @@ } case _CHECK_FUNCTION_EXACT_ARGS: { - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; oparg = CURRENT_OPARG(); - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); assert(PyFunction_Check(callable_o)); PyFunctionObject *func = (PyFunctionObject *)callable_o; PyCodeObject *code = (PyCodeObject *)func->func_code; - if (code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null))) { + if (code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null[0]))) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -3833,21 +3826,21 @@ case _INIT_CALL_PY_EXACT_ARGS_0: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = 0; assert(oparg == CURRENT_OPARG()); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -3859,21 +3852,21 @@ case _INIT_CALL_PY_EXACT_ARGS_1: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = 1; assert(oparg == CURRENT_OPARG()); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -3885,21 +3878,21 @@ case _INIT_CALL_PY_EXACT_ARGS_2: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = 2; assert(oparg == CURRENT_OPARG()); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -3911,21 +3904,21 @@ case _INIT_CALL_PY_EXACT_ARGS_3: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = 3; assert(oparg == CURRENT_OPARG()); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -3937,21 +3930,21 @@ case _INIT_CALL_PY_EXACT_ARGS_4: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = 4; assert(oparg == CURRENT_OPARG()); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -3963,20 +3956,20 @@ case _INIT_CALL_PY_EXACT_ARGS: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -4191,16 +4184,16 @@ case _CALL_BUILTIN_CLASS: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4217,7 +4210,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -4240,17 +4233,17 @@ case _CALL_BUILTIN_O: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* Builtin METH_O functions */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4290,17 +4283,17 @@ case _CALL_BUILTIN_FAST: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* Builtin METH_FASTCALL functions, without keywords */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4318,7 +4311,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -4345,17 +4338,17 @@ case _CALL_BUILTIN_FAST_WITH_KEYWORDS: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4375,7 +4368,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -4399,17 +4392,17 @@ case _CALL_LEN: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* len(o) */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4445,17 +4438,17 @@ case _CALL_ISINSTANCE: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* isinstance(o, o2) */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4525,16 +4518,16 @@ case _CALL_METHOD_DESCRIPTOR_O: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4585,16 +4578,16 @@ case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4621,7 +4614,7 @@ STACKREFS_TO_PYOBJECTS(args, nargs, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -4645,17 +4638,17 @@ case _CALL_METHOD_DESCRIPTOR_NOARGS: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; assert(oparg == 0 || oparg == 1); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4702,16 +4695,16 @@ case _CALL_METHOD_DESCRIPTOR_FAST: { _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4738,7 +4731,7 @@ STACKREFS_TO_PYOBJECTS(args, nargs, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -4767,19 +4760,18 @@ case _PY_FRAME_KW: { _PyStackRef kwnames; _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyInterpreterFrame *new_frame; oparg = CURRENT_OPARG(); kwnames = stack_pointer[-1]; args = &stack_pointer[-1 - oparg]; - self_or_null = stack_pointer[-2 - oparg]; + self_or_null = &stack_pointer[-2 - oparg]; callable = stack_pointer[-3 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4825,10 +4817,10 @@ } case _CHECK_METHOD_VERSION_KW: { - _PyStackRef null; + _PyStackRef *null; _PyStackRef callable; oparg = CURRENT_OPARG(); - null = stack_pointer[-2 - oparg]; + null = &stack_pointer[-2 - oparg]; callable = stack_pointer[-3 - oparg]; uint32_t func_version = (uint32_t)CURRENT_OPERAND(); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); @@ -4845,7 +4837,7 @@ UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } - if (!PyStackRef_IsNull(null)) { + if (!PyStackRef_IsNull(null[0])) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -4854,19 +4846,19 @@ case _EXPAND_METHOD_KW: { _PyStackRef kwnames; - _PyStackRef null; + _PyStackRef *null; _PyStackRef callable; _PyStackRef method; - _PyStackRef self; + _PyStackRef *self; oparg = CURRENT_OPARG(); kwnames = stack_pointer[-1]; - null = stack_pointer[-2 - oparg]; + null = &stack_pointer[-2 - oparg]; callable = stack_pointer[-3 - oparg]; + self = &stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - assert(PyStackRef_IsNull(null)); + assert(PyStackRef_IsNull(null[0])); assert(Py_TYPE(callable_o) == &PyMethod_Type); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); - stack_pointer[-2 - oparg] = self; + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); stack_pointer[-3 - oparg] = method; assert(PyStackRef_FunctionCheck(method)); @@ -4894,21 +4886,20 @@ case _CALL_KW_NON_PY: { _PyStackRef kwnames; _PyStackRef *args; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef callable; _PyStackRef res; oparg = CURRENT_OPARG(); kwnames = stack_pointer[-1]; args = &stack_pointer[-1 - oparg]; - self_or_null = stack_pointer[-2 - oparg]; + self_or_null = &stack_pointer[-2 - oparg]; callable = stack_pointer[-3 - oparg]; #if TIER_ONE assert(opcode != INSTRUMENTED_CALL); #endif PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4916,7 +4907,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 65dfb990cc2..09a14ee4d38 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -834,13 +834,13 @@ _Py_CODEUNIT *this_instr = next_instr - 4; (void)this_instr; _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef func; - _PyStackRef maybe_self; + _PyStackRef *maybe_self; _PyStackRef res; // _SPECIALIZE_CALL - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { uint16_t counter = read_u16(&this_instr[1].cache); @@ -848,7 +848,7 @@ #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { next_instr = this_instr; - _Py_Specialize_Call(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null)); + _Py_Specialize_Call(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null[0])); DISPATCH_SAME_OPARG(); } OPCODE_DEFERRED_INC(CALL); @@ -859,23 +859,18 @@ // _MAYBE_EXPAND_METHOD args = &stack_pointer[-oparg]; { - args = &stack_pointer[-oparg]; - if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) { + maybe_self = &stack_pointer[-1 - oparg]; + if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *self = ((PyMethodObject *)callable_o)->im_self; - maybe_self = PyStackRef_FromPyObjectNew(self); - stack_pointer[-1 - oparg] = maybe_self; + maybe_self[0] = PyStackRef_FromPyObjectNew(self); PyObject *method = ((PyMethodObject *)callable_o)->im_func; func = PyStackRef_FromPyObjectNew(method); stack_pointer[-2 - oparg] = func; - /* Make sure that callable and all args are in memory */ - args[-2] = func; - args[-1] = maybe_self; PyStackRef_CLOSE(callable); } else { func = callable; - maybe_self = self_or_null; } } // _DO_CALL @@ -885,7 +880,7 @@ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1066,10 +1061,10 @@ INSTRUCTION_STATS(CALL_BOUND_METHOD_EXACT_ARGS); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef null; + _PyStackRef *null; _PyStackRef func; - _PyStackRef self; - _PyStackRef self_or_null; + _PyStackRef *self; + _PyStackRef *self_or_null; _PyStackRef *args; _PyInterpreterFrame *new_frame; /* Skip 1 cache entry */ @@ -1078,18 +1073,18 @@ DEOPT_IF(tstate->interp->eval_frame, CALL); } // _CHECK_CALL_BOUND_METHOD_EXACT_ARGS - null = stack_pointer[-1 - oparg]; + null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { - DEOPT_IF(!PyStackRef_IsNull(null), CALL); + DEOPT_IF(!PyStackRef_IsNull(null[0]), CALL); DEOPT_IF(Py_TYPE(PyStackRef_AsPyObjectBorrow(callable)) != &PyMethod_Type, CALL); } // _INIT_CALL_BOUND_METHOD_EXACT_ARGS { + self = &stack_pointer[-1 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); STAT_INC(CALL, hit); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); - stack_pointer[-1 - oparg] = self; + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); stack_pointer[-2 - oparg] = func; PyStackRef_CLOSE(callable); @@ -1105,13 +1100,13 @@ DEOPT_IF(func->func_version != func_version, CALL); } // _CHECK_FUNCTION_EXACT_ARGS - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); assert(PyFunction_Check(callable_o)); PyFunctionObject *func = (PyFunctionObject *)callable_o; PyCodeObject *code = (PyCodeObject *)func->func_code; - DEOPT_IF(code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null)), CALL); + DEOPT_IF(code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null[0])), CALL); } // _CHECK_STACK_SPACE { @@ -1125,12 +1120,12 @@ args = &stack_pointer[-oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -1169,10 +1164,10 @@ INSTRUCTION_STATS(CALL_BOUND_METHOD_GENERAL); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef null; + _PyStackRef *null; _PyStackRef method; - _PyStackRef self; - _PyStackRef self_or_null; + _PyStackRef *self; + _PyStackRef *self_or_null; _PyStackRef *args; _PyInterpreterFrame *new_frame; /* Skip 1 cache entry */ @@ -1181,7 +1176,7 @@ DEOPT_IF(tstate->interp->eval_frame, CALL); } // _CHECK_METHOD_VERSION - null = stack_pointer[-1 - oparg]; + null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { uint32_t func_version = read_u32(&this_instr[2].cache); @@ -1190,15 +1185,15 @@ PyObject *func = ((PyMethodObject *)callable_o)->im_func; DEOPT_IF(!PyFunction_Check(func), CALL); DEOPT_IF(((PyFunctionObject *)func)->func_version != func_version, CALL); - DEOPT_IF(!PyStackRef_IsNull(null), CALL); + DEOPT_IF(!PyStackRef_IsNull(null[0]), CALL); } // _EXPAND_METHOD { + self = &stack_pointer[-1 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - assert(PyStackRef_IsNull(null)); + assert(PyStackRef_IsNull(null[0])); assert(Py_TYPE(callable_o) == &PyMethod_Type); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); - stack_pointer[-1 - oparg] = self; + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); stack_pointer[-2 - oparg] = method; assert(PyStackRef_FunctionCheck(method)); @@ -1207,14 +1202,13 @@ // flush // _PY_FRAME_GENERAL args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1265,19 +1259,19 @@ INSTRUCTION_STATS(CALL_BUILTIN_CLASS); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_BUILTIN_CLASS args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1288,7 +1282,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -1338,20 +1332,20 @@ INSTRUCTION_STATS(CALL_BUILTIN_FAST); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_BUILTIN_FAST args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { /* Builtin METH_FASTCALL functions, without keywords */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1363,7 +1357,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -1417,20 +1411,20 @@ INSTRUCTION_STATS(CALL_BUILTIN_FAST_WITH_KEYWORDS); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_BUILTIN_FAST_WITH_KEYWORDS args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1444,7 +1438,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -1495,20 +1489,20 @@ INSTRUCTION_STATS(CALL_BUILTIN_O); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_BUILTIN_O args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { /* Builtin METH_O functions */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1711,18 +1705,18 @@ INSTRUCTION_STATS(CALL_ISINSTANCE); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* isinstance(o, o2) */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1755,12 +1749,12 @@ _Py_CODEUNIT *this_instr = next_instr - 4; (void)this_instr; _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef kwnames; _PyStackRef res; // _SPECIALIZE_CALL_KW - self_or_null = stack_pointer[-2 - oparg]; + self_or_null = &stack_pointer[-2 - oparg]; callable = stack_pointer[-3 - oparg]; { uint16_t counter = read_u16(&this_instr[1].cache); @@ -1768,7 +1762,7 @@ #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { next_instr = this_instr; - _Py_Specialize_CallKw(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null)); + _Py_Specialize_CallKw(callable, next_instr, oparg + !PyStackRef_IsNull(self_or_null[0])); DISPATCH_SAME_OPARG(); } OPCODE_DEFERRED_INC(CALL_KW); @@ -1781,15 +1775,14 @@ args = &stack_pointer[-1 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } - if (self_or_null_o == NULL && Py_TYPE(callable_o) == &PyMethod_Type) { + else if (Py_TYPE(callable_o) == &PyMethod_Type) { args--; total_args++; PyObject *self = ((PyMethodObject *)callable_o)->im_self; @@ -1828,7 +1821,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -1886,11 +1879,11 @@ INSTRUCTION_STATS(CALL_KW_BOUND_METHOD); static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef null; + _PyStackRef *null; _PyStackRef kwnames; _PyStackRef method; - _PyStackRef self; - _PyStackRef self_or_null; + _PyStackRef *self; + _PyStackRef *self_or_null; _PyStackRef *args; _PyInterpreterFrame *new_frame; /* Skip 1 cache entry */ @@ -1899,7 +1892,7 @@ DEOPT_IF(tstate->interp->eval_frame, CALL_KW); } // _CHECK_METHOD_VERSION_KW - null = stack_pointer[-2 - oparg]; + null = &stack_pointer[-2 - oparg]; callable = stack_pointer[-3 - oparg]; { uint32_t func_version = read_u32(&this_instr[2].cache); @@ -1908,16 +1901,16 @@ PyObject *func = ((PyMethodObject *)callable_o)->im_func; DEOPT_IF(!PyFunction_Check(func), CALL_KW); DEOPT_IF(((PyFunctionObject *)func)->func_version != func_version, CALL_KW); - DEOPT_IF(!PyStackRef_IsNull(null), CALL_KW); + DEOPT_IF(!PyStackRef_IsNull(null[0]), CALL_KW); } // _EXPAND_METHOD_KW kwnames = stack_pointer[-1]; { + self = &stack_pointer[-2 - oparg]; PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - assert(PyStackRef_IsNull(null)); + assert(PyStackRef_IsNull(null[0])); assert(Py_TYPE(callable_o) == &PyMethod_Type); - self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); - stack_pointer[-2 - oparg] = self; + self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); stack_pointer[-3 - oparg] = method; assert(PyStackRef_FunctionCheck(method)); @@ -1927,14 +1920,13 @@ // _PY_FRAME_KW kwnames = stack_pointer[-1]; args = &stack_pointer[-1 - oparg]; - self_or_null = stack_pointer[-2 - oparg]; + self_or_null = &stack_pointer[-2 - oparg]; callable = stack_pointer[-3 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -1989,7 +1981,7 @@ static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size"); _PyStackRef callable; _PyStackRef kwnames; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ @@ -2004,15 +1996,14 @@ // _CALL_KW_NON_PY kwnames = stack_pointer[-1]; args = &stack_pointer[-1 - oparg]; - self_or_null = stack_pointer[-2 - oparg]; + self_or_null = &stack_pointer[-2 - oparg]; { #if TIER_ONE assert(opcode != INSTRUMENTED_CALL); #endif PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2020,7 +2011,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -2077,7 +2068,7 @@ INSTRUCTION_STATS(CALL_KW_PY); static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef kwnames; _PyStackRef *args; _PyInterpreterFrame *new_frame; @@ -2098,13 +2089,12 @@ // _PY_FRAME_KW kwnames = stack_pointer[-1]; args = &stack_pointer[-1 - oparg]; - self_or_null = stack_pointer[-2 - oparg]; + self_or_null = &stack_pointer[-2 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2158,18 +2148,18 @@ INSTRUCTION_STATS(CALL_LEN); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; /* len(o) */ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2239,19 +2229,19 @@ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_METHOD_DESCRIPTOR_FAST args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2269,7 +2259,7 @@ STACKREFS_TO_PYOBJECTS(args, nargs, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -2320,19 +2310,19 @@ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2350,7 +2340,7 @@ STACKREFS_TO_PYOBJECTS(args, nargs, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -2401,20 +2391,20 @@ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_NOARGS); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_METHOD_DESCRIPTOR_NOARGS args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { assert(oparg == 0 || oparg == 1); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2469,19 +2459,19 @@ INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_O); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ /* Skip 2 cache entries */ // _CALL_METHOD_DESCRIPTOR_O args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2540,7 +2530,7 @@ INSTRUCTION_STATS(CALL_NON_PY_GENERAL); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef res; /* Skip 1 cache entry */ @@ -2554,15 +2544,14 @@ } // _CALL_NON_PY_GENERAL args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; { #if TIER_ONE assert(opcode != INSTRUMENTED_CALL); #endif PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -2570,7 +2559,7 @@ STACKREFS_TO_PYOBJECTS(args, total_args, args_o); if (CONVERSION_FAILED(args_o)) { PyStackRef_CLOSE(callable); - PyStackRef_CLOSE(self_or_null); + PyStackRef_CLOSE(self_or_null[0]); for (int _i = oparg; --_i >= 0;) { PyStackRef_CLOSE(args[_i]); } @@ -2623,7 +2612,7 @@ INSTRUCTION_STATS(CALL_PY_EXACT_ARGS); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyInterpreterFrame *new_frame; /* Skip 1 cache entry */ @@ -2641,13 +2630,13 @@ DEOPT_IF(func->func_version != func_version, CALL); } // _CHECK_FUNCTION_EXACT_ARGS - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); assert(PyFunction_Check(callable_o)); PyFunctionObject *func = (PyFunctionObject *)callable_o; PyCodeObject *code = (PyCodeObject *)func->func_code; - DEOPT_IF(code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null)), CALL); + DEOPT_IF(code->co_argcount != oparg + (!PyStackRef_IsNull(self_or_null[0])), CALL); } // _CHECK_STACK_SPACE { @@ -2661,12 +2650,12 @@ args = &stack_pointer[-oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - int has_self = !PyStackRef_IsNull(self_or_null); + int has_self = !PyStackRef_IsNull(self_or_null[0]); STAT_INC(CALL, hit); PyFunctionObject *func = (PyFunctionObject *)callable_o; new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); _PyStackRef *first_non_self_local = new_frame->localsplus + has_self; - new_frame->localsplus[0] = self_or_null; + new_frame->localsplus[0] = self_or_null[0]; for (int i = 0; i < oparg; i++) { first_non_self_local[i] = args[i]; } @@ -2705,7 +2694,7 @@ INSTRUCTION_STATS(CALL_PY_GENERAL); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyInterpreterFrame *new_frame; /* Skip 1 cache entry */ @@ -2724,13 +2713,12 @@ } // _PY_FRAME_GENERAL args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); - PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (self_or_null_o != NULL) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } @@ -4050,43 +4038,38 @@ next_instr += 4; INSTRUCTION_STATS(INSTRUMENTED_CALL); _PyStackRef callable; - _PyStackRef self_or_null; + _PyStackRef *self_or_null; _PyStackRef *args; _PyStackRef func; - _PyStackRef maybe_self; + _PyStackRef *maybe_self; _PyStackRef res; /* Skip 3 cache entries */ // _MAYBE_EXPAND_METHOD args = &stack_pointer[-oparg]; - self_or_null = stack_pointer[-1 - oparg]; + self_or_null = &stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; { - args = &stack_pointer[-oparg]; - if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) { + maybe_self = &stack_pointer[-1 - oparg]; + if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *self = ((PyMethodObject *)callable_o)->im_self; - maybe_self = PyStackRef_FromPyObjectNew(self); - stack_pointer[-1 - oparg] = maybe_self; + maybe_self[0] = PyStackRef_FromPyObjectNew(self); PyObject *method = ((PyMethodObject *)callable_o)->im_func; func = PyStackRef_FromPyObjectNew(method); stack_pointer[-2 - oparg] = func; - /* Make sure that callable and all args are in memory */ - args[-2] = func; - args[-1] = maybe_self; PyStackRef_CLOSE(callable); } else { func = callable; - maybe_self = self_or_null; } } // _MONITOR_CALL { - int is_meth = !PyStackRef_IsNull(maybe_self); + int is_meth = !PyStackRef_IsNull(maybe_self[0]); PyObject *function = PyStackRef_AsPyObjectBorrow(func); PyObject *arg0; if (is_meth) { - arg0 = PyStackRef_AsPyObjectBorrow(maybe_self); + arg0 = PyStackRef_AsPyObjectBorrow(maybe_self[0]); } else if (oparg) { arg0 = PyStackRef_AsPyObjectBorrow(args[0]); @@ -4107,7 +4090,7 @@ PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); // oparg counts all of the args, but *not* self: int total_args = oparg; - if (!PyStackRef_IsNull(self_or_null)) { + if (!PyStackRef_IsNull(self_or_null[0])) { args--; total_args++; } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 672fec3946f..e89c969ad0d 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1686,11 +1686,13 @@ case _EXPAND_METHOD: { _Py_UopsSymbol *method; - _Py_UopsSymbol *self; + _Py_UopsSymbol **self; + self = &stack_pointer[-1 - oparg]; method = sym_new_not_null(ctx); - self = sym_new_not_null(ctx); + for (int _i = 1; --_i >= 0;) { + self[_i] = sym_new_not_null(ctx); + } stack_pointer[-2 - oparg] = method; - stack_pointer[-1 - oparg] = self; break; } @@ -2045,13 +2047,15 @@ case _EXPAND_METHOD_KW: { _Py_UopsSymbol *method; - _Py_UopsSymbol *self; + _Py_UopsSymbol **self; _Py_UopsSymbol *kwnames; + self = &stack_pointer[-2 - oparg]; method = sym_new_not_null(ctx); - self = sym_new_not_null(ctx); + for (int _i = 1; --_i >= 0;) { + self[_i] = sym_new_not_null(ctx); + } kwnames = sym_new_not_null(ctx); stack_pointer[-3 - oparg] = method; - stack_pointer[-2 - oparg] = self; stack_pointer[-1] = kwnames; break; } diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py index dd4057c931c..2f8fccec2ea 100644 --- a/Tools/cases_generator/generators_common.py +++ b/Tools/cases_generator/generators_common.py @@ -165,9 +165,12 @@ def decref_inputs( if var.name == "unused" or var.name == "null" or var.peek: continue if var.size: - self.out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n") - self.out.emit(f"PyStackRef_CLOSE({var.name}[_i]);\n") - self.out.emit("}\n") + if var.size == "1": + self.out.emit(f"PyStackRef_CLOSE({var.name}[0]);\n") + else: + self.out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n") + self.out.emit(f"PyStackRef_CLOSE({var.name}[_i]);\n") + self.out.emit("}\n") elif var.condition: if var.condition == "1": self.out.emit(f"PyStackRef_CLOSE({var.name});\n") diff --git a/Tools/cases_generator/stack.py b/Tools/cases_generator/stack.py index 34bf597f2f5..de4d900563e 100644 --- a/Tools/cases_generator/stack.py +++ b/Tools/cases_generator/stack.py @@ -164,6 +164,8 @@ def clear(self) -> None: class StackError(Exception): pass +def array_or_scalar(var: StackItem | Local) -> str: + return "array" if var.is_array() else "scalar" class Stack: def __init__(self) -> None: @@ -177,10 +179,15 @@ def pop(self, var: StackItem, extract_bits: bool = False) -> tuple[str, Local]: indirect = "&" if var.is_array() else "" if self.variables: popped = self.variables.pop() + if var.is_array() ^ popped.is_array(): + raise StackError( + f"Array mismatch when popping '{popped.name}' from stack to assign to '{var.name}'. " + f"Expected {array_or_scalar(var)} got {array_or_scalar(popped)}" + ) if popped.size != var.size: raise StackError( - f"Size mismatch when popping '{popped.name}' from stack to assign to {var.name}. " - f"Expected {var.size} got {popped.size}" + f"Size mismatch when popping '{popped.name}' from stack to assign to '{var.name}'. " + f"Expected {var_size(var)} got {var_size(popped.item)}" ) if var.name in UNUSED: if popped.name not in UNUSED and popped.name in self.defined: