mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
gh-98831: Modernize CALL_FUNCTION_EX (#101627)
New generator feature: Move CHECK_EVAL_BREAKER() call to just before DISPATCH().
This commit is contained in:
parent
790ff6bc6a
commit
a9f01448a9
5 changed files with 41 additions and 37 deletions
|
@ -2951,26 +2951,21 @@ dummy_func(
|
|||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
|
||||
// error: CALL_FUNCTION_EX has irregular stack effect
|
||||
inst(CALL_FUNCTION_EX) {
|
||||
PyObject *func, *callargs, *kwargs = NULL, *result;
|
||||
if (oparg & 0x01) {
|
||||
kwargs = POP();
|
||||
inst(CALL_FUNCTION_EX, (unused, func, callargs, kwargs if (oparg & 1) -- result)) {
|
||||
if (oparg & 1) {
|
||||
// DICT_MERGE is called before this opcode if there are kwargs.
|
||||
// It converts all dict subtypes in kwargs into regular dicts.
|
||||
assert(PyDict_CheckExact(kwargs));
|
||||
}
|
||||
callargs = POP();
|
||||
func = TOP();
|
||||
if (!PyTuple_CheckExact(callargs)) {
|
||||
if (check_args_iterable(tstate, func, callargs) < 0) {
|
||||
Py_DECREF(callargs);
|
||||
goto error;
|
||||
}
|
||||
Py_SETREF(callargs, PySequence_Tuple(callargs));
|
||||
if (callargs == NULL) {
|
||||
PyObject *tuple = PySequence_Tuple(callargs);
|
||||
if (tuple == NULL) {
|
||||
goto error;
|
||||
}
|
||||
Py_SETREF(callargs, tuple);
|
||||
}
|
||||
assert(PyTuple_CheckExact(callargs));
|
||||
|
||||
|
@ -2979,12 +2974,8 @@ dummy_func(
|
|||
Py_DECREF(callargs);
|
||||
Py_XDECREF(kwargs);
|
||||
|
||||
STACK_SHRINK(1);
|
||||
assert(TOP() == NULL);
|
||||
SET_TOP(result);
|
||||
if (result == NULL) {
|
||||
goto error;
|
||||
}
|
||||
assert(PEEK(3 + (oparg & 1)) == NULL);
|
||||
ERROR_IF(result == NULL, error);
|
||||
CHECK_EVAL_BREAKER();
|
||||
}
|
||||
|
||||
|
|
27
Python/generated_cases.c.h
generated
27
Python/generated_cases.c.h
generated
|
@ -3587,24 +3587,24 @@
|
|||
|
||||
TARGET(CALL_FUNCTION_EX) {
|
||||
PREDICTED(CALL_FUNCTION_EX);
|
||||
PyObject *func, *callargs, *kwargs = NULL, *result;
|
||||
if (oparg & 0x01) {
|
||||
kwargs = POP();
|
||||
PyObject *kwargs = (oparg & 1) ? PEEK(((oparg & 1) ? 1 : 0)) : NULL;
|
||||
PyObject *callargs = PEEK(1 + ((oparg & 1) ? 1 : 0));
|
||||
PyObject *func = PEEK(2 + ((oparg & 1) ? 1 : 0));
|
||||
PyObject *result;
|
||||
if (oparg & 1) {
|
||||
// DICT_MERGE is called before this opcode if there are kwargs.
|
||||
// It converts all dict subtypes in kwargs into regular dicts.
|
||||
assert(PyDict_CheckExact(kwargs));
|
||||
}
|
||||
callargs = POP();
|
||||
func = TOP();
|
||||
if (!PyTuple_CheckExact(callargs)) {
|
||||
if (check_args_iterable(tstate, func, callargs) < 0) {
|
||||
Py_DECREF(callargs);
|
||||
goto error;
|
||||
}
|
||||
Py_SETREF(callargs, PySequence_Tuple(callargs));
|
||||
if (callargs == NULL) {
|
||||
PyObject *tuple = PySequence_Tuple(callargs);
|
||||
if (tuple == NULL) {
|
||||
goto error;
|
||||
}
|
||||
Py_SETREF(callargs, tuple);
|
||||
}
|
||||
assert(PyTuple_CheckExact(callargs));
|
||||
|
||||
|
@ -3613,12 +3613,11 @@
|
|||
Py_DECREF(callargs);
|
||||
Py_XDECREF(kwargs);
|
||||
|
||||
STACK_SHRINK(1);
|
||||
assert(TOP() == NULL);
|
||||
SET_TOP(result);
|
||||
if (result == NULL) {
|
||||
goto error;
|
||||
}
|
||||
assert(PEEK(3 + (oparg & 1)) == NULL);
|
||||
if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; }
|
||||
STACK_SHRINK(((oparg & 1) ? 1 : 0));
|
||||
STACK_SHRINK(2);
|
||||
POKE(1, result);
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST:
|
||||
return -1;
|
||||
case CALL_FUNCTION_EX:
|
||||
return -1;
|
||||
return ((oparg & 1) ? 1 : 0) + 3;
|
||||
case MAKE_FUNCTION:
|
||||
return ((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0) + 1;
|
||||
case RETURN_GENERATOR:
|
||||
|
@ -673,7 +673,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST:
|
||||
return -1;
|
||||
case CALL_FUNCTION_EX:
|
||||
return -1;
|
||||
return 1;
|
||||
case MAKE_FUNCTION:
|
||||
return 1;
|
||||
case RETURN_GENERATOR:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue