GH-123996: Explicitly mark 'self_or_null' as an array of size 1 to ensure that it is kept in memory for calls (GH-124003)

This commit is contained in:
Mark Shannon 2024-09-12 15:32:45 +01:00 committed by GitHub
parent 3ea51fa2e3
commit 4ed7d1d6ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 344 additions and 327 deletions

View file

@ -1110,6 +1110,44 @@ class TestGeneratedCases(unittest.TestCase):
""" """
self.run_cases_test(input, output) 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): class TestGeneratedAbstractCases(unittest.TestCase):
def setUp(self) -> None: def setUp(self) -> None:

View file

@ -3207,11 +3207,11 @@ dummy_func(
CALL_NON_PY_GENERAL, 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 ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr; 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(); DISPATCH_SAME_OPARG();
} }
OPCODE_DEFERRED_INC(CALL); OPCODE_DEFERRED_INC(CALL);
@ -3219,31 +3219,27 @@ dummy_func(
#endif /* ENABLE_SPECIALIZATION */ #endif /* ENABLE_SPECIALIZATION */
} }
op(_MAYBE_EXPAND_METHOD, (callable, self_or_null, args[oparg] -- func, maybe_self, args[oparg])) { 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)) { if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self = ((PyMethodObject *)callable_o)->im_self; 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; PyObject *method = ((PyMethodObject *)callable_o)->im_func;
func = PyStackRef_FromPyObjectNew(method); func = PyStackRef_FromPyObjectNew(method);
/* Make sure that callable and all args are in memory */
args[-2] = func;
args[-1] = maybe_self;
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
} }
else { else {
func = callable; func = callable;
maybe_self = self_or_null;
} }
} }
// When calling Python, inline the call using DISPATCH_INLINED(). // 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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
// oparg counts all of the args, but *not* self: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3308,12 +3304,12 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
} }
op(_MONITOR_CALL, (func, maybe_self, args[oparg] -- func, maybe_self, args[oparg])) { op(_MONITOR_CALL, (func, maybe_self[1], args[oparg] -- func, maybe_self[1], args[oparg])) {
int is_meth = !PyStackRef_IsNull(maybe_self); int is_meth = !PyStackRef_IsNull(maybe_self[0]);
PyObject *function = PyStackRef_AsPyObjectBorrow(func); PyObject *function = PyStackRef_AsPyObjectBorrow(func);
PyObject *arg0; PyObject *arg0;
if (is_meth) { if (is_meth) {
arg0 = PyStackRef_AsPyObjectBorrow(maybe_self); arg0 = PyStackRef_AsPyObjectBorrow(maybe_self[0]);
} }
else if (oparg) { else if (oparg) {
arg0 = PyStackRef_AsPyObjectBorrow(args[0]); 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(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC;
macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC; macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC;
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) { op(_PY_FRAME_GENERAL, (callable, self_or_null[1], args[oparg] -- new_frame: _PyInterpreterFrame*)) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
EXIT_IF(!PyFunction_Check(callable_o)); EXIT_IF(!PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
@ -3371,22 +3366,22 @@ dummy_func(
_SAVE_RETURN_OFFSET + _SAVE_RETURN_OFFSET +
_PUSH_FRAME; _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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
EXIT_IF(Py_TYPE(callable_o) != &PyMethod_Type); EXIT_IF(Py_TYPE(callable_o) != &PyMethod_Type);
PyObject *func = ((PyMethodObject *)callable_o)->im_func; PyObject *func = ((PyMethodObject *)callable_o)->im_func;
EXIT_IF(!PyFunction_Check(func)); EXIT_IF(!PyFunction_Check(func));
EXIT_IF(((PyFunctionObject *)func)->func_version != func_version); 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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyStackRef_IsNull(null)); assert(PyStackRef_IsNull(null[0]));
assert(Py_TYPE(callable_o) == &PyMethod_Type); 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); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
assert(PyStackRef_FunctionCheck(method)); assert(PyStackRef_FunctionCheck(method));
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
@ -3402,21 +3397,20 @@ dummy_func(
_SAVE_RETURN_OFFSET + _SAVE_RETURN_OFFSET +
_PUSH_FRAME; _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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
EXIT_IF(PyFunction_Check(callable_o)); EXIT_IF(PyFunction_Check(callable_o));
EXIT_IF(Py_TYPE(callable_o) == &PyMethod_Type); 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 #if TIER_ONE
assert(opcode != INSTRUMENTED_CALL); assert(opcode != INSTRUMENTED_CALL);
#endif #endif
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3447,15 +3441,15 @@ dummy_func(
_CALL_NON_PY_GENERAL + _CALL_NON_PY_GENERAL +
_CHECK_PERIODIC; _CHECK_PERIODIC;
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) { op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null[1], unused[oparg] -- callable, null[1], unused[oparg])) {
EXIT_IF(!PyStackRef_IsNull(null)); EXIT_IF(!PyStackRef_IsNull(null[0]));
EXIT_IF(Py_TYPE(PyStackRef_AsPyObjectBorrow(callable)) != &PyMethod_Type); 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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
STAT_INC(CALL, hit); 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); func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
} }
@ -3464,15 +3458,15 @@ dummy_func(
DEOPT_IF(tstate->interp->eval_frame); 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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyFunction_Check(callable_o)); assert(PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
PyCodeObject *code = (PyCodeObject *)func->func_code; 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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
PyCodeObject *code = (PyCodeObject *)func->func_code; PyCodeObject *code = (PyCodeObject *)func->func_code;
@ -3480,14 +3474,14 @@ dummy_func(
DEOPT_IF(tstate->py_recursion_remaining <= 1); DEOPT_IF(tstate->py_recursion_remaining <= 1);
} }
replicate(5) pure op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) { replicate(5) pure op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null[1], args[oparg] -- new_frame: _PyInterpreterFrame*)) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3674,12 +3668,12 @@ dummy_func(
_CALL_BUILTIN_CLASS + _CALL_BUILTIN_CLASS +
_CHECK_PERIODIC; _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 */ /* Builtin METH_O functions */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3708,12 +3702,12 @@ dummy_func(
_CALL_BUILTIN_O + _CALL_BUILTIN_O +
_CHECK_PERIODIC; _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 */ /* Builtin METH_FASTCALL functions, without keywords */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3749,12 +3743,12 @@ dummy_func(
_CALL_BUILTIN_FAST + _CALL_BUILTIN_FAST +
_CHECK_PERIODIC; _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 */ /* Builtin METH_FASTCALL | METH_KEYWORDS functions */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3791,12 +3785,12 @@ dummy_func(
_CALL_BUILTIN_FAST_WITH_KEYWORDS + _CALL_BUILTIN_FAST_WITH_KEYWORDS +
_CHECK_PERIODIC; _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) */ /* len(o) */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3820,12 +3814,12 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o); 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) */ /* isinstance(o, o2) */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3869,11 +3863,11 @@ dummy_func(
#endif #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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3910,11 +3904,11 @@ dummy_func(
_CALL_METHOD_DESCRIPTOR_O + _CALL_METHOD_DESCRIPTOR_O +
_CHECK_PERIODIC; _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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3954,12 +3948,12 @@ dummy_func(
_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS + _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS +
_CHECK_PERIODIC; _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); assert(oparg == 0 || oparg == 1);
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3991,11 +3985,11 @@ dummy_func(
_CALL_METHOD_DESCRIPTOR_NOARGS + _CALL_METHOD_DESCRIPTOR_NOARGS +
_CHECK_PERIODIC; _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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4056,18 +4050,17 @@ dummy_func(
GO_TO_INSTRUCTION(CALL_KW); 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 *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames); PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
// oparg counts all of the args, but *not* self: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
if (self_or_null_o == NULL && Py_TYPE(callable_o) == &PyMethod_Type) { else if (Py_TYPE(callable_o) == &PyMethod_Type) {
args--; args--;
total_args++; total_args++;
PyObject *self = ((PyMethodObject *)callable_o)->im_self; PyObject *self = ((PyMethodObject *)callable_o)->im_self;
@ -4140,13 +4133,12 @@ dummy_func(
res = PyStackRef_FromPyObjectSteal(res_o); res = PyStackRef_FromPyObjectSteal(res_o);
} }
op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame: _PyInterpreterFrame*)) { op(_PY_FRAME_KW, (callable, self_or_null[1], args[oparg], kwnames -- new_frame: _PyInterpreterFrame*)) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
EXIT_IF(!PyFunction_Check(callable_o)); EXIT_IF(!PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
@ -4183,22 +4175,22 @@ dummy_func(
_SAVE_RETURN_OFFSET + _SAVE_RETURN_OFFSET +
_PUSH_FRAME; _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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
EXIT_IF(Py_TYPE(callable_o) != &PyMethod_Type); EXIT_IF(Py_TYPE(callable_o) != &PyMethod_Type);
PyObject *func = ((PyMethodObject *)callable_o)->im_func; PyObject *func = ((PyMethodObject *)callable_o)->im_func;
EXIT_IF(!PyFunction_Check(func)); EXIT_IF(!PyFunction_Check(func));
EXIT_IF(((PyFunctionObject *)func)->func_version != func_version); 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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyStackRef_IsNull(null)); assert(PyStackRef_IsNull(null[0]));
assert(Py_TYPE(callable_o) == &PyMethod_Type); 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); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
assert(PyStackRef_FunctionCheck(method)); assert(PyStackRef_FunctionCheck(method));
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
@ -4214,11 +4206,11 @@ dummy_func(
_SAVE_RETURN_OFFSET + _SAVE_RETURN_OFFSET +
_PUSH_FRAME; _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 ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr; 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(); DISPATCH_SAME_OPARG();
} }
OPCODE_DEFERRED_INC(CALL_KW); OPCODE_DEFERRED_INC(CALL_KW);
@ -4231,22 +4223,21 @@ dummy_func(
unused/2 + unused/2 +
_DO_CALL_KW; _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); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
EXIT_IF(PyFunction_Check(callable_o)); EXIT_IF(PyFunction_Check(callable_o));
EXIT_IF(Py_TYPE(callable_o) == &PyMethod_Type); 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 #if TIER_ONE
assert(opcode != INSTRUMENTED_CALL); assert(opcode != INSTRUMENTED_CALL);
#endif #endif
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }

View file

@ -3556,31 +3556,26 @@
case _MAYBE_EXPAND_METHOD: { case _MAYBE_EXPAND_METHOD: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef func; _PyStackRef func;
_PyStackRef maybe_self; _PyStackRef *maybe_self;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
args = &stack_pointer[-oparg]; maybe_self = &stack_pointer[-1 - oparg];
if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) { if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self = ((PyMethodObject *)callable_o)->im_self; PyObject *self = ((PyMethodObject *)callable_o)->im_self;
maybe_self = PyStackRef_FromPyObjectNew(self); maybe_self[0] = PyStackRef_FromPyObjectNew(self);
stack_pointer[-1 - oparg] = maybe_self;
PyObject *method = ((PyMethodObject *)callable_o)->im_func; PyObject *method = ((PyMethodObject *)callable_o)->im_func;
func = PyStackRef_FromPyObjectNew(method); func = PyStackRef_FromPyObjectNew(method);
stack_pointer[-2 - oparg] = func; 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); PyStackRef_CLOSE(callable);
} }
else { else {
func = callable; func = callable;
maybe_self = self_or_null;
} }
break; break;
} }
@ -3591,18 +3586,17 @@
case _PY_FRAME_GENERAL: { case _PY_FRAME_GENERAL: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3645,10 +3639,10 @@
} }
case _CHECK_METHOD_VERSION: { case _CHECK_METHOD_VERSION: {
_PyStackRef null; _PyStackRef *null;
_PyStackRef callable; _PyStackRef callable;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
null = stack_pointer[-1 - oparg]; null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
uint32_t func_version = (uint32_t)CURRENT_OPERAND(); uint32_t func_version = (uint32_t)CURRENT_OPERAND();
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
@ -3665,7 +3659,7 @@
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
} }
if (!PyStackRef_IsNull(null)) { if (!PyStackRef_IsNull(null[0])) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
} }
@ -3673,18 +3667,18 @@
} }
case _EXPAND_METHOD: { case _EXPAND_METHOD: {
_PyStackRef null; _PyStackRef *null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef method; _PyStackRef method;
_PyStackRef self; _PyStackRef *self;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
null = stack_pointer[-1 - oparg]; null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
self = &stack_pointer[-1 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyStackRef_IsNull(null)); assert(PyStackRef_IsNull(null[0]));
assert(Py_TYPE(callable_o) == &PyMethod_Type); assert(Py_TYPE(callable_o) == &PyMethod_Type);
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
stack_pointer[-1 - oparg] = self;
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
stack_pointer[-2 - oparg] = method; stack_pointer[-2 - oparg] = method;
assert(PyStackRef_FunctionCheck(method)); assert(PyStackRef_FunctionCheck(method));
@ -3710,20 +3704,19 @@
case _CALL_NON_PY_GENERAL: { case _CALL_NON_PY_GENERAL: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
#if TIER_ONE #if TIER_ONE
assert(opcode != INSTRUMENTED_CALL); assert(opcode != INSTRUMENTED_CALL);
#endif #endif
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -3731,7 +3724,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -3756,12 +3749,12 @@
} }
case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: { case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: {
_PyStackRef null; _PyStackRef *null;
_PyStackRef callable; _PyStackRef callable;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
null = stack_pointer[-1 - oparg]; null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
if (!PyStackRef_IsNull(null)) { if (!PyStackRef_IsNull(null[0])) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
} }
@ -3775,13 +3768,13 @@
case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: { case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: {
_PyStackRef callable; _PyStackRef callable;
_PyStackRef func; _PyStackRef func;
_PyStackRef self; _PyStackRef *self;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
self = &stack_pointer[-1 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
stack_pointer[-1 - oparg] = self;
func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
stack_pointer[-2 - oparg] = func; stack_pointer[-2 - oparg] = func;
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
@ -3797,16 +3790,16 @@
} }
case _CHECK_FUNCTION_EXACT_ARGS: { case _CHECK_FUNCTION_EXACT_ARGS: {
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyFunction_Check(callable_o)); assert(PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
PyCodeObject *code = (PyCodeObject *)func->func_code; 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); UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
} }
@ -3833,21 +3826,21 @@
case _INIT_CALL_PY_EXACT_ARGS_0: { case _INIT_CALL_PY_EXACT_ARGS_0: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = 0; oparg = 0;
assert(oparg == CURRENT_OPARG()); assert(oparg == CURRENT_OPARG());
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -3859,21 +3852,21 @@
case _INIT_CALL_PY_EXACT_ARGS_1: { case _INIT_CALL_PY_EXACT_ARGS_1: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = 1; oparg = 1;
assert(oparg == CURRENT_OPARG()); assert(oparg == CURRENT_OPARG());
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -3885,21 +3878,21 @@
case _INIT_CALL_PY_EXACT_ARGS_2: { case _INIT_CALL_PY_EXACT_ARGS_2: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = 2; oparg = 2;
assert(oparg == CURRENT_OPARG()); assert(oparg == CURRENT_OPARG());
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -3911,21 +3904,21 @@
case _INIT_CALL_PY_EXACT_ARGS_3: { case _INIT_CALL_PY_EXACT_ARGS_3: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = 3; oparg = 3;
assert(oparg == CURRENT_OPARG()); assert(oparg == CURRENT_OPARG());
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -3937,21 +3930,21 @@
case _INIT_CALL_PY_EXACT_ARGS_4: { case _INIT_CALL_PY_EXACT_ARGS_4: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = 4; oparg = 4;
assert(oparg == CURRENT_OPARG()); assert(oparg == CURRENT_OPARG());
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -3963,20 +3956,20 @@
case _INIT_CALL_PY_EXACT_ARGS: { case _INIT_CALL_PY_EXACT_ARGS: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -4191,16 +4184,16 @@
case _CALL_BUILTIN_CLASS: { case _CALL_BUILTIN_CLASS: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4217,7 +4210,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -4240,17 +4233,17 @@
case _CALL_BUILTIN_O: { case _CALL_BUILTIN_O: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
/* Builtin METH_O functions */ /* Builtin METH_O functions */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4290,17 +4283,17 @@
case _CALL_BUILTIN_FAST: { case _CALL_BUILTIN_FAST: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
/* Builtin METH_FASTCALL functions, without keywords */ /* Builtin METH_FASTCALL functions, without keywords */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4318,7 +4311,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -4345,17 +4338,17 @@
case _CALL_BUILTIN_FAST_WITH_KEYWORDS: { case _CALL_BUILTIN_FAST_WITH_KEYWORDS: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
/* Builtin METH_FASTCALL | METH_KEYWORDS functions */ /* Builtin METH_FASTCALL | METH_KEYWORDS functions */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4375,7 +4368,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -4399,17 +4392,17 @@
case _CALL_LEN: { case _CALL_LEN: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
/* len(o) */ /* len(o) */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4445,17 +4438,17 @@
case _CALL_ISINSTANCE: { case _CALL_ISINSTANCE: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
/* isinstance(o, o2) */ /* isinstance(o, o2) */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4525,16 +4518,16 @@
case _CALL_METHOD_DESCRIPTOR_O: { case _CALL_METHOD_DESCRIPTOR_O: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4585,16 +4578,16 @@
case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: { case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4621,7 +4614,7 @@
STACKREFS_TO_PYOBJECTS(args, nargs, args_o); STACKREFS_TO_PYOBJECTS(args, nargs, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -4645,17 +4638,17 @@
case _CALL_METHOD_DESCRIPTOR_NOARGS: { case _CALL_METHOD_DESCRIPTOR_NOARGS: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
assert(oparg == 0 || oparg == 1); assert(oparg == 0 || oparg == 1);
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4702,16 +4695,16 @@
case _CALL_METHOD_DESCRIPTOR_FAST: { case _CALL_METHOD_DESCRIPTOR_FAST: {
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4738,7 +4731,7 @@
STACKREFS_TO_PYOBJECTS(args, nargs, args_o); STACKREFS_TO_PYOBJECTS(args, nargs, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -4767,19 +4760,18 @@
case _PY_FRAME_KW: { case _PY_FRAME_KW: {
_PyStackRef kwnames; _PyStackRef kwnames;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
kwnames = stack_pointer[-1]; kwnames = stack_pointer[-1];
args = &stack_pointer[-1 - oparg]; args = &stack_pointer[-1 - oparg];
self_or_null = stack_pointer[-2 - oparg]; self_or_null = &stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg]; callable = stack_pointer[-3 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4825,10 +4817,10 @@
} }
case _CHECK_METHOD_VERSION_KW: { case _CHECK_METHOD_VERSION_KW: {
_PyStackRef null; _PyStackRef *null;
_PyStackRef callable; _PyStackRef callable;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
null = stack_pointer[-2 - oparg]; null = &stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg]; callable = stack_pointer[-3 - oparg];
uint32_t func_version = (uint32_t)CURRENT_OPERAND(); uint32_t func_version = (uint32_t)CURRENT_OPERAND();
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
@ -4845,7 +4837,7 @@
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
} }
if (!PyStackRef_IsNull(null)) { if (!PyStackRef_IsNull(null[0])) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
} }
@ -4854,19 +4846,19 @@
case _EXPAND_METHOD_KW: { case _EXPAND_METHOD_KW: {
_PyStackRef kwnames; _PyStackRef kwnames;
_PyStackRef null; _PyStackRef *null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef method; _PyStackRef method;
_PyStackRef self; _PyStackRef *self;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
kwnames = stack_pointer[-1]; kwnames = stack_pointer[-1];
null = stack_pointer[-2 - oparg]; null = &stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg]; callable = stack_pointer[-3 - oparg];
self = &stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyStackRef_IsNull(null)); assert(PyStackRef_IsNull(null[0]));
assert(Py_TYPE(callable_o) == &PyMethod_Type); assert(Py_TYPE(callable_o) == &PyMethod_Type);
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
stack_pointer[-2 - oparg] = self;
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
stack_pointer[-3 - oparg] = method; stack_pointer[-3 - oparg] = method;
assert(PyStackRef_FunctionCheck(method)); assert(PyStackRef_FunctionCheck(method));
@ -4894,21 +4886,20 @@
case _CALL_KW_NON_PY: { case _CALL_KW_NON_PY: {
_PyStackRef kwnames; _PyStackRef kwnames;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef res; _PyStackRef res;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
kwnames = stack_pointer[-1]; kwnames = stack_pointer[-1];
args = &stack_pointer[-1 - oparg]; args = &stack_pointer[-1 - oparg];
self_or_null = stack_pointer[-2 - oparg]; self_or_null = &stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg]; callable = stack_pointer[-3 - oparg];
#if TIER_ONE #if TIER_ONE
assert(opcode != INSTRUMENTED_CALL); assert(opcode != INSTRUMENTED_CALL);
#endif #endif
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4916,7 +4907,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }

View file

@ -834,13 +834,13 @@
_Py_CODEUNIT *this_instr = next_instr - 4; _Py_CODEUNIT *this_instr = next_instr - 4;
(void)this_instr; (void)this_instr;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef func; _PyStackRef func;
_PyStackRef maybe_self; _PyStackRef *maybe_self;
_PyStackRef res; _PyStackRef res;
// _SPECIALIZE_CALL // _SPECIALIZE_CALL
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
uint16_t counter = read_u16(&this_instr[1].cache); uint16_t counter = read_u16(&this_instr[1].cache);
@ -848,7 +848,7 @@
#if ENABLE_SPECIALIZATION #if ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr; 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(); DISPATCH_SAME_OPARG();
} }
OPCODE_DEFERRED_INC(CALL); OPCODE_DEFERRED_INC(CALL);
@ -859,23 +859,18 @@
// _MAYBE_EXPAND_METHOD // _MAYBE_EXPAND_METHOD
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
{ {
args = &stack_pointer[-oparg]; maybe_self = &stack_pointer[-1 - oparg];
if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) { if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self = ((PyMethodObject *)callable_o)->im_self; PyObject *self = ((PyMethodObject *)callable_o)->im_self;
maybe_self = PyStackRef_FromPyObjectNew(self); maybe_self[0] = PyStackRef_FromPyObjectNew(self);
stack_pointer[-1 - oparg] = maybe_self;
PyObject *method = ((PyMethodObject *)callable_o)->im_func; PyObject *method = ((PyMethodObject *)callable_o)->im_func;
func = PyStackRef_FromPyObjectNew(method); func = PyStackRef_FromPyObjectNew(method);
stack_pointer[-2 - oparg] = func; 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); PyStackRef_CLOSE(callable);
} }
else { else {
func = callable; func = callable;
maybe_self = self_or_null;
} }
} }
// _DO_CALL // _DO_CALL
@ -885,7 +880,7 @@
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
// oparg counts all of the args, but *not* self: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1066,10 +1061,10 @@
INSTRUCTION_STATS(CALL_BOUND_METHOD_EXACT_ARGS); INSTRUCTION_STATS(CALL_BOUND_METHOD_EXACT_ARGS);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef null; _PyStackRef *null;
_PyStackRef func; _PyStackRef func;
_PyStackRef self; _PyStackRef *self;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
@ -1078,18 +1073,18 @@
DEOPT_IF(tstate->interp->eval_frame, CALL); DEOPT_IF(tstate->interp->eval_frame, CALL);
} }
// _CHECK_CALL_BOUND_METHOD_EXACT_ARGS // _CHECK_CALL_BOUND_METHOD_EXACT_ARGS
null = stack_pointer[-1 - oparg]; null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - 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); DEOPT_IF(Py_TYPE(PyStackRef_AsPyObjectBorrow(callable)) != &PyMethod_Type, CALL);
} }
// _INIT_CALL_BOUND_METHOD_EXACT_ARGS // _INIT_CALL_BOUND_METHOD_EXACT_ARGS
{ {
self = &stack_pointer[-1 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
stack_pointer[-1 - oparg] = self;
func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); func = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
stack_pointer[-2 - oparg] = func; stack_pointer[-2 - oparg] = func;
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
@ -1105,13 +1100,13 @@
DEOPT_IF(func->func_version != func_version, CALL); DEOPT_IF(func->func_version != func_version, CALL);
} }
// _CHECK_FUNCTION_EXACT_ARGS // _CHECK_FUNCTION_EXACT_ARGS
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyFunction_Check(callable_o)); assert(PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
PyCodeObject *code = (PyCodeObject *)func->func_code; 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 // _CHECK_STACK_SPACE
{ {
@ -1125,12 +1120,12 @@
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -1169,10 +1164,10 @@
INSTRUCTION_STATS(CALL_BOUND_METHOD_GENERAL); INSTRUCTION_STATS(CALL_BOUND_METHOD_GENERAL);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef null; _PyStackRef *null;
_PyStackRef method; _PyStackRef method;
_PyStackRef self; _PyStackRef *self;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
@ -1181,7 +1176,7 @@
DEOPT_IF(tstate->interp->eval_frame, CALL); DEOPT_IF(tstate->interp->eval_frame, CALL);
} }
// _CHECK_METHOD_VERSION // _CHECK_METHOD_VERSION
null = stack_pointer[-1 - oparg]; null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
uint32_t func_version = read_u32(&this_instr[2].cache); uint32_t func_version = read_u32(&this_instr[2].cache);
@ -1190,15 +1185,15 @@
PyObject *func = ((PyMethodObject *)callable_o)->im_func; PyObject *func = ((PyMethodObject *)callable_o)->im_func;
DEOPT_IF(!PyFunction_Check(func), CALL); DEOPT_IF(!PyFunction_Check(func), CALL);
DEOPT_IF(((PyFunctionObject *)func)->func_version != func_version, 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 // _EXPAND_METHOD
{ {
self = &stack_pointer[-1 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyStackRef_IsNull(null)); assert(PyStackRef_IsNull(null[0]));
assert(Py_TYPE(callable_o) == &PyMethod_Type); assert(Py_TYPE(callable_o) == &PyMethod_Type);
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
stack_pointer[-1 - oparg] = self;
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
stack_pointer[-2 - oparg] = method; stack_pointer[-2 - oparg] = method;
assert(PyStackRef_FunctionCheck(method)); assert(PyStackRef_FunctionCheck(method));
@ -1207,14 +1202,13 @@
// flush // flush
// _PY_FRAME_GENERAL // _PY_FRAME_GENERAL
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1265,19 +1259,19 @@
INSTRUCTION_STATS(CALL_BUILTIN_CLASS); INSTRUCTION_STATS(CALL_BUILTIN_CLASS);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_BUILTIN_CLASS // _CALL_BUILTIN_CLASS
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1288,7 +1282,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -1338,20 +1332,20 @@
INSTRUCTION_STATS(CALL_BUILTIN_FAST); INSTRUCTION_STATS(CALL_BUILTIN_FAST);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_BUILTIN_FAST // _CALL_BUILTIN_FAST
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
/* Builtin METH_FASTCALL functions, without keywords */ /* Builtin METH_FASTCALL functions, without keywords */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1363,7 +1357,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -1417,20 +1411,20 @@
INSTRUCTION_STATS(CALL_BUILTIN_FAST_WITH_KEYWORDS); INSTRUCTION_STATS(CALL_BUILTIN_FAST_WITH_KEYWORDS);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_BUILTIN_FAST_WITH_KEYWORDS // _CALL_BUILTIN_FAST_WITH_KEYWORDS
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
/* Builtin METH_FASTCALL | METH_KEYWORDS functions */ /* Builtin METH_FASTCALL | METH_KEYWORDS functions */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1444,7 +1438,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -1495,20 +1489,20 @@
INSTRUCTION_STATS(CALL_BUILTIN_O); INSTRUCTION_STATS(CALL_BUILTIN_O);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_BUILTIN_O // _CALL_BUILTIN_O
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
/* Builtin METH_O functions */ /* Builtin METH_O functions */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1711,18 +1705,18 @@
INSTRUCTION_STATS(CALL_ISINSTANCE); INSTRUCTION_STATS(CALL_ISINSTANCE);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
/* isinstance(o, o2) */ /* isinstance(o, o2) */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1755,12 +1749,12 @@
_Py_CODEUNIT *this_instr = next_instr - 4; _Py_CODEUNIT *this_instr = next_instr - 4;
(void)this_instr; (void)this_instr;
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef kwnames; _PyStackRef kwnames;
_PyStackRef res; _PyStackRef res;
// _SPECIALIZE_CALL_KW // _SPECIALIZE_CALL_KW
self_or_null = stack_pointer[-2 - oparg]; self_or_null = &stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg]; callable = stack_pointer[-3 - oparg];
{ {
uint16_t counter = read_u16(&this_instr[1].cache); uint16_t counter = read_u16(&this_instr[1].cache);
@ -1768,7 +1762,7 @@
#if ENABLE_SPECIALIZATION #if ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) { if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr; 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(); DISPATCH_SAME_OPARG();
} }
OPCODE_DEFERRED_INC(CALL_KW); OPCODE_DEFERRED_INC(CALL_KW);
@ -1781,15 +1775,14 @@
args = &stack_pointer[-1 - oparg]; args = &stack_pointer[-1 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames); PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
// oparg counts all of the args, but *not* self: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
if (self_or_null_o == NULL && Py_TYPE(callable_o) == &PyMethod_Type) { else if (Py_TYPE(callable_o) == &PyMethod_Type) {
args--; args--;
total_args++; total_args++;
PyObject *self = ((PyMethodObject *)callable_o)->im_self; PyObject *self = ((PyMethodObject *)callable_o)->im_self;
@ -1828,7 +1821,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -1886,11 +1879,11 @@
INSTRUCTION_STATS(CALL_KW_BOUND_METHOD); INSTRUCTION_STATS(CALL_KW_BOUND_METHOD);
static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef null; _PyStackRef *null;
_PyStackRef kwnames; _PyStackRef kwnames;
_PyStackRef method; _PyStackRef method;
_PyStackRef self; _PyStackRef *self;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
@ -1899,7 +1892,7 @@
DEOPT_IF(tstate->interp->eval_frame, CALL_KW); DEOPT_IF(tstate->interp->eval_frame, CALL_KW);
} }
// _CHECK_METHOD_VERSION_KW // _CHECK_METHOD_VERSION_KW
null = stack_pointer[-2 - oparg]; null = &stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg]; callable = stack_pointer[-3 - oparg];
{ {
uint32_t func_version = read_u32(&this_instr[2].cache); uint32_t func_version = read_u32(&this_instr[2].cache);
@ -1908,16 +1901,16 @@
PyObject *func = ((PyMethodObject *)callable_o)->im_func; PyObject *func = ((PyMethodObject *)callable_o)->im_func;
DEOPT_IF(!PyFunction_Check(func), CALL_KW); DEOPT_IF(!PyFunction_Check(func), CALL_KW);
DEOPT_IF(((PyFunctionObject *)func)->func_version != func_version, 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 // _EXPAND_METHOD_KW
kwnames = stack_pointer[-1]; kwnames = stack_pointer[-1];
{ {
self = &stack_pointer[-2 - oparg];
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyStackRef_IsNull(null)); assert(PyStackRef_IsNull(null[0]));
assert(Py_TYPE(callable_o) == &PyMethod_Type); assert(Py_TYPE(callable_o) == &PyMethod_Type);
self = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self); self[0] = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_self);
stack_pointer[-2 - oparg] = self;
method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func); method = PyStackRef_FromPyObjectNew(((PyMethodObject *)callable_o)->im_func);
stack_pointer[-3 - oparg] = method; stack_pointer[-3 - oparg] = method;
assert(PyStackRef_FunctionCheck(method)); assert(PyStackRef_FunctionCheck(method));
@ -1927,14 +1920,13 @@
// _PY_FRAME_KW // _PY_FRAME_KW
kwnames = stack_pointer[-1]; kwnames = stack_pointer[-1];
args = &stack_pointer[-1 - oparg]; args = &stack_pointer[-1 - oparg];
self_or_null = stack_pointer[-2 - oparg]; self_or_null = &stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg]; callable = stack_pointer[-3 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -1989,7 +1981,7 @@
static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef kwnames; _PyStackRef kwnames;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
@ -2004,15 +1996,14 @@
// _CALL_KW_NON_PY // _CALL_KW_NON_PY
kwnames = stack_pointer[-1]; kwnames = stack_pointer[-1];
args = &stack_pointer[-1 - oparg]; args = &stack_pointer[-1 - oparg];
self_or_null = stack_pointer[-2 - oparg]; self_or_null = &stack_pointer[-2 - oparg];
{ {
#if TIER_ONE #if TIER_ONE
assert(opcode != INSTRUMENTED_CALL); assert(opcode != INSTRUMENTED_CALL);
#endif #endif
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2020,7 +2011,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -2077,7 +2068,7 @@
INSTRUCTION_STATS(CALL_KW_PY); INSTRUCTION_STATS(CALL_KW_PY);
static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL_KW == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef kwnames; _PyStackRef kwnames;
_PyStackRef *args; _PyStackRef *args;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
@ -2098,13 +2089,12 @@
// _PY_FRAME_KW // _PY_FRAME_KW
kwnames = stack_pointer[-1]; kwnames = stack_pointer[-1];
args = &stack_pointer[-1 - oparg]; 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 *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
// oparg counts all of the args, but *not* self: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2158,18 +2148,18 @@
INSTRUCTION_STATS(CALL_LEN); INSTRUCTION_STATS(CALL_LEN);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
/* len(o) */ /* len(o) */
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2239,19 +2229,19 @@
INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST); INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_METHOD_DESCRIPTOR_FAST // _CALL_METHOD_DESCRIPTOR_FAST
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2269,7 +2259,7 @@
STACKREFS_TO_PYOBJECTS(args, nargs, args_o); STACKREFS_TO_PYOBJECTS(args, nargs, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -2320,19 +2310,19 @@
INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS // _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2350,7 +2340,7 @@
STACKREFS_TO_PYOBJECTS(args, nargs, args_o); STACKREFS_TO_PYOBJECTS(args, nargs, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -2401,20 +2391,20 @@
INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_NOARGS); INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_NOARGS);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_METHOD_DESCRIPTOR_NOARGS // _CALL_METHOD_DESCRIPTOR_NOARGS
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
assert(oparg == 0 || oparg == 1); assert(oparg == 0 || oparg == 1);
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2469,19 +2459,19 @@
INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_O); INSTRUCTION_STATS(CALL_METHOD_DESCRIPTOR_O);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
/* Skip 2 cache entries */ /* Skip 2 cache entries */
// _CALL_METHOD_DESCRIPTOR_O // _CALL_METHOD_DESCRIPTOR_O
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2540,7 +2530,7 @@
INSTRUCTION_STATS(CALL_NON_PY_GENERAL); INSTRUCTION_STATS(CALL_NON_PY_GENERAL);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef res; _PyStackRef res;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
@ -2554,15 +2544,14 @@
} }
// _CALL_NON_PY_GENERAL // _CALL_NON_PY_GENERAL
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
{ {
#if TIER_ONE #if TIER_ONE
assert(opcode != INSTRUMENTED_CALL); assert(opcode != INSTRUMENTED_CALL);
#endif #endif
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -2570,7 +2559,7 @@
STACKREFS_TO_PYOBJECTS(args, total_args, args_o); STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
if (CONVERSION_FAILED(args_o)) { if (CONVERSION_FAILED(args_o)) {
PyStackRef_CLOSE(callable); PyStackRef_CLOSE(callable);
PyStackRef_CLOSE(self_or_null); PyStackRef_CLOSE(self_or_null[0]);
for (int _i = oparg; --_i >= 0;) { for (int _i = oparg; --_i >= 0;) {
PyStackRef_CLOSE(args[_i]); PyStackRef_CLOSE(args[_i]);
} }
@ -2623,7 +2612,7 @@
INSTRUCTION_STATS(CALL_PY_EXACT_ARGS); INSTRUCTION_STATS(CALL_PY_EXACT_ARGS);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
@ -2641,13 +2630,13 @@
DEOPT_IF(func->func_version != func_version, CALL); DEOPT_IF(func->func_version != func_version, CALL);
} }
// _CHECK_FUNCTION_EXACT_ARGS // _CHECK_FUNCTION_EXACT_ARGS
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
assert(PyFunction_Check(callable_o)); assert(PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
PyCodeObject *code = (PyCodeObject *)func->func_code; 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 // _CHECK_STACK_SPACE
{ {
@ -2661,12 +2650,12 @@
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
{ {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); 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); STAT_INC(CALL, hit);
PyFunctionObject *func = (PyFunctionObject *)callable_o; PyFunctionObject *func = (PyFunctionObject *)callable_o;
new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame); new_frame = _PyFrame_PushUnchecked(tstate, func, oparg + has_self, frame);
_PyStackRef *first_non_self_local = new_frame->localsplus + has_self; _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++) { for (int i = 0; i < oparg; i++) {
first_non_self_local[i] = args[i]; first_non_self_local[i] = args[i];
} }
@ -2705,7 +2694,7 @@
INSTRUCTION_STATS(CALL_PY_GENERAL); INSTRUCTION_STATS(CALL_PY_GENERAL);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
/* Skip 1 cache entry */ /* Skip 1 cache entry */
@ -2724,13 +2713,12 @@
} }
// _PY_FRAME_GENERAL // _PY_FRAME_GENERAL
args = &stack_pointer[-oparg]; 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 *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
// oparg counts all of the args, but *not* self: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null_o != NULL) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }
@ -4050,43 +4038,38 @@
next_instr += 4; next_instr += 4;
INSTRUCTION_STATS(INSTRUMENTED_CALL); INSTRUCTION_STATS(INSTRUMENTED_CALL);
_PyStackRef callable; _PyStackRef callable;
_PyStackRef self_or_null; _PyStackRef *self_or_null;
_PyStackRef *args; _PyStackRef *args;
_PyStackRef func; _PyStackRef func;
_PyStackRef maybe_self; _PyStackRef *maybe_self;
_PyStackRef res; _PyStackRef res;
/* Skip 3 cache entries */ /* Skip 3 cache entries */
// _MAYBE_EXPAND_METHOD // _MAYBE_EXPAND_METHOD
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
self_or_null = stack_pointer[-1 - oparg]; self_or_null = &stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
args = &stack_pointer[-oparg]; maybe_self = &stack_pointer[-1 - oparg];
if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null)) { if (PyStackRef_TYPE(callable) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
PyObject *self = ((PyMethodObject *)callable_o)->im_self; PyObject *self = ((PyMethodObject *)callable_o)->im_self;
maybe_self = PyStackRef_FromPyObjectNew(self); maybe_self[0] = PyStackRef_FromPyObjectNew(self);
stack_pointer[-1 - oparg] = maybe_self;
PyObject *method = ((PyMethodObject *)callable_o)->im_func; PyObject *method = ((PyMethodObject *)callable_o)->im_func;
func = PyStackRef_FromPyObjectNew(method); func = PyStackRef_FromPyObjectNew(method);
stack_pointer[-2 - oparg] = func; 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); PyStackRef_CLOSE(callable);
} }
else { else {
func = callable; func = callable;
maybe_self = self_or_null;
} }
} }
// _MONITOR_CALL // _MONITOR_CALL
{ {
int is_meth = !PyStackRef_IsNull(maybe_self); int is_meth = !PyStackRef_IsNull(maybe_self[0]);
PyObject *function = PyStackRef_AsPyObjectBorrow(func); PyObject *function = PyStackRef_AsPyObjectBorrow(func);
PyObject *arg0; PyObject *arg0;
if (is_meth) { if (is_meth) {
arg0 = PyStackRef_AsPyObjectBorrow(maybe_self); arg0 = PyStackRef_AsPyObjectBorrow(maybe_self[0]);
} }
else if (oparg) { else if (oparg) {
arg0 = PyStackRef_AsPyObjectBorrow(args[0]); arg0 = PyStackRef_AsPyObjectBorrow(args[0]);
@ -4107,7 +4090,7 @@
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
// oparg counts all of the args, but *not* self: // oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (!PyStackRef_IsNull(self_or_null)) { if (!PyStackRef_IsNull(self_or_null[0])) {
args--; args--;
total_args++; total_args++;
} }

View file

@ -1686,11 +1686,13 @@
case _EXPAND_METHOD: { case _EXPAND_METHOD: {
_Py_UopsSymbol *method; _Py_UopsSymbol *method;
_Py_UopsSymbol *self; _Py_UopsSymbol **self;
self = &stack_pointer[-1 - oparg];
method = sym_new_not_null(ctx); 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[-2 - oparg] = method;
stack_pointer[-1 - oparg] = self;
break; break;
} }
@ -2045,13 +2047,15 @@
case _EXPAND_METHOD_KW: { case _EXPAND_METHOD_KW: {
_Py_UopsSymbol *method; _Py_UopsSymbol *method;
_Py_UopsSymbol *self; _Py_UopsSymbol **self;
_Py_UopsSymbol *kwnames; _Py_UopsSymbol *kwnames;
self = &stack_pointer[-2 - oparg];
method = sym_new_not_null(ctx); 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); kwnames = sym_new_not_null(ctx);
stack_pointer[-3 - oparg] = method; stack_pointer[-3 - oparg] = method;
stack_pointer[-2 - oparg] = self;
stack_pointer[-1] = kwnames; stack_pointer[-1] = kwnames;
break; break;
} }

View file

@ -165,6 +165,9 @@ class Emitter:
if var.name == "unused" or var.name == "null" or var.peek: if var.name == "unused" or var.name == "null" or var.peek:
continue continue
if var.size: if var.size:
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"for (int _i = {var.size}; --_i >= 0;) {{\n")
self.out.emit(f"PyStackRef_CLOSE({var.name}[_i]);\n") self.out.emit(f"PyStackRef_CLOSE({var.name}[_i]);\n")
self.out.emit("}\n") self.out.emit("}\n")

View file

@ -164,6 +164,8 @@ class StackOffset:
class StackError(Exception): class StackError(Exception):
pass pass
def array_or_scalar(var: StackItem | Local) -> str:
return "array" if var.is_array() else "scalar"
class Stack: class Stack:
def __init__(self) -> None: def __init__(self) -> None:
@ -177,10 +179,15 @@ class Stack:
indirect = "&" if var.is_array() else "" indirect = "&" if var.is_array() else ""
if self.variables: if self.variables:
popped = self.variables.pop() 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: if popped.size != var.size:
raise StackError( raise StackError(
f"Size mismatch when popping '{popped.name}' from stack to assign to {var.name}. " f"Size mismatch when popping '{popped.name}' from stack to assign to '{var.name}'. "
f"Expected {var.size} got {popped.size}" f"Expected {var_size(var)} got {var_size(popped.item)}"
) )
if var.name in UNUSED: if var.name in UNUSED:
if popped.name not in UNUSED and popped.name in self.defined: if popped.name not in UNUSED and popped.name in self.defined: