mirror of
https://github.com/python/cpython.git
synced 2025-10-10 00:43:41 +00:00
GH-128682: Stronger checking of PyStackRef_CLOSE
and DEAD
. (GH-128683)
This commit is contained in:
parent
6ff8f82f92
commit
517dc65ffc
7 changed files with 224 additions and 127 deletions
6
Include/internal/pycore_opcode_metadata.h
generated
6
Include/internal/pycore_opcode_metadata.h
generated
|
@ -1985,7 +1985,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
|
||||||
[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||||
[BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
[BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||||
|
@ -2055,7 +2055,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
|
||||||
[DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[DICT_UPDATE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[END_ASYNC_FOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[END_FOR] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG },
|
[END_FOR] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG },
|
||||||
[END_SEND] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_PURE_FLAG },
|
[END_SEND] = { true, INSTR_FMT_IX, HAS_PURE_FLAG },
|
||||||
[ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
|
@ -2136,7 +2136,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
|
||||||
[LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[MAKE_CELL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[MAP_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
|
6
Include/internal/pycore_uop_metadata.h
generated
6
Include/internal/pycore_uop_metadata.h
generated
|
@ -56,7 +56,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_POP_TOP] = HAS_PURE_FLAG,
|
[_POP_TOP] = HAS_PURE_FLAG,
|
||||||
[_PUSH_NULL] = HAS_PURE_FLAG,
|
[_PUSH_NULL] = HAS_PURE_FLAG,
|
||||||
[_END_FOR] = HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG,
|
[_END_FOR] = HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG,
|
||||||
[_END_SEND] = HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
|
[_END_SEND] = HAS_PURE_FLAG,
|
||||||
[_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_UNARY_NEGATIVE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_UNARY_NOT] = HAS_PURE_FLAG,
|
[_UNARY_NOT] = HAS_PURE_FLAG,
|
||||||
[_TO_BOOL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_TO_BOOL] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
|
@ -81,7 +81,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
|
[_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
|
||||||
[_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG,
|
[_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG,
|
||||||
[_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
|
[_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
|
||||||
[_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG,
|
||||||
[_BINARY_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_BINARY_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_STORE_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
|
@ -146,7 +146,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_DICT_MERGE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_MAP_ADD] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_LOAD_SUPER_ATTR_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_LOAD_SUPER_ATTR_METHOD] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_LOAD_ATTR] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG,
|
[_GUARD_TYPE_VERSION] = HAS_EXIT_FLAG,
|
||||||
[_GUARD_TYPE_VERSION_AND_LOCK] = HAS_EXIT_FLAG,
|
[_GUARD_TYPE_VERSION_AND_LOCK] = HAS_EXIT_FLAG,
|
||||||
|
|
|
@ -1739,6 +1739,18 @@ class TestGeneratedCases(unittest.TestCase):
|
||||||
with self.assertRaises(SyntaxError):
|
with self.assertRaises(SyntaxError):
|
||||||
self.run_cases_test(input, "")
|
self.run_cases_test(input, "")
|
||||||
|
|
||||||
|
def test_kill_in_wrong_order(self):
|
||||||
|
input = """
|
||||||
|
inst(OP, (a, b -- c)) {
|
||||||
|
c = b;
|
||||||
|
PyStackRef_CLOSE(a);
|
||||||
|
PyStackRef_CLOSE(b);
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
with self.assertRaises(SyntaxError):
|
||||||
|
self.run_cases_test(input, "")
|
||||||
|
|
||||||
|
|
||||||
class TestGeneratedAbstractCases(unittest.TestCase):
|
class TestGeneratedAbstractCases(unittest.TestCase):
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
|
@ -384,7 +384,7 @@ dummy_func(
|
||||||
(void)receiver;
|
(void)receiver;
|
||||||
val = value;
|
val = value;
|
||||||
DEAD(value);
|
DEAD(value);
|
||||||
PyStackRef_CLOSE(receiver);
|
DECREF_INPUTS();
|
||||||
}
|
}
|
||||||
|
|
||||||
tier1 inst(INSTRUMENTED_END_SEND, (receiver, value -- val)) {
|
tier1 inst(INSTRUMENTED_END_SEND, (receiver, value -- val)) {
|
||||||
|
@ -681,8 +681,8 @@ dummy_func(
|
||||||
|
|
||||||
STAT_INC(BINARY_OP, hit);
|
STAT_INC(BINARY_OP, hit);
|
||||||
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
|
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
|
||||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
|
||||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
|
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
|
||||||
|
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
||||||
INPUTS_DEAD();
|
INPUTS_DEAD();
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
|
@ -725,7 +725,7 @@ dummy_func(
|
||||||
* that the string is safe to mutate.
|
* that the string is safe to mutate.
|
||||||
*/
|
*/
|
||||||
assert(Py_REFCNT(left_o) >= 2);
|
assert(Py_REFCNT(left_o) >= 2);
|
||||||
PyStackRef_CLOSE(left);
|
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
||||||
DEAD(left);
|
DEAD(left);
|
||||||
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
|
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
|
||||||
PyUnicode_Append(&temp, right_o);
|
PyUnicode_Append(&temp, right_o);
|
||||||
|
@ -822,8 +822,7 @@ dummy_func(
|
||||||
err = PyObject_SetItem(PyStackRef_AsPyObjectBorrow(container), slice, PyStackRef_AsPyObjectBorrow(v));
|
err = PyObject_SetItem(PyStackRef_AsPyObjectBorrow(container), slice, PyStackRef_AsPyObjectBorrow(v));
|
||||||
Py_DECREF(slice);
|
Py_DECREF(slice);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(v);
|
DECREF_INPUTS();
|
||||||
PyStackRef_CLOSE(container);
|
|
||||||
ERROR_IF(err, error);
|
ERROR_IF(err, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2082,11 +2081,8 @@ dummy_func(
|
||||||
int method_found = 0;
|
int method_found = 0;
|
||||||
PyObject *attr_o = _PySuper_Lookup(cls, self, name,
|
PyObject *attr_o = _PySuper_Lookup(cls, self, name,
|
||||||
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
||||||
PyStackRef_CLOSE(global_super_st);
|
|
||||||
PyStackRef_CLOSE(class_st);
|
|
||||||
if (attr_o == NULL) {
|
if (attr_o == NULL) {
|
||||||
PyStackRef_CLOSE(self_st);
|
ERROR_NO_POP();
|
||||||
ERROR_IF(true, error);
|
|
||||||
}
|
}
|
||||||
if (method_found) {
|
if (method_found) {
|
||||||
self_or_null = self_st; // transfer ownership
|
self_or_null = self_st; // transfer ownership
|
||||||
|
@ -2095,6 +2091,8 @@ dummy_func(
|
||||||
PyStackRef_CLOSE(self_st);
|
PyStackRef_CLOSE(self_st);
|
||||||
self_or_null = PyStackRef_NULL;
|
self_or_null = PyStackRef_NULL;
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(class_st);
|
||||||
|
PyStackRef_CLOSE(global_super_st);
|
||||||
|
|
||||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
}
|
}
|
||||||
|
@ -2920,7 +2918,6 @@ dummy_func(
|
||||||
else {
|
else {
|
||||||
/* `iterable` is not a generator. */
|
/* `iterable` is not a generator. */
|
||||||
PyObject *iter_o = PyObject_GetIter(iterable_o);
|
PyObject *iter_o = PyObject_GetIter(iterable_o);
|
||||||
DEAD(iterable);
|
|
||||||
if (iter_o == NULL) {
|
if (iter_o == NULL) {
|
||||||
ERROR_NO_POP();
|
ERROR_NO_POP();
|
||||||
}
|
}
|
||||||
|
@ -3466,11 +3463,11 @@ dummy_func(
|
||||||
/* Callable is not a normal Python function */
|
/* Callable is not a normal Python function */
|
||||||
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[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
DEAD(self_or_null);
|
DEAD(self_or_null);
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
ERROR_IF(true, error);
|
ERROR_IF(true, error);
|
||||||
}
|
}
|
||||||
PyObject *res_o = PyObject_Vectorcall(
|
PyObject *res_o = PyObject_Vectorcall(
|
||||||
|
@ -3496,11 +3493,11 @@ dummy_func(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
DEAD(self_or_null);
|
DEAD(self_or_null);
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
@ -3636,11 +3633,11 @@ dummy_func(
|
||||||
NULL);
|
NULL);
|
||||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
DEAD(self_or_null);
|
DEAD(self_or_null);
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
@ -3865,28 +3862,29 @@ dummy_func(
|
||||||
|
|
||||||
op(_CALL_BUILTIN_CLASS, (callable[1], self_or_null[1], args[oparg] -- res)) {
|
op(_CALL_BUILTIN_CLASS, (callable[1], self_or_null[1], args[oparg] -- res)) {
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
|
||||||
int total_args = oparg;
|
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
|
||||||
args--;
|
|
||||||
total_args++;
|
|
||||||
}
|
|
||||||
DEAD(self_or_null);
|
|
||||||
DEOPT_IF(!PyType_Check(callable_o));
|
DEOPT_IF(!PyType_Check(callable_o));
|
||||||
PyTypeObject *tp = (PyTypeObject *)callable_o;
|
PyTypeObject *tp = (PyTypeObject *)callable_o;
|
||||||
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
|
arguments--;
|
||||||
|
total_args++;
|
||||||
|
}
|
||||||
DEOPT_IF(tp->tp_vectorcall == NULL);
|
DEOPT_IF(tp->tp_vectorcall == NULL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
DECREF_INPUTS();
|
DECREF_INPUTS();
|
||||||
ERROR_IF(true, error);
|
ERROR_IF(true, error);
|
||||||
}
|
}
|
||||||
|
DEAD(self_or_null);
|
||||||
PyObject *res_o = tp->tp_vectorcall((PyObject *)tp, args_o, total_args, NULL);
|
PyObject *res_o = tp->tp_vectorcall((PyObject *)tp, args_o, total_args, NULL);
|
||||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
/* Free the arguments. */
|
/* Free the arguments. */
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(arguments[i]);
|
||||||
}
|
}
|
||||||
|
DEAD(args);
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
|
@ -3939,21 +3937,22 @@ dummy_func(
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
|
||||||
int total_args = oparg;
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
args--;
|
arguments--;
|
||||||
total_args++;
|
total_args++;
|
||||||
}
|
}
|
||||||
DEAD(self_or_null);
|
|
||||||
DEOPT_IF(!PyCFunction_CheckExact(callable_o));
|
DEOPT_IF(!PyCFunction_CheckExact(callable_o));
|
||||||
DEOPT_IF(PyCFunction_GET_FLAGS(callable_o) != METH_FASTCALL);
|
DEOPT_IF(PyCFunction_GET_FLAGS(callable_o) != METH_FASTCALL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o);
|
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o);
|
||||||
/* res = func(self, args, nargs) */
|
/* res = func(self, args, nargs) */
|
||||||
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
DECREF_INPUTS();
|
DECREF_INPUTS();
|
||||||
ERROR_IF(true, error);
|
ERROR_IF(true, error);
|
||||||
}
|
}
|
||||||
|
DEAD(self_or_null);
|
||||||
PyObject *res_o = ((PyCFunctionFast)(void(*)(void))cfunc)(
|
PyObject *res_o = ((PyCFunctionFast)(void(*)(void))cfunc)(
|
||||||
PyCFunction_GET_SELF(callable_o),
|
PyCFunction_GET_SELF(callable_o),
|
||||||
args_o,
|
args_o,
|
||||||
|
@ -3963,8 +3962,9 @@ dummy_func(
|
||||||
|
|
||||||
/* Free the arguments. */
|
/* Free the arguments. */
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(arguments[i]);
|
||||||
}
|
}
|
||||||
|
DEAD(args);
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
|
@ -4043,8 +4043,10 @@ dummy_func(
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
GOTO_ERROR(error);
|
GOTO_ERROR(error);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
PyStackRef_CLOSE(arg_stackref);
|
PyStackRef_CLOSE(arg_stackref);
|
||||||
|
DEAD(args);
|
||||||
|
DEAD(self_or_null);
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4053,25 +4055,24 @@ dummy_func(
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
|
|
||||||
int total_args = oparg;
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
args--;
|
arguments--;
|
||||||
total_args++;
|
total_args++;
|
||||||
}
|
}
|
||||||
DEOPT_IF(total_args != 2);
|
DEOPT_IF(total_args != 2);
|
||||||
PyInterpreterState *interp = tstate->interp;
|
PyInterpreterState *interp = tstate->interp;
|
||||||
DEOPT_IF(callable_o != interp->callable_cache.isinstance);
|
DEOPT_IF(callable_o != interp->callable_cache.isinstance);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
_PyStackRef cls_stackref = args[1];
|
_PyStackRef cls_stackref = arguments[1];
|
||||||
_PyStackRef inst_stackref = args[0];
|
_PyStackRef inst_stackref = arguments[0];
|
||||||
int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref));
|
int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref));
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
ERROR_NO_POP();
|
ERROR_NO_POP();
|
||||||
}
|
}
|
||||||
res = retval ? PyStackRef_True : PyStackRef_False;
|
res = retval ? PyStackRef_True : PyStackRef_False;
|
||||||
assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(inst_stackref);
|
DECREF_INPUTS();
|
||||||
PyStackRef_CLOSE(cls_stackref);
|
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is secretly a super-instruction
|
// This is secretly a super-instruction
|
||||||
|
@ -4370,11 +4371,11 @@ dummy_func(
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(kwnames);
|
PyStackRef_CLOSE(kwnames);
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
DEAD(self_or_null);
|
DEAD(self_or_null);
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
@ -4529,6 +4530,8 @@ dummy_func(
|
||||||
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||||
if (PyTuple_CheckExact(callargs_o)) {
|
if (PyTuple_CheckExact(callargs_o)) {
|
||||||
tuple = callargs;
|
tuple = callargs;
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
|
DEAD(kwargs_in);
|
||||||
DEAD(callargs);
|
DEAD(callargs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -4540,11 +4543,11 @@ dummy_func(
|
||||||
if (tuple_o == NULL) {
|
if (tuple_o == NULL) {
|
||||||
ERROR_NO_POP();
|
ERROR_NO_POP();
|
||||||
}
|
}
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
|
DEAD(kwargs_in);
|
||||||
PyStackRef_CLOSE(callargs);
|
PyStackRef_CLOSE(callargs);
|
||||||
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
||||||
}
|
}
|
||||||
kwargs_out = kwargs_in;
|
|
||||||
DEAD(kwargs_in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) {
|
op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) {
|
||||||
|
@ -4720,8 +4723,7 @@ dummy_func(
|
||||||
|
|
||||||
inst(FORMAT_WITH_SPEC, (value, fmt_spec -- res)) {
|
inst(FORMAT_WITH_SPEC, (value, fmt_spec -- res)) {
|
||||||
PyObject *res_o = PyObject_Format(PyStackRef_AsPyObjectBorrow(value), PyStackRef_AsPyObjectBorrow(fmt_spec));
|
PyObject *res_o = PyObject_Format(PyStackRef_AsPyObjectBorrow(value), PyStackRef_AsPyObjectBorrow(fmt_spec));
|
||||||
PyStackRef_CLOSE(value);
|
DECREF_INPUTS();
|
||||||
PyStackRef_CLOSE(fmt_spec);
|
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
|
67
Python/executor_cases.c.h
generated
67
Python/executor_cases.c.h
generated
|
@ -838,8 +838,8 @@
|
||||||
assert(PyUnicode_CheckExact(right_o));
|
assert(PyUnicode_CheckExact(right_o));
|
||||||
STAT_INC(BINARY_OP, hit);
|
STAT_INC(BINARY_OP, hit);
|
||||||
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
|
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
|
||||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
|
||||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
|
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
|
||||||
|
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
||||||
if (res_o == NULL) JUMP_TO_ERROR();
|
if (res_o == NULL) JUMP_TO_ERROR();
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
stack_pointer[-2] = res;
|
stack_pointer[-2] = res;
|
||||||
|
@ -882,7 +882,7 @@
|
||||||
* that the string is safe to mutate.
|
* that the string is safe to mutate.
|
||||||
*/
|
*/
|
||||||
assert(Py_REFCNT(left_o) >= 2);
|
assert(Py_REFCNT(left_o) >= 2);
|
||||||
PyStackRef_CLOSE(left);
|
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
||||||
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
|
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
|
||||||
PyUnicode_Append(&temp, right_o);
|
PyUnicode_Append(&temp, right_o);
|
||||||
*target_local = PyStackRef_FromPyObjectSteal(temp);
|
*target_local = PyStackRef_FromPyObjectSteal(temp);
|
||||||
|
@ -2529,11 +2529,8 @@
|
||||||
PyObject *attr_o = _PySuper_Lookup(cls, self, name,
|
PyObject *attr_o = _PySuper_Lookup(cls, self, name,
|
||||||
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
PyStackRef_CLOSE(global_super_st);
|
|
||||||
PyStackRef_CLOSE(class_st);
|
|
||||||
if (attr_o == NULL) {
|
if (attr_o == NULL) {
|
||||||
PyStackRef_CLOSE(self_st);
|
JUMP_TO_ERROR();
|
||||||
if (true) JUMP_TO_ERROR();
|
|
||||||
}
|
}
|
||||||
if (method_found) {
|
if (method_found) {
|
||||||
self_or_null = self_st; // transfer ownership
|
self_or_null = self_st; // transfer ownership
|
||||||
|
@ -2541,6 +2538,8 @@
|
||||||
PyStackRef_CLOSE(self_st);
|
PyStackRef_CLOSE(self_st);
|
||||||
self_or_null = PyStackRef_NULL;
|
self_or_null = PyStackRef_NULL;
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(class_st);
|
||||||
|
PyStackRef_CLOSE(global_super_st);
|
||||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
stack_pointer[-3] = attr;
|
stack_pointer[-3] = attr;
|
||||||
stack_pointer[-2] = self_or_null;
|
stack_pointer[-2] = self_or_null;
|
||||||
|
@ -4215,7 +4214,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -4229,10 +4228,10 @@
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) JUMP_TO_ERROR();
|
if (res_o == NULL) JUMP_TO_ERROR();
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
@ -4695,25 +4694,26 @@
|
||||||
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[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
int total_args = oparg;
|
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
|
||||||
args--;
|
|
||||||
total_args++;
|
|
||||||
}
|
|
||||||
if (!PyType_Check(callable_o)) {
|
if (!PyType_Check(callable_o)) {
|
||||||
UOP_STAT_INC(uopcode, miss);
|
UOP_STAT_INC(uopcode, miss);
|
||||||
JUMP_TO_JUMP_TARGET();
|
JUMP_TO_JUMP_TARGET();
|
||||||
}
|
}
|
||||||
PyTypeObject *tp = (PyTypeObject *)callable_o;
|
PyTypeObject *tp = (PyTypeObject *)callable_o;
|
||||||
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
|
arguments--;
|
||||||
|
total_args++;
|
||||||
|
}
|
||||||
if (tp->tp_vectorcall == NULL) {
|
if (tp->tp_vectorcall == NULL) {
|
||||||
UOP_STAT_INC(uopcode, miss);
|
UOP_STAT_INC(uopcode, miss);
|
||||||
JUMP_TO_JUMP_TARGET();
|
JUMP_TO_JUMP_TARGET();
|
||||||
}
|
}
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -4725,7 +4725,7 @@
|
||||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
/* Free the arguments. */
|
/* Free the arguments. */
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(arguments[i]);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) JUMP_TO_ERROR();
|
if (res_o == NULL) JUMP_TO_ERROR();
|
||||||
|
@ -4800,8 +4800,9 @@
|
||||||
/* Builtin METH_FASTCALL functions, without keywords */
|
/* Builtin METH_FASTCALL functions, without keywords */
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
int total_args = oparg;
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
args--;
|
arguments--;
|
||||||
total_args++;
|
total_args++;
|
||||||
}
|
}
|
||||||
if (!PyCFunction_CheckExact(callable_o)) {
|
if (!PyCFunction_CheckExact(callable_o)) {
|
||||||
|
@ -4815,10 +4816,10 @@
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o);
|
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o);
|
||||||
/* res = func(self, args, nargs) */
|
/* res = func(self, args, nargs) */
|
||||||
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -4834,7 +4835,7 @@
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
/* Free the arguments. */
|
/* Free the arguments. */
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(arguments[i]);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) JUMP_TO_ERROR();
|
if (res_o == NULL) JUMP_TO_ERROR();
|
||||||
|
@ -4879,7 +4880,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -4942,8 +4943,8 @@
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
GOTO_ERROR(error);
|
GOTO_ERROR(error);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
PyStackRef_CLOSE(arg_stackref);
|
PyStackRef_CLOSE(arg_stackref);
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
|
@ -4963,8 +4964,9 @@
|
||||||
/* isinstance(o, o2) */
|
/* isinstance(o, o2) */
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
int total_args = oparg;
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
args--;
|
arguments--;
|
||||||
total_args++;
|
total_args++;
|
||||||
}
|
}
|
||||||
if (total_args != 2) {
|
if (total_args != 2) {
|
||||||
|
@ -4977,8 +4979,8 @@
|
||||||
JUMP_TO_JUMP_TARGET();
|
JUMP_TO_JUMP_TARGET();
|
||||||
}
|
}
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
_PyStackRef cls_stackref = args[1];
|
_PyStackRef cls_stackref = arguments[1];
|
||||||
_PyStackRef inst_stackref = args[0];
|
_PyStackRef inst_stackref = arguments[0];
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref));
|
int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref));
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
@ -4987,9 +4989,11 @@
|
||||||
}
|
}
|
||||||
res = retval ? PyStackRef_True : PyStackRef_False;
|
res = retval ? PyStackRef_True : PyStackRef_False;
|
||||||
assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(inst_stackref);
|
|
||||||
PyStackRef_CLOSE(cls_stackref);
|
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
|
PyStackRef_CLOSE(args[_i]);
|
||||||
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -5136,7 +5140,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -5257,7 +5261,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -5467,7 +5471,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -5512,6 +5516,7 @@
|
||||||
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||||
if (PyTuple_CheckExact(callargs_o)) {
|
if (PyTuple_CheckExact(callargs_o)) {
|
||||||
tuple = callargs;
|
tuple = callargs;
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
@ -5526,10 +5531,10 @@
|
||||||
if (tuple_o == NULL) {
|
if (tuple_o == NULL) {
|
||||||
JUMP_TO_ERROR();
|
JUMP_TO_ERROR();
|
||||||
}
|
}
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
PyStackRef_CLOSE(callargs);
|
PyStackRef_CLOSE(callargs);
|
||||||
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
||||||
}
|
}
|
||||||
kwargs_out = kwargs_in;
|
|
||||||
stack_pointer[-1 - (oparg & 1)] = tuple;
|
stack_pointer[-1 - (oparg & 1)] = tuple;
|
||||||
if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
|
if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
|
||||||
break;
|
break;
|
||||||
|
|
79
Python/generated_cases.c.h
generated
79
Python/generated_cases.c.h
generated
|
@ -159,8 +159,8 @@
|
||||||
assert(PyUnicode_CheckExact(right_o));
|
assert(PyUnicode_CheckExact(right_o));
|
||||||
STAT_INC(BINARY_OP, hit);
|
STAT_INC(BINARY_OP, hit);
|
||||||
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
|
PyObject *res_o = PyUnicode_Concat(left_o, right_o);
|
||||||
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
|
||||||
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
|
PyStackRef_CLOSE_SPECIALIZED(right, _PyUnicode_ExactDealloc);
|
||||||
|
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
||||||
if (res_o == NULL) goto pop_2_error;
|
if (res_o == NULL) goto pop_2_error;
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@
|
||||||
* that the string is safe to mutate.
|
* that the string is safe to mutate.
|
||||||
*/
|
*/
|
||||||
assert(Py_REFCNT(left_o) >= 2);
|
assert(Py_REFCNT(left_o) >= 2);
|
||||||
PyStackRef_CLOSE(left);
|
PyStackRef_CLOSE_SPECIALIZED(left, _PyUnicode_ExactDealloc);
|
||||||
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
|
PyObject *temp = PyStackRef_AsPyObjectSteal(*target_local);
|
||||||
PyUnicode_Append(&temp, right_o);
|
PyUnicode_Append(&temp, right_o);
|
||||||
*target_local = PyStackRef_FromPyObjectSteal(temp);
|
*target_local = PyStackRef_FromPyObjectSteal(temp);
|
||||||
|
@ -962,10 +962,10 @@
|
||||||
/* Callable is not a normal Python function */
|
/* Callable is not a normal Python function */
|
||||||
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[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
{
|
{
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -1001,10 +1001,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -1351,19 +1351,20 @@
|
||||||
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[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
int total_args = oparg;
|
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
|
||||||
args--;
|
|
||||||
total_args++;
|
|
||||||
}
|
|
||||||
DEOPT_IF(!PyType_Check(callable_o), CALL);
|
DEOPT_IF(!PyType_Check(callable_o), CALL);
|
||||||
PyTypeObject *tp = (PyTypeObject *)callable_o;
|
PyTypeObject *tp = (PyTypeObject *)callable_o;
|
||||||
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
|
arguments--;
|
||||||
|
total_args++;
|
||||||
|
}
|
||||||
DEOPT_IF(tp->tp_vectorcall == NULL, CALL);
|
DEOPT_IF(tp->tp_vectorcall == NULL, CALL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -1379,7 +1380,7 @@
|
||||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
/* Free the arguments. */
|
/* Free the arguments. */
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(arguments[i]);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
|
@ -1430,8 +1431,9 @@
|
||||||
/* Builtin METH_FASTCALL functions, without keywords */
|
/* Builtin METH_FASTCALL functions, without keywords */
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
int total_args = oparg;
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
args--;
|
arguments--;
|
||||||
total_args++;
|
total_args++;
|
||||||
}
|
}
|
||||||
DEOPT_IF(!PyCFunction_CheckExact(callable_o), CALL);
|
DEOPT_IF(!PyCFunction_CheckExact(callable_o), CALL);
|
||||||
|
@ -1439,10 +1441,10 @@
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o);
|
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o);
|
||||||
/* res = func(self, args, nargs) */
|
/* res = func(self, args, nargs) */
|
||||||
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -1462,7 +1464,7 @@
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
/* Free the arguments. */
|
/* Free the arguments. */
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(arguments[i]);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
|
@ -1529,7 +1531,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -1670,6 +1672,7 @@
|
||||||
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||||
if (PyTuple_CheckExact(callargs_o)) {
|
if (PyTuple_CheckExact(callargs_o)) {
|
||||||
tuple = callargs;
|
tuple = callargs;
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
@ -1684,10 +1687,10 @@
|
||||||
if (tuple_o == NULL) {
|
if (tuple_o == NULL) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
kwargs_out = kwargs_in;
|
||||||
PyStackRef_CLOSE(callargs);
|
PyStackRef_CLOSE(callargs);
|
||||||
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
||||||
}
|
}
|
||||||
kwargs_out = kwargs_in;
|
|
||||||
}
|
}
|
||||||
// _DO_CALL_FUNCTION_EX
|
// _DO_CALL_FUNCTION_EX
|
||||||
{
|
{
|
||||||
|
@ -1872,16 +1875,17 @@
|
||||||
/* isinstance(o, o2) */
|
/* isinstance(o, o2) */
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||||
int total_args = oparg;
|
int total_args = oparg;
|
||||||
|
_PyStackRef *arguments = args;
|
||||||
if (!PyStackRef_IsNull(self_or_null[0])) {
|
if (!PyStackRef_IsNull(self_or_null[0])) {
|
||||||
args--;
|
arguments--;
|
||||||
total_args++;
|
total_args++;
|
||||||
}
|
}
|
||||||
DEOPT_IF(total_args != 2, CALL);
|
DEOPT_IF(total_args != 2, CALL);
|
||||||
PyInterpreterState *interp = tstate->interp;
|
PyInterpreterState *interp = tstate->interp;
|
||||||
DEOPT_IF(callable_o != interp->callable_cache.isinstance, CALL);
|
DEOPT_IF(callable_o != interp->callable_cache.isinstance, CALL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
_PyStackRef cls_stackref = args[1];
|
_PyStackRef cls_stackref = arguments[1];
|
||||||
_PyStackRef inst_stackref = args[0];
|
_PyStackRef inst_stackref = arguments[0];
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref));
|
int retval = PyObject_IsInstance(PyStackRef_AsPyObjectBorrow(inst_stackref), PyStackRef_AsPyObjectBorrow(cls_stackref));
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
|
@ -1890,9 +1894,11 @@
|
||||||
}
|
}
|
||||||
res = retval ? PyStackRef_True : PyStackRef_False;
|
res = retval ? PyStackRef_True : PyStackRef_False;
|
||||||
assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((!PyStackRef_IsNull(res)) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(inst_stackref);
|
|
||||||
PyStackRef_CLOSE(cls_stackref);
|
|
||||||
PyStackRef_CLOSE(callable[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
|
PyStackRef_CLOSE(args[_i]);
|
||||||
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -1997,7 +2003,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -2039,10 +2045,10 @@
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(kwnames);
|
PyStackRef_CLOSE(kwnames);
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
stack_pointer += -3 - oparg;
|
stack_pointer += -3 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -2198,7 +2204,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -2375,8 +2381,8 @@
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
GOTO_ERROR(error);
|
GOTO_ERROR(error);
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
PyStackRef_CLOSE(arg_stackref);
|
PyStackRef_CLOSE(arg_stackref);
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
|
@ -2456,7 +2462,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -2541,7 +2547,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -2774,7 +2780,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[0]);
|
PyStackRef_CLOSE(callable[0]);
|
||||||
PyStackRef_CLOSE(self_or_null[0]);
|
PyStackRef_XCLOSE(self_or_null[0]);
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
PyStackRef_CLOSE(args[_i]);
|
PyStackRef_CLOSE(args[_i]);
|
||||||
}
|
}
|
||||||
|
@ -2792,10 +2798,10 @@
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -4480,10 +4486,10 @@
|
||||||
/* Callable is not a normal Python function */
|
/* Callable is not a normal Python function */
|
||||||
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[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
{
|
{
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -4519,10 +4525,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable[0]);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
for (int i = 0; i < total_args; i++) {
|
||||||
PyStackRef_CLOSE(args[i]);
|
PyStackRef_CLOSE(args[i]);
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(callable[0]);
|
||||||
if (res_o == NULL) {
|
if (res_o == NULL) {
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
@ -6540,11 +6546,8 @@
|
||||||
PyObject *attr_o = _PySuper_Lookup(cls, self, name,
|
PyObject *attr_o = _PySuper_Lookup(cls, self, name,
|
||||||
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
PyStackRef_CLOSE(global_super_st);
|
|
||||||
PyStackRef_CLOSE(class_st);
|
|
||||||
if (attr_o == NULL) {
|
if (attr_o == NULL) {
|
||||||
PyStackRef_CLOSE(self_st);
|
goto error;
|
||||||
goto pop_3_error;
|
|
||||||
}
|
}
|
||||||
if (method_found) {
|
if (method_found) {
|
||||||
self_or_null = self_st; // transfer ownership
|
self_or_null = self_st; // transfer ownership
|
||||||
|
@ -6552,6 +6555,8 @@
|
||||||
PyStackRef_CLOSE(self_st);
|
PyStackRef_CLOSE(self_st);
|
||||||
self_or_null = PyStackRef_NULL;
|
self_or_null = PyStackRef_NULL;
|
||||||
}
|
}
|
||||||
|
PyStackRef_CLOSE(class_st);
|
||||||
|
PyStackRef_CLOSE(global_super_st);
|
||||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||||
stack_pointer[-3] = attr;
|
stack_pointer[-3] = attr;
|
||||||
stack_pointer[-2] = self_or_null;
|
stack_pointer[-2] = self_or_null;
|
||||||
|
|
|
@ -98,6 +98,11 @@ def always_true(tkn: Token | None) -> bool:
|
||||||
return False
|
return False
|
||||||
return tkn.text in {"true", "1"}
|
return tkn.text in {"true", "1"}
|
||||||
|
|
||||||
|
NON_ESCAPING_DEALLOCS = {
|
||||||
|
"_PyFloat_ExactDealloc",
|
||||||
|
"_PyLong_ExactDealloc",
|
||||||
|
"_PyUnicode_ExactDealloc",
|
||||||
|
}
|
||||||
|
|
||||||
class Emitter:
|
class Emitter:
|
||||||
out: CWriter
|
out: CWriter
|
||||||
|
@ -116,7 +121,7 @@ class Emitter:
|
||||||
"SAVE_STACK": self.save_stack,
|
"SAVE_STACK": self.save_stack,
|
||||||
"RELOAD_STACK": self.reload_stack,
|
"RELOAD_STACK": self.reload_stack,
|
||||||
"PyStackRef_CLOSE": self.stackref_close,
|
"PyStackRef_CLOSE": self.stackref_close,
|
||||||
"PyStackRef_CLOSE_SPECIALIZED": self.stackref_close,
|
"PyStackRef_CLOSE_SPECIALIZED": self.stackref_close_specialized,
|
||||||
"PyStackRef_AsPyObjectSteal": self.stackref_steal,
|
"PyStackRef_AsPyObjectSteal": self.stackref_steal,
|
||||||
"DISPATCH": self.dispatch,
|
"DISPATCH": self.dispatch,
|
||||||
"INSTRUCTION_SIZE": self.instruction_size,
|
"INSTRUCTION_SIZE": self.instruction_size,
|
||||||
|
@ -234,23 +239,26 @@ class Emitter:
|
||||||
next(tkn_iter)
|
next(tkn_iter)
|
||||||
next(tkn_iter)
|
next(tkn_iter)
|
||||||
self.out.emit_at("", tkn)
|
self.out.emit_at("", tkn)
|
||||||
for var in uop.stack.inputs:
|
for var in storage.inputs:
|
||||||
if var.name == "unused" or var.name == "null" or var.peek:
|
if not var.defined:
|
||||||
continue
|
continue
|
||||||
|
if var.name == "null":
|
||||||
|
continue
|
||||||
|
close = "PyStackRef_CLOSE"
|
||||||
|
if "null" in var.name or var.condition and var.condition != "1":
|
||||||
|
close = "PyStackRef_XCLOSE"
|
||||||
if var.size:
|
if var.size:
|
||||||
if var.size == "1":
|
if var.size == "1":
|
||||||
self.out.emit(f"PyStackRef_CLOSE({var.name}[0]);\n")
|
self.out.emit(f"{close}({var.name}[0]);\n")
|
||||||
else:
|
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"{close}({var.name}[_i]);\n")
|
||||||
self.out.emit("}\n")
|
self.out.emit("}\n")
|
||||||
elif var.condition:
|
elif var.condition:
|
||||||
if var.condition == "1":
|
if var.condition != "0":
|
||||||
self.out.emit(f"PyStackRef_CLOSE({var.name});\n")
|
self.out.emit(f"{close}({var.name});\n")
|
||||||
elif var.condition != "0":
|
|
||||||
self.out.emit(f"PyStackRef_XCLOSE({var.name});\n")
|
|
||||||
else:
|
else:
|
||||||
self.out.emit(f"PyStackRef_CLOSE({var.name});\n")
|
self.out.emit(f"{close}({var.name});\n")
|
||||||
for input in storage.inputs:
|
for input in storage.inputs:
|
||||||
input.defined = False
|
input.defined = False
|
||||||
return True
|
return True
|
||||||
|
@ -291,6 +299,25 @@ class Emitter:
|
||||||
raise analysis_error(f"'{name}' is not a live input-only variable", name_tkn)
|
raise analysis_error(f"'{name}' is not a live input-only variable", name_tkn)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def stackref_kill(
|
||||||
|
self,
|
||||||
|
name: Token,
|
||||||
|
storage: Storage,
|
||||||
|
escapes: bool
|
||||||
|
) -> bool:
|
||||||
|
live = ""
|
||||||
|
for var in reversed(storage.inputs):
|
||||||
|
if var.name == name.text:
|
||||||
|
if live and escapes:
|
||||||
|
raise analysis_error(
|
||||||
|
f"Cannot close '{name.text}' when "
|
||||||
|
f"'{live}' is still live", name)
|
||||||
|
var.defined = False
|
||||||
|
break
|
||||||
|
if var.defined:
|
||||||
|
live = var.name
|
||||||
|
return True
|
||||||
|
|
||||||
def stackref_close(
|
def stackref_close(
|
||||||
self,
|
self,
|
||||||
tkn: Token,
|
tkn: Token,
|
||||||
|
@ -306,14 +333,60 @@ class Emitter:
|
||||||
name = next(tkn_iter)
|
name = next(tkn_iter)
|
||||||
self.out.emit(name)
|
self.out.emit(name)
|
||||||
if name.kind == "IDENTIFIER":
|
if name.kind == "IDENTIFIER":
|
||||||
for var in storage.inputs:
|
return self.stackref_kill(name, storage, True)
|
||||||
if var.name == name.text:
|
|
||||||
var.defined = False
|
|
||||||
rparen = emit_to(self.out, tkn_iter, "RPAREN")
|
rparen = emit_to(self.out, tkn_iter, "RPAREN")
|
||||||
self.emit(rparen)
|
self.emit(rparen)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
stackref_steal = stackref_close
|
def stackref_close_specialized(
|
||||||
|
self,
|
||||||
|
tkn: Token,
|
||||||
|
tkn_iter: TokenIterator,
|
||||||
|
uop: Uop,
|
||||||
|
storage: Storage,
|
||||||
|
inst: Instruction | None,
|
||||||
|
) -> bool:
|
||||||
|
|
||||||
|
self.out.emit(tkn)
|
||||||
|
tkn = next(tkn_iter)
|
||||||
|
assert tkn.kind == "LPAREN"
|
||||||
|
self.out.emit(tkn)
|
||||||
|
name = next(tkn_iter)
|
||||||
|
self.out.emit(name)
|
||||||
|
comma = next(tkn_iter)
|
||||||
|
if comma.kind != "COMMA":
|
||||||
|
raise analysis_error("Expected comma", comma)
|
||||||
|
self.out.emit(comma)
|
||||||
|
dealloc = next(tkn_iter)
|
||||||
|
if dealloc.kind != "IDENTIFIER":
|
||||||
|
raise analysis_error("Expected identifier", dealloc)
|
||||||
|
self.out.emit(dealloc)
|
||||||
|
if name.kind == "IDENTIFIER":
|
||||||
|
escapes = dealloc.text not in NON_ESCAPING_DEALLOCS
|
||||||
|
return self.stackref_kill(name, storage, escapes)
|
||||||
|
rparen = emit_to(self.out, tkn_iter, "RPAREN")
|
||||||
|
self.emit(rparen)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def stackref_steal(
|
||||||
|
self,
|
||||||
|
tkn: Token,
|
||||||
|
tkn_iter: TokenIterator,
|
||||||
|
uop: Uop,
|
||||||
|
storage: Storage,
|
||||||
|
inst: Instruction | None,
|
||||||
|
) -> bool:
|
||||||
|
self.out.emit(tkn)
|
||||||
|
tkn = next(tkn_iter)
|
||||||
|
assert tkn.kind == "LPAREN"
|
||||||
|
self.out.emit(tkn)
|
||||||
|
name = next(tkn_iter)
|
||||||
|
self.out.emit(name)
|
||||||
|
if name.kind == "IDENTIFIER":
|
||||||
|
return self.stackref_kill(name, storage, False)
|
||||||
|
rparen = emit_to(self.out, tkn_iter, "RPAREN")
|
||||||
|
self.emit(rparen)
|
||||||
|
return True
|
||||||
|
|
||||||
def sync_sp(
|
def sync_sp(
|
||||||
self,
|
self,
|
||||||
|
@ -548,7 +621,7 @@ class Emitter:
|
||||||
storage.push_outputs()
|
storage.push_outputs()
|
||||||
self._print_storage(storage)
|
self._print_storage(storage)
|
||||||
except StackError as ex:
|
except StackError as ex:
|
||||||
raise analysis_error(ex.args[0], rbrace)
|
raise analysis_error(ex.args[0], rbrace) from None
|
||||||
return storage
|
return storage
|
||||||
|
|
||||||
def emit(self, txt: str | Token) -> None:
|
def emit(self, txt: str | Token) -> None:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue