mirror of
https://github.com/python/cpython.git
synced 2025-07-09 20:35:26 +00:00
gh-109979: Auto-generate the target for DEOPT_IF() (#110193)
In Python/bytecodes.c, you now write ``` DEOPT_IF(condition); ``` The code generator expands this to ``` DEOPT_IF(condition, opcode); ``` where `opcode` is the name of the unspecialized instruction. This works inside macro expansions too. **CAVEAT:** The entire `DEOPT_IF(condition)` statement must be on a single line. If it isn't, the substitution will fail; an error will be printed by the code generator and the C compiler will report some errors.
This commit is contained in:
parent
d73501602f
commit
d67edcf0b3
8 changed files with 315 additions and 315 deletions
132
Python/generated_cases.c.h
generated
132
Python/generated_cases.c.h
generated
|
@ -32,8 +32,7 @@
|
|||
_Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING;
|
||||
#endif
|
||||
/* Possibly combine these two checks */
|
||||
DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version
|
||||
!= tstate->interp->monitoring_version, RESUME);
|
||||
DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version, RESUME);
|
||||
DEOPT_IF(_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker), RESUME);
|
||||
DISPATCH();
|
||||
}
|
||||
|
@ -391,8 +390,8 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_MULTIPLY_INT
|
||||
{
|
||||
|
@ -416,8 +415,8 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_ADD_INT
|
||||
{
|
||||
|
@ -441,8 +440,8 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_SUBTRACT_INT
|
||||
{
|
||||
|
@ -466,8 +465,8 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_MULTIPLY_FLOAT
|
||||
{
|
||||
|
@ -491,8 +490,8 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_ADD_FLOAT
|
||||
{
|
||||
|
@ -516,8 +515,8 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_SUBTRACT_FLOAT
|
||||
{
|
||||
|
@ -541,8 +540,8 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_ADD_UNICODE
|
||||
{
|
||||
|
@ -565,15 +564,15 @@
|
|||
right = stack_pointer[-1];
|
||||
left = stack_pointer[-2];
|
||||
{
|
||||
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
|
||||
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
|
||||
DEOPT_IF(!PyUnicode_CheckExact(right), BINARY_OP);
|
||||
}
|
||||
// _BINARY_OP_INPLACE_ADD_UNICODE
|
||||
{
|
||||
_Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP];
|
||||
assert(true_next.op.code == STORE_FAST);
|
||||
PyObject **target_local = &GETLOCAL(true_next.op.arg);
|
||||
DEOPT_IF(*target_local != left, BINARY_OP);
|
||||
DEOPT_IF(*target_local != left, BINARY_OP);
|
||||
STAT_INC(BINARY_OP, hit);
|
||||
/* Handle `left = left + right` or `left += right` for str.
|
||||
*
|
||||
|
@ -1294,8 +1293,7 @@
|
|||
receiver = stack_pointer[-2];
|
||||
DEOPT_IF(tstate->interp->eval_frame, SEND);
|
||||
PyGenObject *gen = (PyGenObject *)receiver;
|
||||
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type &&
|
||||
Py_TYPE(gen) != &PyCoro_Type, SEND);
|
||||
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND);
|
||||
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND);
|
||||
STAT_INC(SEND, hit);
|
||||
_PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
|
||||
|
@ -1806,8 +1804,8 @@
|
|||
{
|
||||
uint16_t version = read_u16(&next_instr[1].cache);
|
||||
PyDictObject *dict = (PyDictObject *)GLOBALS();
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
|
||||
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
|
||||
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
|
||||
assert(DK_IS_UNICODE(dict->ma_keys));
|
||||
}
|
||||
// _LOAD_GLOBAL_MODULE
|
||||
|
@ -1816,7 +1814,7 @@
|
|||
PyDictObject *dict = (PyDictObject *)GLOBALS();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
|
||||
res = entries[index].me_value;
|
||||
DEOPT_IF(res == NULL, LOAD_GLOBAL);
|
||||
DEOPT_IF(res == NULL, LOAD_GLOBAL);
|
||||
Py_INCREF(res);
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
null = NULL;
|
||||
|
@ -1836,16 +1834,16 @@
|
|||
{
|
||||
uint16_t version = read_u16(&next_instr[1].cache);
|
||||
PyDictObject *dict = (PyDictObject *)GLOBALS();
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
|
||||
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
|
||||
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
|
||||
assert(DK_IS_UNICODE(dict->ma_keys));
|
||||
}
|
||||
// _GUARD_BUILTINS_VERSION
|
||||
{
|
||||
uint16_t version = read_u16(&next_instr[2].cache);
|
||||
PyDictObject *dict = (PyDictObject *)BUILTINS();
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
|
||||
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
|
||||
DEOPT_IF(!PyDict_CheckExact(dict), LOAD_GLOBAL);
|
||||
DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
|
||||
assert(DK_IS_UNICODE(dict->ma_keys));
|
||||
}
|
||||
// _LOAD_GLOBAL_BUILTINS
|
||||
|
@ -1854,7 +1852,7 @@
|
|||
PyDictObject *bdict = (PyDictObject *)BUILTINS();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys);
|
||||
res = entries[index].me_value;
|
||||
DEOPT_IF(res == NULL, LOAD_GLOBAL);
|
||||
DEOPT_IF(res == NULL, LOAD_GLOBAL);
|
||||
Py_INCREF(res);
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
null = NULL;
|
||||
|
@ -2403,23 +2401,21 @@
|
|||
uint32_t type_version = read_u32(&next_instr[1].cache);
|
||||
PyTypeObject *tp = Py_TYPE(owner);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
}
|
||||
// _CHECK_MANAGED_OBJECT_HAS_VALUES
|
||||
{
|
||||
assert(Py_TYPE(owner)->tp_dictoffset < 0);
|
||||
assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||
PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) &&
|
||||
!_PyObject_MakeInstanceAttributesFromDict(owner, dorv),
|
||||
LOAD_ATTR);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
|
||||
}
|
||||
// _LOAD_ATTR_INSTANCE_VALUE
|
||||
{
|
||||
uint16_t index = read_u16(&next_instr[3].cache);
|
||||
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
|
||||
attr = _PyDictOrValues_GetValues(dorv)->values[index];
|
||||
DEOPT_IF(attr == NULL, LOAD_ATTR);
|
||||
DEOPT_IF(attr == NULL, LOAD_ATTR);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
Py_INCREF(attr);
|
||||
null = NULL;
|
||||
|
@ -2510,14 +2506,14 @@
|
|||
uint32_t type_version = read_u32(&next_instr[1].cache);
|
||||
PyTypeObject *tp = Py_TYPE(owner);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
}
|
||||
// _LOAD_ATTR_SLOT
|
||||
{
|
||||
uint16_t index = read_u16(&next_instr[3].cache);
|
||||
char *addr = (char *)owner + index;
|
||||
attr = *(PyObject **)addr;
|
||||
DEOPT_IF(attr == NULL, LOAD_ATTR);
|
||||
DEOPT_IF(attr == NULL, LOAD_ATTR);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
Py_INCREF(attr);
|
||||
null = NULL;
|
||||
|
@ -2539,8 +2535,7 @@
|
|||
PyObject *descr = read_obj(&next_instr[5].cache);
|
||||
|
||||
DEOPT_IF(!PyType_Check(owner), LOAD_ATTR);
|
||||
DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version,
|
||||
LOAD_ATTR);
|
||||
DEOPT_IF(((PyTypeObject *)owner)->tp_version_tag != type_version, LOAD_ATTR);
|
||||
assert(type_version != 0);
|
||||
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
|
@ -2627,13 +2622,13 @@
|
|||
uint32_t type_version = read_u32(&next_instr[1].cache);
|
||||
PyTypeObject *tp = Py_TYPE(owner);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
|
||||
}
|
||||
// _GUARD_DORV_VALUES
|
||||
{
|
||||
assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR);
|
||||
}
|
||||
// _STORE_ATTR_INSTANCE_VALUE
|
||||
value = stack_pointer[-2];
|
||||
|
@ -2716,7 +2711,7 @@
|
|||
uint32_t type_version = read_u32(&next_instr[1].cache);
|
||||
PyTypeObject *tp = Py_TYPE(owner);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
|
||||
}
|
||||
// _STORE_ATTR_SLOT
|
||||
value = stack_pointer[-2];
|
||||
|
@ -3297,7 +3292,7 @@
|
|||
// _ITER_CHECK_LIST
|
||||
iter = stack_pointer[-1];
|
||||
{
|
||||
DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
|
||||
DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
|
||||
}
|
||||
// _ITER_JUMP_LIST
|
||||
{
|
||||
|
@ -3339,7 +3334,7 @@
|
|||
// _ITER_CHECK_TUPLE
|
||||
iter = stack_pointer[-1];
|
||||
{
|
||||
DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER);
|
||||
DEOPT_IF(Py_TYPE(iter) != &PyTupleIter_Type, FOR_ITER);
|
||||
}
|
||||
// _ITER_JUMP_TUPLE
|
||||
{
|
||||
|
@ -3382,7 +3377,7 @@
|
|||
iter = stack_pointer[-1];
|
||||
{
|
||||
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
|
||||
DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
|
||||
DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
|
||||
}
|
||||
// _ITER_JUMP_RANGE
|
||||
{
|
||||
|
@ -3585,23 +3580,20 @@
|
|||
uint32_t type_version = read_u32(&next_instr[1].cache);
|
||||
PyTypeObject *tp = Py_TYPE(owner);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
}
|
||||
// _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT
|
||||
{
|
||||
assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||
PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) &&
|
||||
!_PyObject_MakeInstanceAttributesFromDict(owner, dorv),
|
||||
LOAD_ATTR);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
|
||||
}
|
||||
// _GUARD_KEYS_VERSION
|
||||
{
|
||||
uint32_t keys_version = read_u32(&next_instr[3].cache);
|
||||
PyTypeObject *owner_cls = Py_TYPE(owner);
|
||||
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
|
||||
DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version !=
|
||||
keys_version, LOAD_ATTR);
|
||||
DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
|
||||
}
|
||||
// _LOAD_ATTR_METHOD_WITH_VALUES
|
||||
{
|
||||
|
@ -3631,7 +3623,7 @@
|
|||
uint32_t type_version = read_u32(&next_instr[1].cache);
|
||||
PyTypeObject *tp = Py_TYPE(owner);
|
||||
assert(type_version != 0);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
|
||||
}
|
||||
// _LOAD_ATTR_METHOD_NO_DICT
|
||||
{
|
||||
|
@ -3664,12 +3656,9 @@
|
|||
DEOPT_IF(owner_cls->tp_version_tag != type_version, LOAD_ATTR);
|
||||
assert(owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||
PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) &&
|
||||
!_PyObject_MakeInstanceAttributesFromDict(owner, dorv),
|
||||
LOAD_ATTR);
|
||||
DEOPT_IF(!_PyDictOrValues_IsValues(*dorv) && !_PyObject_MakeInstanceAttributesFromDict(owner, dorv), LOAD_ATTR);
|
||||
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
|
||||
DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version !=
|
||||
keys_version, LOAD_ATTR);
|
||||
DEOPT_IF(owner_heap_type->ht_cached_keys->dk_version != keys_version, LOAD_ATTR);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
Py_DECREF(owner);
|
||||
|
@ -3845,14 +3834,14 @@
|
|||
_PyInterpreterFrame *new_frame;
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
}
|
||||
// _CHECK_CALL_BOUND_METHOD_EXACT_ARGS
|
||||
null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
{
|
||||
DEOPT_IF(null != NULL, CALL);
|
||||
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
|
||||
DEOPT_IF(null != NULL, CALL);
|
||||
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
|
||||
}
|
||||
// _INIT_CALL_BOUND_METHOD_EXACT_ARGS
|
||||
{
|
||||
|
@ -3868,18 +3857,18 @@
|
|||
callable = func;
|
||||
{
|
||||
uint32_t func_version = read_u32(&next_instr[1].cache);
|
||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
DEOPT_IF(func->func_version != func_version, CALL);
|
||||
DEOPT_IF(func->func_version != func_version, CALL);
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
||||
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
||||
}
|
||||
// _CHECK_STACK_SPACE
|
||||
{
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
|
||||
DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
|
||||
DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
|
||||
}
|
||||
// _INIT_CALL_PY_EXACT_ARGS
|
||||
args = stack_pointer - oparg;
|
||||
|
@ -3939,25 +3928,25 @@
|
|||
_PyInterpreterFrame *new_frame;
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
}
|
||||
// _CHECK_FUNCTION_EXACT_ARGS
|
||||
self_or_null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
{
|
||||
uint32_t func_version = read_u32(&next_instr[1].cache);
|
||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
DEOPT_IF(func->func_version != func_version, CALL);
|
||||
DEOPT_IF(func->func_version != func_version, CALL);
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
||||
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
||||
}
|
||||
// _CHECK_STACK_SPACE
|
||||
{
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
|
||||
DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
|
||||
DEOPT_IF(tstate->py_recursion_remaining <= 1, CALL);
|
||||
}
|
||||
// _INIT_CALL_PY_EXACT_ARGS
|
||||
args = stack_pointer - oparg;
|
||||
|
@ -4328,8 +4317,7 @@
|
|||
total_args++;
|
||||
}
|
||||
DEOPT_IF(!PyCFunction_CheckExact(callable), CALL);
|
||||
DEOPT_IF(PyCFunction_GET_FLAGS(callable) !=
|
||||
(METH_FASTCALL | METH_KEYWORDS), CALL);
|
||||
DEOPT_IF(PyCFunction_GET_FLAGS(callable) != (METH_FASTCALL | METH_KEYWORDS), CALL);
|
||||
STAT_INC(CALL, hit);
|
||||
/* res = func(self, args, nargs, kwnames) */
|
||||
_PyCFunctionFastWithKeywords cfunc =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue