GH-105848: Replace KW_NAMES + CALL with LOAD_CONST + CALL_KW (GH-109300)

This commit is contained in:
Brandt Bucher 2023-09-13 10:25:45 -07:00 committed by GitHub
parent 987b4bc087
commit 22e65eecaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 719 additions and 508 deletions

View File

@ -1122,7 +1122,8 @@ iterations of the loop.
This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the
correct name, the bytecode pushes the unbound method and ``STACK[-1]``. correct name, the bytecode pushes the unbound method and ``STACK[-1]``.
``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL` ``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL`
when calling the unbound method. Otherwise, ``NULL`` and the object returned by or :opcode:`CALL_KW` when calling the unbound method.
Otherwise, ``NULL`` and the object returned by
the attribute lookup are pushed. the attribute lookup are pushed.
.. versionchanged:: 3.12 .. versionchanged:: 3.12
@ -1390,25 +1391,14 @@ iterations of the loop.
.. opcode:: CALL (argc) .. opcode:: CALL (argc)
Calls a callable object with the number of arguments specified by ``argc``, Calls a callable object with the number of arguments specified by ``argc``.
including the named arguments specified by the preceding On the stack are (in ascending order):
:opcode:`KW_NAMES`, if any.
On the stack are (in ascending order), either:
* NULL
* The callable
* The positional arguments
* The named arguments
or:
* The callable * The callable
* ``self`` * ``self`` or ``NULL``
* The remaining positional arguments * The remaining positional arguments
* The named arguments
``argc`` is the total of the positional and named arguments, excluding ``argc`` is the total of the positional arguments, excluding ``self``.
``self`` when a ``NULL`` is not present.
``CALL`` pops all arguments and the callable object off the stack, ``CALL`` pops all arguments and the callable object off the stack,
calls the callable object with those arguments, and pushes the return value calls the callable object with those arguments, and pushes the return value
@ -1416,6 +1406,33 @@ iterations of the loop.
.. versionadded:: 3.11 .. versionadded:: 3.11
.. versionchanged:: 3.13
The callable now always appears at the same position on the stack.
.. versionchanged:: 3.13
Calls with keyword arguments are now handled by :opcode:`CALL_KW`.
.. opcode:: CALL_KW (argc)
Calls a callable object with the number of arguments specified by ``argc``,
including one or more named arguments. On the stack are (in ascending order):
* The callable
* ``self`` or ``NULL``
* The remaining positional arguments
* The named arguments
* A :class:`tuple` of keyword argument names
``argc`` is the total of the positional and named arguments, excluding ``self``.
The length of the tuple of keyword argument names is the number of named arguments.
``CALL_KW`` pops all arguments, the keyword names, and the callable object
off the stack, calls the callable object with those arguments, and pushes the
return value returned by the callable object.
.. versionadded:: 3.13
.. opcode:: CALL_FUNCTION_EX (flags) .. opcode:: CALL_FUNCTION_EX (flags)
@ -1441,15 +1458,6 @@ iterations of the loop.
.. versionadded:: 3.11 .. versionadded:: 3.11
.. opcode:: KW_NAMES (consti)
Prefixes :opcode:`CALL`.
Stores a reference to ``co_consts[consti]`` into an internal variable
for use by :opcode:`CALL`. ``co_consts[consti]`` must be a tuple of strings.
.. versionadded:: 3.11
.. opcode:: MAKE_FUNCTION .. opcode:: MAKE_FUNCTION
Pushes a new function object on the stack built from the code object at ``STACK[1]``. Pushes a new function object on the stack built from the code object at ``STACK[1]``.

View File

@ -253,7 +253,7 @@ extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container,
extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub,
_Py_CODEUNIT *instr); _Py_CODEUNIT *instr);
extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr,
int nargs, PyObject *kwnames); int nargs);
extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
int oparg, PyObject **locals); int oparg, PyObject **locals);
extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,

View File

@ -480,8 +480,6 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return 1; return 1;
case LOAD_ATTR_METHOD_LAZY_DICT: case LOAD_ATTR_METHOD_LAZY_DICT:
return 1; return 1;
case KW_NAMES:
return 0;
case INSTRUMENTED_CALL: case INSTRUMENTED_CALL:
return 0; return 0;
case CALL: case CALL:
@ -506,38 +504,42 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return oparg + 2; return oparg + 2;
case CALL_PY_WITH_DEFAULTS: case CALL_PY_WITH_DEFAULTS:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_TYPE_1: case CALL_TYPE_1:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_STR_1: case CALL_STR_1:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_TUPLE_1: case CALL_TUPLE_1:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_ALLOC_AND_ENTER_INIT: case CALL_ALLOC_AND_ENTER_INIT:
return oparg + 2; return oparg + 2;
case EXIT_INIT_CHECK: case EXIT_INIT_CHECK:
return 1; return 1;
case CALL_BUILTIN_CLASS: case CALL_BUILTIN_CLASS:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_BUILTIN_O: case CALL_BUILTIN_O:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_BUILTIN_FAST: case CALL_BUILTIN_FAST:
return oparg + 2; return oparg + 2;
case CALL_BUILTIN_FAST_WITH_KEYWORDS: case CALL_BUILTIN_FAST_WITH_KEYWORDS:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_LEN: case CALL_LEN:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_ISINSTANCE: case CALL_ISINSTANCE:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_LIST_APPEND: case CALL_LIST_APPEND:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_METHOD_DESCRIPTOR_O: case CALL_METHOD_DESCRIPTOR_O:
return oparg + 2; return oparg + 2;
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: case CALL_METHOD_DESCRIPTOR_NOARGS:
return oparg + 2; return oparg + 2;
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: case CALL_METHOD_DESCRIPTOR_FAST:
return oparg + 2; return oparg + 2;
case INSTRUMENTED_CALL_KW:
return 0;
case CALL_KW:
return oparg + 3;
case INSTRUMENTED_CALL_FUNCTION_EX: case INSTRUMENTED_CALL_FUNCTION_EX:
return 0; return 0;
case CALL_FUNCTION_EX: case CALL_FUNCTION_EX:
@ -1010,8 +1012,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 1; return 1;
case LOAD_ATTR_METHOD_LAZY_DICT: case LOAD_ATTR_METHOD_LAZY_DICT:
return 2; return 2;
case KW_NAMES:
return 0;
case INSTRUMENTED_CALL: case INSTRUMENTED_CALL:
return 0; return 0;
case CALL: case CALL:
@ -1036,37 +1036,41 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 1; return 1;
case CALL_PY_WITH_DEFAULTS: case CALL_PY_WITH_DEFAULTS:
return 1; return 1;
case CALL_NO_KW_TYPE_1: case CALL_TYPE_1:
return 1; return 1;
case CALL_NO_KW_STR_1: case CALL_STR_1:
return 1; return 1;
case CALL_NO_KW_TUPLE_1: case CALL_TUPLE_1:
return 1; return 1;
case CALL_NO_KW_ALLOC_AND_ENTER_INIT: case CALL_ALLOC_AND_ENTER_INIT:
return 1; return 1;
case EXIT_INIT_CHECK: case EXIT_INIT_CHECK:
return 0; return 0;
case CALL_BUILTIN_CLASS: case CALL_BUILTIN_CLASS:
return 1; return 1;
case CALL_NO_KW_BUILTIN_O: case CALL_BUILTIN_O:
return 1; return 1;
case CALL_NO_KW_BUILTIN_FAST: case CALL_BUILTIN_FAST:
return 1; return 1;
case CALL_BUILTIN_FAST_WITH_KEYWORDS: case CALL_BUILTIN_FAST_WITH_KEYWORDS:
return 1; return 1;
case CALL_NO_KW_LEN: case CALL_LEN:
return 1; return 1;
case CALL_NO_KW_ISINSTANCE: case CALL_ISINSTANCE:
return 1; return 1;
case CALL_NO_KW_LIST_APPEND: case CALL_LIST_APPEND:
return 1; return 1;
case CALL_NO_KW_METHOD_DESCRIPTOR_O: case CALL_METHOD_DESCRIPTOR_O:
return 1; return 1;
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
return 1; return 1;
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: case CALL_METHOD_DESCRIPTOR_NOARGS:
return 1; return 1;
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: case CALL_METHOD_DESCRIPTOR_FAST:
return 1;
case INSTRUMENTED_CALL_KW:
return 0;
case CALL_KW:
return 1; return 1;
case INSTRUMENTED_CALL_FUNCTION_EX: case INSTRUMENTED_CALL_FUNCTION_EX:
return 0; return 0;
@ -1405,7 +1409,6 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[KW_NAMES] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
[INSTRUMENTED_CALL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG }, [INSTRUMENTED_CALL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, [CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
@ -1418,22 +1421,24 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[CALL_NO_KW_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG }, [CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[CALL_NO_KW_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [EXIT_INIT_CHECK] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_BUILTIN_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_LEN] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_ISINSTANCE] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG }, [CALL_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG },
[INSTRUMENTED_CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
[CALL_KW] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
[INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, 0 }, [INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX, 0 },
[CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG }, [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
[MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [MAKE_FUNCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
@ -1581,17 +1586,20 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
[PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } }, [PUSH_EXC_INFO] = { .nuops = 1, .uops = { { PUSH_EXC_INFO, 0, 0 } } },
[CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 9, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } }, [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 9, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } },
[CALL_PY_EXACT_ARGS] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } }, [CALL_PY_EXACT_ARGS] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SET_IP, 7, 3 }, { _SAVE_CURRENT_IP, 0, 0 }, { _PUSH_FRAME, 0, 0 } } },
[CALL_NO_KW_TYPE_1] = { .nuops = 1, .uops = { { CALL_NO_KW_TYPE_1, 0, 0 } } }, [CALL_TYPE_1] = { .nuops = 1, .uops = { { CALL_TYPE_1, 0, 0 } } },
[CALL_NO_KW_STR_1] = { .nuops = 1, .uops = { { CALL_NO_KW_STR_1, 0, 0 } } }, [CALL_STR_1] = { .nuops = 1, .uops = { { CALL_STR_1, 0, 0 } } },
[CALL_NO_KW_TUPLE_1] = { .nuops = 1, .uops = { { CALL_NO_KW_TUPLE_1, 0, 0 } } }, [CALL_TUPLE_1] = { .nuops = 1, .uops = { { CALL_TUPLE_1, 0, 0 } } },
[EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { EXIT_INIT_CHECK, 0, 0 } } }, [EXIT_INIT_CHECK] = { .nuops = 1, .uops = { { EXIT_INIT_CHECK, 0, 0 } } },
[CALL_NO_KW_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_NO_KW_BUILTIN_O, 0, 0 } } }, [CALL_BUILTIN_CLASS] = { .nuops = 1, .uops = { { CALL_BUILTIN_CLASS, 0, 0 } } },
[CALL_NO_KW_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_NO_KW_BUILTIN_FAST, 0, 0 } } }, [CALL_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_BUILTIN_O, 0, 0 } } },
[CALL_NO_KW_LEN] = { .nuops = 1, .uops = { { CALL_NO_KW_LEN, 0, 0 } } }, [CALL_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST, 0, 0 } } },
[CALL_NO_KW_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_NO_KW_ISINSTANCE, 0, 0 } } }, [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 } } },
[CALL_NO_KW_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_O, 0, 0 } } }, [CALL_LEN] = { .nuops = 1, .uops = { { CALL_LEN, 0, 0 } } },
[CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } }, [CALL_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_ISINSTANCE, 0, 0 } } },
[CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_FAST, 0, 0 } } }, [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_O, 0, 0 } } },
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 } } },
[CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } },
[CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { CALL_METHOD_DESCRIPTOR_FAST, 0, 0 } } },
[MAKE_FUNCTION] = { .nuops = 1, .uops = { { MAKE_FUNCTION, 0, 0 } } }, [MAKE_FUNCTION] = { .nuops = 1, .uops = { { MAKE_FUNCTION, 0, 0 } } },
[SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { SET_FUNCTION_ATTRIBUTE, 0, 0 } } }, [SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { SET_FUNCTION_ATTRIBUTE, 0, 0 } } },
[BUILD_SLICE] = { .nuops = 1, .uops = { { BUILD_SLICE, 0, 0 } } }, [BUILD_SLICE] = { .nuops = 1, .uops = { { BUILD_SLICE, 0, 0 } } },
@ -1717,6 +1725,7 @@ const char *const _PyOpcode_OpName[268] = {
[CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX",
[CALL_INTRINSIC_1] = "CALL_INTRINSIC_1", [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1",
[CALL_INTRINSIC_2] = "CALL_INTRINSIC_2", [CALL_INTRINSIC_2] = "CALL_INTRINSIC_2",
[CALL_KW] = "CALL_KW",
[COMPARE_OP] = "COMPARE_OP", [COMPARE_OP] = "COMPARE_OP",
[CONTAINS_OP] = "CONTAINS_OP", [CONTAINS_OP] = "CONTAINS_OP",
[CONVERT_VALUE] = "CONVERT_VALUE", [CONVERT_VALUE] = "CONVERT_VALUE",
@ -1739,7 +1748,6 @@ const char *const _PyOpcode_OpName[268] = {
[JUMP_BACKWARD] = "JUMP_BACKWARD", [JUMP_BACKWARD] = "JUMP_BACKWARD",
[JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT", [JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT",
[JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_FORWARD] = "JUMP_FORWARD",
[KW_NAMES] = "KW_NAMES",
[LIST_APPEND] = "LIST_APPEND", [LIST_APPEND] = "LIST_APPEND",
[LIST_EXTEND] = "LIST_EXTEND", [LIST_EXTEND] = "LIST_EXTEND",
[LOAD_ATTR] = "LOAD_ATTR", [LOAD_ATTR] = "LOAD_ATTR",
@ -1791,24 +1799,24 @@ const char *const _PyOpcode_OpName[268] = {
[BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT", [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT",
[BINARY_SUBSCR_STR_INT] = "BINARY_SUBSCR_STR_INT", [BINARY_SUBSCR_STR_INT] = "BINARY_SUBSCR_STR_INT",
[BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT", [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT",
[CALL_ALLOC_AND_ENTER_INIT] = "CALL_ALLOC_AND_ENTER_INIT",
[CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS", [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
[CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS", [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
[CALL_BUILTIN_FAST] = "CALL_BUILTIN_FAST",
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS", [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
[CALL_BUILTIN_O] = "CALL_BUILTIN_O",
[CALL_ISINSTANCE] = "CALL_ISINSTANCE",
[CALL_LEN] = "CALL_LEN",
[CALL_LIST_APPEND] = "CALL_LIST_APPEND",
[CALL_METHOD_DESCRIPTOR_FAST] = "CALL_METHOD_DESCRIPTOR_FAST",
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
[CALL_NO_KW_ALLOC_AND_ENTER_INIT] = "CALL_NO_KW_ALLOC_AND_ENTER_INIT", [CALL_METHOD_DESCRIPTOR_NOARGS] = "CALL_METHOD_DESCRIPTOR_NOARGS",
[CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST", [CALL_METHOD_DESCRIPTOR_O] = "CALL_METHOD_DESCRIPTOR_O",
[CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O",
[CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE",
[CALL_NO_KW_LEN] = "CALL_NO_KW_LEN",
[CALL_NO_KW_LIST_APPEND] = "CALL_NO_KW_LIST_APPEND",
[CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "CALL_NO_KW_METHOD_DESCRIPTOR_FAST",
[CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
[CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O",
[CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1",
[CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1",
[CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1",
[CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
[CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS",
[CALL_STR_1] = "CALL_STR_1",
[CALL_TUPLE_1] = "CALL_TUPLE_1",
[CALL_TYPE_1] = "CALL_TYPE_1",
[COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT", [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT",
[COMPARE_OP_INT] = "COMPARE_OP_INT", [COMPARE_OP_INT] = "COMPARE_OP_INT",
[COMPARE_OP_STR] = "COMPARE_OP_STR", [COMPARE_OP_STR] = "COMPARE_OP_STR",
@ -1857,6 +1865,7 @@ const char *const _PyOpcode_OpName[268] = {
[INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR", [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR",
[INSTRUMENTED_FOR_ITER] = "INSTRUMENTED_FOR_ITER", [INSTRUMENTED_FOR_ITER] = "INSTRUMENTED_FOR_ITER",
[INSTRUMENTED_CALL] = "INSTRUMENTED_CALL", [INSTRUMENTED_CALL] = "INSTRUMENTED_CALL",
[INSTRUMENTED_CALL_KW] = "INSTRUMENTED_CALL_KW",
[INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX", [INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX",
[INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION", [INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION",
[INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD", [INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD",
@ -1935,27 +1944,28 @@ const uint8_t _PyOpcode_Deopt[256] = {
[BUILD_TUPLE] = BUILD_TUPLE, [BUILD_TUPLE] = BUILD_TUPLE,
[CACHE] = CACHE, [CACHE] = CACHE,
[CALL] = CALL, [CALL] = CALL,
[CALL_ALLOC_AND_ENTER_INIT] = CALL,
[CALL_BOUND_METHOD_EXACT_ARGS] = CALL, [CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
[CALL_BUILTIN_CLASS] = CALL, [CALL_BUILTIN_CLASS] = CALL,
[CALL_BUILTIN_FAST] = CALL,
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL, [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
[CALL_BUILTIN_O] = CALL,
[CALL_FUNCTION_EX] = CALL_FUNCTION_EX, [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
[CALL_INTRINSIC_1] = CALL_INTRINSIC_1, [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
[CALL_INTRINSIC_2] = CALL_INTRINSIC_2, [CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
[CALL_ISINSTANCE] = CALL,
[CALL_KW] = CALL_KW,
[CALL_LEN] = CALL,
[CALL_LIST_APPEND] = CALL,
[CALL_METHOD_DESCRIPTOR_FAST] = CALL,
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL, [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
[CALL_NO_KW_ALLOC_AND_ENTER_INIT] = CALL, [CALL_METHOD_DESCRIPTOR_NOARGS] = CALL,
[CALL_NO_KW_BUILTIN_FAST] = CALL, [CALL_METHOD_DESCRIPTOR_O] = CALL,
[CALL_NO_KW_BUILTIN_O] = CALL,
[CALL_NO_KW_ISINSTANCE] = CALL,
[CALL_NO_KW_LEN] = CALL,
[CALL_NO_KW_LIST_APPEND] = CALL,
[CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL,
[CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL,
[CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL,
[CALL_NO_KW_STR_1] = CALL,
[CALL_NO_KW_TUPLE_1] = CALL,
[CALL_NO_KW_TYPE_1] = CALL,
[CALL_PY_EXACT_ARGS] = CALL, [CALL_PY_EXACT_ARGS] = CALL,
[CALL_PY_WITH_DEFAULTS] = CALL, [CALL_PY_WITH_DEFAULTS] = CALL,
[CALL_STR_1] = CALL,
[CALL_TUPLE_1] = CALL,
[CALL_TYPE_1] = CALL,
[CHECK_EG_MATCH] = CHECK_EG_MATCH, [CHECK_EG_MATCH] = CHECK_EG_MATCH,
[CHECK_EXC_MATCH] = CHECK_EXC_MATCH, [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
[CLEANUP_THROW] = CLEANUP_THROW, [CLEANUP_THROW] = CLEANUP_THROW,
@ -1998,6 +2008,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[IMPORT_NAME] = IMPORT_NAME, [IMPORT_NAME] = IMPORT_NAME,
[INSTRUMENTED_CALL] = INSTRUMENTED_CALL, [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
[INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
[INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW,
[INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR, [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
[INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND, [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
[INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER, [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
@ -2019,7 +2030,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
[JUMP_BACKWARD] = JUMP_BACKWARD, [JUMP_BACKWARD] = JUMP_BACKWARD,
[JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
[JUMP_FORWARD] = JUMP_FORWARD, [JUMP_FORWARD] = JUMP_FORWARD,
[KW_NAMES] = KW_NAMES,
[LIST_APPEND] = LIST_APPEND, [LIST_APPEND] = LIST_APPEND,
[LIST_EXTEND] = LIST_EXTEND, [LIST_EXTEND] = LIST_EXTEND,
[LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
@ -2166,7 +2176,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 233: \ case 233: \
case 234: \ case 234: \
case 235: \ case 235: \
case 236: \
case 255: \ case 255: \
; ;

103
Include/opcode_ids.h generated
View File

@ -68,29 +68,29 @@ extern "C" {
#define CALL_FUNCTION_EX 54 #define CALL_FUNCTION_EX 54
#define CALL_INTRINSIC_1 55 #define CALL_INTRINSIC_1 55
#define CALL_INTRINSIC_2 56 #define CALL_INTRINSIC_2 56
#define COMPARE_OP 57 #define CALL_KW 57
#define CONTAINS_OP 58 #define COMPARE_OP 58
#define CONVERT_VALUE 59 #define CONTAINS_OP 59
#define COPY 60 #define CONVERT_VALUE 60
#define COPY_FREE_VARS 61 #define COPY 61
#define DELETE_ATTR 62 #define COPY_FREE_VARS 62
#define DELETE_DEREF 63 #define DELETE_ATTR 63
#define DELETE_FAST 64 #define DELETE_DEREF 64
#define DELETE_GLOBAL 65 #define DELETE_FAST 65
#define DELETE_NAME 66 #define DELETE_GLOBAL 66
#define DICT_MERGE 67 #define DELETE_NAME 67
#define DICT_UPDATE 68 #define DICT_MERGE 68
#define ENTER_EXECUTOR 69 #define DICT_UPDATE 69
#define EXTENDED_ARG 70 #define ENTER_EXECUTOR 70
#define FOR_ITER 71 #define EXTENDED_ARG 71
#define GET_AWAITABLE 72 #define FOR_ITER 72
#define IMPORT_FROM 73 #define GET_AWAITABLE 73
#define IMPORT_NAME 74 #define IMPORT_FROM 74
#define IS_OP 75 #define IMPORT_NAME 75
#define JUMP_BACKWARD 76 #define IS_OP 76
#define JUMP_BACKWARD_NO_INTERRUPT 77 #define JUMP_BACKWARD 77
#define JUMP_FORWARD 78 #define JUMP_BACKWARD_NO_INTERRUPT 78
#define KW_NAMES 79 #define JUMP_FORWARD 79
#define LIST_APPEND 80 #define LIST_APPEND 80
#define LIST_EXTEND 81 #define LIST_EXTEND 81
#define LOAD_ATTR 82 #define LOAD_ATTR 82
@ -143,24 +143,24 @@ extern "C" {
#define BINARY_SUBSCR_LIST_INT 159 #define BINARY_SUBSCR_LIST_INT 159
#define BINARY_SUBSCR_STR_INT 160 #define BINARY_SUBSCR_STR_INT 160
#define BINARY_SUBSCR_TUPLE_INT 161 #define BINARY_SUBSCR_TUPLE_INT 161
#define CALL_BOUND_METHOD_EXACT_ARGS 162 #define CALL_ALLOC_AND_ENTER_INIT 162
#define CALL_BUILTIN_CLASS 163 #define CALL_BOUND_METHOD_EXACT_ARGS 163
#define CALL_BUILTIN_FAST_WITH_KEYWORDS 164 #define CALL_BUILTIN_CLASS 164
#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 165 #define CALL_BUILTIN_FAST 165
#define CALL_NO_KW_ALLOC_AND_ENTER_INIT 166 #define CALL_BUILTIN_FAST_WITH_KEYWORDS 166
#define CALL_NO_KW_BUILTIN_FAST 167 #define CALL_BUILTIN_O 167
#define CALL_NO_KW_BUILTIN_O 168 #define CALL_ISINSTANCE 168
#define CALL_NO_KW_ISINSTANCE 169 #define CALL_LEN 169
#define CALL_NO_KW_LEN 170 #define CALL_LIST_APPEND 170
#define CALL_NO_KW_LIST_APPEND 171 #define CALL_METHOD_DESCRIPTOR_FAST 171
#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 172 #define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 172
#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 173 #define CALL_METHOD_DESCRIPTOR_NOARGS 173
#define CALL_NO_KW_METHOD_DESCRIPTOR_O 174 #define CALL_METHOD_DESCRIPTOR_O 174
#define CALL_NO_KW_STR_1 175 #define CALL_PY_EXACT_ARGS 175
#define CALL_NO_KW_TUPLE_1 176 #define CALL_PY_WITH_DEFAULTS 176
#define CALL_NO_KW_TYPE_1 177 #define CALL_STR_1 177
#define CALL_PY_EXACT_ARGS 178 #define CALL_TUPLE_1 178
#define CALL_PY_WITH_DEFAULTS 179 #define CALL_TYPE_1 179
#define COMPARE_OP_FLOAT 180 #define COMPARE_OP_FLOAT 180
#define COMPARE_OP_INT 181 #define COMPARE_OP_INT 181
#define COMPARE_OP_STR 182 #define COMPARE_OP_STR 182
@ -200,16 +200,17 @@ extern "C" {
#define UNPACK_SEQUENCE_LIST 216 #define UNPACK_SEQUENCE_LIST 216
#define UNPACK_SEQUENCE_TUPLE 217 #define UNPACK_SEQUENCE_TUPLE 217
#define UNPACK_SEQUENCE_TWO_TUPLE 218 #define UNPACK_SEQUENCE_TWO_TUPLE 218
#define MIN_INSTRUMENTED_OPCODE 237 #define MIN_INSTRUMENTED_OPCODE 236
#define INSTRUMENTED_RESUME 237 #define INSTRUMENTED_RESUME 236
#define INSTRUMENTED_END_FOR 238 #define INSTRUMENTED_END_FOR 237
#define INSTRUMENTED_END_SEND 239 #define INSTRUMENTED_END_SEND 238
#define INSTRUMENTED_RETURN_VALUE 240 #define INSTRUMENTED_RETURN_VALUE 239
#define INSTRUMENTED_RETURN_CONST 241 #define INSTRUMENTED_RETURN_CONST 240
#define INSTRUMENTED_YIELD_VALUE 242 #define INSTRUMENTED_YIELD_VALUE 241
#define INSTRUMENTED_LOAD_SUPER_ATTR 243 #define INSTRUMENTED_LOAD_SUPER_ATTR 242
#define INSTRUMENTED_FOR_ITER 244 #define INSTRUMENTED_FOR_ITER 243
#define INSTRUMENTED_CALL 245 #define INSTRUMENTED_CALL 244
#define INSTRUMENTED_CALL_KW 245
#define INSTRUMENTED_CALL_FUNCTION_EX 246 #define INSTRUMENTED_CALL_FUNCTION_EX 246
#define INSTRUMENTED_INSTRUCTION 247 #define INSTRUMENTED_INSTRUCTION 247
#define INSTRUMENTED_JUMP_FORWARD 248 #define INSTRUMENTED_JUMP_FORWARD 248

127
Lib/_opcode_metadata.py generated
View File

@ -85,21 +85,21 @@ _specializations = {
"CALL_BOUND_METHOD_EXACT_ARGS", "CALL_BOUND_METHOD_EXACT_ARGS",
"CALL_PY_EXACT_ARGS", "CALL_PY_EXACT_ARGS",
"CALL_PY_WITH_DEFAULTS", "CALL_PY_WITH_DEFAULTS",
"CALL_NO_KW_TYPE_1", "CALL_TYPE_1",
"CALL_NO_KW_STR_1", "CALL_STR_1",
"CALL_NO_KW_TUPLE_1", "CALL_TUPLE_1",
"CALL_BUILTIN_CLASS", "CALL_BUILTIN_CLASS",
"CALL_NO_KW_BUILTIN_O", "CALL_BUILTIN_O",
"CALL_NO_KW_BUILTIN_FAST", "CALL_BUILTIN_FAST",
"CALL_BUILTIN_FAST_WITH_KEYWORDS", "CALL_BUILTIN_FAST_WITH_KEYWORDS",
"CALL_NO_KW_LEN", "CALL_LEN",
"CALL_NO_KW_ISINSTANCE", "CALL_ISINSTANCE",
"CALL_NO_KW_LIST_APPEND", "CALL_LIST_APPEND",
"CALL_NO_KW_METHOD_DESCRIPTOR_O", "CALL_METHOD_DESCRIPTOR_O",
"CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
"CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", "CALL_METHOD_DESCRIPTOR_NOARGS",
"CALL_NO_KW_METHOD_DESCRIPTOR_FAST", "CALL_METHOD_DESCRIPTOR_FAST",
"CALL_NO_KW_ALLOC_AND_ENTER_INIT", "CALL_ALLOC_AND_ENTER_INIT",
], ],
} }
@ -120,24 +120,24 @@ _specialized_opmap = {
'BINARY_SUBSCR_LIST_INT': 159, 'BINARY_SUBSCR_LIST_INT': 159,
'BINARY_SUBSCR_STR_INT': 160, 'BINARY_SUBSCR_STR_INT': 160,
'BINARY_SUBSCR_TUPLE_INT': 161, 'BINARY_SUBSCR_TUPLE_INT': 161,
'CALL_BOUND_METHOD_EXACT_ARGS': 162, 'CALL_ALLOC_AND_ENTER_INIT': 162,
'CALL_BUILTIN_CLASS': 163, 'CALL_BOUND_METHOD_EXACT_ARGS': 163,
'CALL_BUILTIN_FAST_WITH_KEYWORDS': 164, 'CALL_BUILTIN_CLASS': 164,
'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 165, 'CALL_BUILTIN_FAST': 165,
'CALL_NO_KW_ALLOC_AND_ENTER_INIT': 166, 'CALL_BUILTIN_FAST_WITH_KEYWORDS': 166,
'CALL_NO_KW_BUILTIN_FAST': 167, 'CALL_BUILTIN_O': 167,
'CALL_NO_KW_BUILTIN_O': 168, 'CALL_ISINSTANCE': 168,
'CALL_NO_KW_ISINSTANCE': 169, 'CALL_LEN': 169,
'CALL_NO_KW_LEN': 170, 'CALL_LIST_APPEND': 170,
'CALL_NO_KW_LIST_APPEND': 171, 'CALL_METHOD_DESCRIPTOR_FAST': 171,
'CALL_NO_KW_METHOD_DESCRIPTOR_FAST': 172, 'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 172,
'CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS': 173, 'CALL_METHOD_DESCRIPTOR_NOARGS': 173,
'CALL_NO_KW_METHOD_DESCRIPTOR_O': 174, 'CALL_METHOD_DESCRIPTOR_O': 174,
'CALL_NO_KW_STR_1': 175, 'CALL_PY_EXACT_ARGS': 175,
'CALL_NO_KW_TUPLE_1': 176, 'CALL_PY_WITH_DEFAULTS': 176,
'CALL_NO_KW_TYPE_1': 177, 'CALL_STR_1': 177,
'CALL_PY_EXACT_ARGS': 178, 'CALL_TUPLE_1': 178,
'CALL_PY_WITH_DEFAULTS': 179, 'CALL_TYPE_1': 179,
'COMPARE_OP_FLOAT': 180, 'COMPARE_OP_FLOAT': 180,
'COMPARE_OP_INT': 181, 'COMPARE_OP_INT': 181,
'COMPARE_OP_STR': 182, 'COMPARE_OP_STR': 182,
@ -236,29 +236,29 @@ opmap = {
'CALL_FUNCTION_EX': 54, 'CALL_FUNCTION_EX': 54,
'CALL_INTRINSIC_1': 55, 'CALL_INTRINSIC_1': 55,
'CALL_INTRINSIC_2': 56, 'CALL_INTRINSIC_2': 56,
'COMPARE_OP': 57, 'CALL_KW': 57,
'CONTAINS_OP': 58, 'COMPARE_OP': 58,
'CONVERT_VALUE': 59, 'CONTAINS_OP': 59,
'COPY': 60, 'CONVERT_VALUE': 60,
'COPY_FREE_VARS': 61, 'COPY': 61,
'DELETE_ATTR': 62, 'COPY_FREE_VARS': 62,
'DELETE_DEREF': 63, 'DELETE_ATTR': 63,
'DELETE_FAST': 64, 'DELETE_DEREF': 64,
'DELETE_GLOBAL': 65, 'DELETE_FAST': 65,
'DELETE_NAME': 66, 'DELETE_GLOBAL': 66,
'DICT_MERGE': 67, 'DELETE_NAME': 67,
'DICT_UPDATE': 68, 'DICT_MERGE': 68,
'ENTER_EXECUTOR': 69, 'DICT_UPDATE': 69,
'EXTENDED_ARG': 70, 'ENTER_EXECUTOR': 70,
'FOR_ITER': 71, 'EXTENDED_ARG': 71,
'GET_AWAITABLE': 72, 'FOR_ITER': 72,
'IMPORT_FROM': 73, 'GET_AWAITABLE': 73,
'IMPORT_NAME': 74, 'IMPORT_FROM': 74,
'IS_OP': 75, 'IMPORT_NAME': 75,
'JUMP_BACKWARD': 76, 'IS_OP': 76,
'JUMP_BACKWARD_NO_INTERRUPT': 77, 'JUMP_BACKWARD': 77,
'JUMP_FORWARD': 78, 'JUMP_BACKWARD_NO_INTERRUPT': 78,
'KW_NAMES': 79, 'JUMP_FORWARD': 79,
'LIST_APPEND': 80, 'LIST_APPEND': 80,
'LIST_EXTEND': 81, 'LIST_EXTEND': 81,
'LOAD_ATTR': 82, 'LOAD_ATTR': 82,
@ -299,15 +299,16 @@ opmap = {
'UNPACK_SEQUENCE': 117, 'UNPACK_SEQUENCE': 117,
'YIELD_VALUE': 118, 'YIELD_VALUE': 118,
'RESUME': 149, 'RESUME': 149,
'INSTRUMENTED_RESUME': 237, 'INSTRUMENTED_RESUME': 236,
'INSTRUMENTED_END_FOR': 238, 'INSTRUMENTED_END_FOR': 237,
'INSTRUMENTED_END_SEND': 239, 'INSTRUMENTED_END_SEND': 238,
'INSTRUMENTED_RETURN_VALUE': 240, 'INSTRUMENTED_RETURN_VALUE': 239,
'INSTRUMENTED_RETURN_CONST': 241, 'INSTRUMENTED_RETURN_CONST': 240,
'INSTRUMENTED_YIELD_VALUE': 242, 'INSTRUMENTED_YIELD_VALUE': 241,
'INSTRUMENTED_LOAD_SUPER_ATTR': 243, 'INSTRUMENTED_LOAD_SUPER_ATTR': 242,
'INSTRUMENTED_FOR_ITER': 244, 'INSTRUMENTED_FOR_ITER': 243,
'INSTRUMENTED_CALL': 245, 'INSTRUMENTED_CALL': 244,
'INSTRUMENTED_CALL_KW': 245,
'INSTRUMENTED_CALL_FUNCTION_EX': 246, 'INSTRUMENTED_CALL_FUNCTION_EX': 246,
'INSTRUMENTED_INSTRUCTION': 247, 'INSTRUMENTED_INSTRUCTION': 247,
'INSTRUMENTED_JUMP_FORWARD': 248, 'INSTRUMENTED_JUMP_FORWARD': 248,
@ -330,5 +331,5 @@ opmap = {
'SETUP_WITH': 266, 'SETUP_WITH': 266,
'STORE_FAST_MAYBE_NULL': 267, 'STORE_FAST_MAYBE_NULL': 267,
} }
MIN_INSTRUMENTED_OPCODE = 237 MIN_INSTRUMENTED_OPCODE = 236
HAVE_ARGUMENT = 45 HAVE_ARGUMENT = 45

View File

@ -458,6 +458,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.13a1 3560 (Add RESUME_CHECK instruction) # Python 3.13a1 3560 (Add RESUME_CHECK instruction)
# Python 3.13a1 3561 (Add cache entry to branch instructions) # Python 3.13a1 3561 (Add cache entry to branch instructions)
# Python 3.13a1 3562 (Assign opcode IDs for internal ops in separate range) # Python 3.13a1 3562 (Assign opcode IDs for internal ops in separate range)
# Python 3.13a1 3563 (Add CALL_KW and remove KW_NAMES)
# Python 3.14 will start with 3600 # Python 3.14 will start with 3600
@ -474,7 +475,7 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated. # in PC/launcher.c must also be updated.
MAGIC_NUMBER = (3562).to_bytes(2, 'little') + b'\r\n' MAGIC_NUMBER = (3563).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

View File

@ -4757,24 +4757,24 @@ class ClassPropertiesAndMethods(unittest.TestCase):
thing = Thing() thing = Thing()
for i in range(20): for i in range(20):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
# PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS # CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS
list.sort(thing) list.sort(thing)
for i in range(20): for i in range(20):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
# PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS # CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS
str.split(thing) str.split(thing)
for i in range(20): for i in range(20):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
# PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS # CALL_METHOD_DESCRIPTOR_NOARGS
str.upper(thing) str.upper(thing)
for i in range(20): for i in range(20):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
# PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST # CALL_METHOD_DESCRIPTOR_FAST
str.strip(thing) str.strip(thing)
from collections import deque from collections import deque
for i in range(20): for i in range(20):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
# PRECALL_NO_KW_METHOD_DESCRIPTOR_O # CALL_METHOD_DESCRIPTOR_O
deque.append(thing, thing) deque.append(thing, thing)
def test_repr_as_str(self): def test_repr_as_str(self):

View File

@ -240,8 +240,8 @@ dis_kw_names = """\
LOAD_CONST 1 (1) LOAD_CONST 1 (1)
LOAD_CONST 2 (2) LOAD_CONST 2 (2)
LOAD_CONST 3 (5) LOAD_CONST 3 (5)
KW_NAMES 4 (('c',)) LOAD_CONST 4 (('c',))
CALL 3 CALL_KW 3
POP_TOP POP_TOP
RETURN_CONST 0 (None) RETURN_CONST 0 (None)
""" % (wrap_func_w_kwargs.__code__.co_firstlineno, """ % (wrap_func_w_kwargs.__code__.co_firstlineno,
@ -1003,7 +1003,7 @@ class DisTests(DisTestBase):
self.do_disassembly_test(bug46724, dis_bug46724) self.do_disassembly_test(bug46724, dis_bug46724)
def test_kw_names(self): def test_kw_names(self):
# Test that value is displayed for KW_NAMES # Test that value is displayed for keyword argument names:
self.do_disassembly_test(wrap_func_w_kwargs, dis_kw_names) self.do_disassembly_test(wrap_func_w_kwargs, dis_kw_names)
def test_intrinsic_1(self): def test_intrinsic_1(self):
@ -1256,7 +1256,7 @@ class DisTests(DisTestBase):
1 LOAD_NAME 0 (str) 1 LOAD_NAME 0 (str)
PUSH_NULL PUSH_NULL
LOAD_CONST 0 (1) LOAD_CONST 0 (1)
CALL_NO_KW_STR_1 1 CALL_STR_1 1
RETURN_VALUE RETURN_VALUE
""" """
co = compile("str(1)", "", "eval") co = compile("str(1)", "", "eval")
@ -1636,7 +1636,7 @@ def _prepare_test_cases():
result = result.replace(repr(code_object_inner), "code_object_inner") result = result.replace(repr(code_object_inner), "code_object_inner")
print(result) print(result)
# _prepare_test_cases() # from test.test_dis import _prepare_test_cases; _prepare_test_cases()
Instruction = dis.Instruction Instruction = dis.Instruction
@ -1668,7 +1668,7 @@ expected_opinfo_outer = [
] ]
expected_opinfo_f = [ expected_opinfo_f = [
Instruction(opname='COPY_FREE_VARS', opcode=61, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), Instruction(opname='COPY_FREE_VARS', opcode=62, arg=2, argval=2, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_CELL', opcode=94, arg=0, argval='c', argrepr='c', offset=2, start_offset=2, starts_line=False, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_CELL', opcode=94, arg=1, argval='d', argrepr='d', offset=4, start_offset=4, starts_line=False, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, is_jump_target=False, positions=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=6, start_offset=6, starts_line=True, line_number=2, is_jump_target=False, positions=None),
@ -1695,7 +1695,7 @@ expected_opinfo_f = [
] ]
expected_opinfo_inner = [ expected_opinfo_inner = [
Instruction(opname='COPY_FREE_VARS', opcode=61, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None), Instruction(opname='COPY_FREE_VARS', opcode=62, arg=4, argval=4, argrepr='', offset=0, start_offset=0, starts_line=True, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, is_jump_target=False, positions=None), Instruction(opname='RESUME', opcode=149, arg=0, argval=0, argrepr='', offset=2, start_offset=2, starts_line=True, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=1, argval='print', argrepr='print + NULL', offset=4, start_offset=4, starts_line=True, line_number=4, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=84, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, is_jump_target=False, positions=None), Instruction(opname='LOAD_DEREF', opcode=84, arg=2, argval='a', argrepr='a', offset=14, start_offset=14, starts_line=False, line_number=4, is_jump_target=False, positions=None),
@ -1714,7 +1714,7 @@ expected_opinfo_jumpy = [
Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, is_jump_target=False, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, is_jump_target=False, positions=None), Instruction(opname='GET_ITER', opcode=19, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='FOR_ITER', opcode=71, arg=30, argval=88, argrepr='to 88', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=True, positions=None), Instruction(opname='FOR_ITER', opcode=72, arg=30, argval=88, argrepr='to 88', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=True, positions=None),
Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, is_jump_target=False, positions=None), Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, is_jump_target=False, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, is_jump_target=False, positions=None),
@ -1722,16 +1722,16 @@ expected_opinfo_jumpy = [
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, is_jump_target=False, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=50, start_offset=50, starts_line=False, line_number=4, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, is_jump_target=False, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, is_jump_target=False, positions=None),
Instruction(opname='COMPARE_OP', opcode=57, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, is_jump_target=False, positions=None),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to 68', offset=60, start_offset=60, starts_line=False, line_number=5, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=68, argrepr='to 68', offset=60, start_offset=60, starts_line=False, line_number=5, is_jump_target=False, positions=None),
Instruction(opname='JUMP_BACKWARD', opcode=76, arg=22, argval=24, argrepr='to 24', offset=64, start_offset=64, starts_line=True, line_number=6, is_jump_target=False, positions=None), Instruction(opname='JUMP_BACKWARD', opcode=77, arg=22, argval=24, argrepr='to 24', offset=64, start_offset=64, starts_line=True, line_number=6, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, is_jump_target=True, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, is_jump_target=True, positions=None),
Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, is_jump_target=False, positions=None),
Instruction(opname='COMPARE_OP', opcode=57, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, is_jump_target=False, positions=None),
Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to 84', offset=76, start_offset=76, starts_line=False, line_number=7, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_TRUE', opcode=100, arg=2, argval=84, argrepr='to 84', offset=76, start_offset=76, starts_line=False, line_number=7, is_jump_target=False, positions=None),
Instruction(opname='JUMP_BACKWARD', opcode=76, arg=30, argval=24, argrepr='to 24', offset=80, start_offset=80, starts_line=False, line_number=7, is_jump_target=False, positions=None), Instruction(opname='JUMP_BACKWARD', opcode=77, arg=30, argval=24, argrepr='to 24', offset=80, start_offset=80, starts_line=False, line_number=7, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, is_jump_target=True, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, is_jump_target=True, positions=None),
Instruction(opname='JUMP_FORWARD', opcode=78, arg=12, argval=112, argrepr='to 112', offset=86, start_offset=86, starts_line=False, line_number=8, is_jump_target=False, positions=None), Instruction(opname='JUMP_FORWARD', opcode=79, arg=12, argval=112, argrepr='to 112', offset=86, start_offset=86, starts_line=False, line_number=8, is_jump_target=False, positions=None),
Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, is_jump_target=True, positions=None), Instruction(opname='END_FOR', opcode=11, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, is_jump_target=True, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, is_jump_target=False, positions=None),
@ -1750,18 +1750,18 @@ expected_opinfo_jumpy = [
Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=False, line_number=13, is_jump_target=False, positions=None), Instruction(opname='STORE_FAST', opcode=110, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=False, line_number=13, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, is_jump_target=False, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, is_jump_target=False, positions=None),
Instruction(opname='COMPARE_OP', opcode=57, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, is_jump_target=False, positions=None),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to 174', offset=166, start_offset=166, starts_line=False, line_number=14, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=174, argrepr='to 174', offset=166, start_offset=166, starts_line=False, line_number=14, is_jump_target=False, positions=None),
Instruction(opname='JUMP_BACKWARD', opcode=76, arg=31, argval=112, argrepr='to 112', offset=170, start_offset=170, starts_line=True, line_number=15, is_jump_target=False, positions=None), Instruction(opname='JUMP_BACKWARD', opcode=77, arg=31, argval=112, argrepr='to 112', offset=170, start_offset=170, starts_line=True, line_number=15, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, is_jump_target=True, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, is_jump_target=True, positions=None),
Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, is_jump_target=False, positions=None),
Instruction(opname='COMPARE_OP', opcode=57, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, is_jump_target=False, positions=None), Instruction(opname='COMPARE_OP', opcode=58, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, is_jump_target=False, positions=None),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to 188', offset=182, start_offset=182, starts_line=False, line_number=16, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=1, argval=188, argrepr='to 188', offset=182, start_offset=182, starts_line=False, line_number=16, is_jump_target=False, positions=None),
Instruction(opname='JUMP_FORWARD', opcode=78, arg=20, argval=228, argrepr='to 228', offset=186, start_offset=186, starts_line=True, line_number=17, is_jump_target=False, positions=None), Instruction(opname='JUMP_FORWARD', opcode=79, arg=20, argval=228, argrepr='to 228', offset=186, start_offset=186, starts_line=True, line_number=17, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, is_jump_target=True, positions=None), Instruction(opname='LOAD_FAST', opcode=85, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, is_jump_target=True, positions=None),
Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, is_jump_target=False, positions=None), Instruction(opname='TO_BOOL', opcode=40, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, is_jump_target=False, positions=None),
Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to 206', offset=198, start_offset=198, starts_line=False, line_number=11, is_jump_target=False, positions=None), Instruction(opname='POP_JUMP_IF_FALSE', opcode=97, arg=2, argval=206, argrepr='to 206', offset=198, start_offset=198, starts_line=False, line_number=11, is_jump_target=False, positions=None),
Instruction(opname='JUMP_BACKWARD', opcode=76, arg=40, argval=126, argrepr='to 126', offset=202, start_offset=202, starts_line=False, line_number=11, is_jump_target=False, positions=None), Instruction(opname='JUMP_BACKWARD', opcode=77, arg=40, argval=126, argrepr='to 126', offset=202, start_offset=202, starts_line=False, line_number=11, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, is_jump_target=True, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=91, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, is_jump_target=True, positions=None),
Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, is_jump_target=False, positions=None), Instruction(opname='LOAD_CONST', opcode=83, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, is_jump_target=False, positions=None),
Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, is_jump_target=False, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, is_jump_target=False, positions=None),
@ -1797,8 +1797,8 @@ expected_opinfo_jumpy = [
Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, is_jump_target=False, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, is_jump_target=False, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, is_jump_target=False, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, is_jump_target=False, positions=None),
Instruction(opname='JUMP_BACKWARD', opcode=76, arg=27, argval=284, argrepr='to 284', offset=334, start_offset=334, starts_line=False, line_number=25, is_jump_target=False, positions=None), Instruction(opname='JUMP_BACKWARD', opcode=77, arg=27, argval=284, argrepr='to 284', offset=334, start_offset=334, starts_line=False, line_number=25, is_jump_target=False, positions=None),
Instruction(opname='COPY', opcode=60, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, is_jump_target=False, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, is_jump_target=False, positions=None),
@ -1811,9 +1811,9 @@ expected_opinfo_jumpy = [
Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, is_jump_target=False, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, is_jump_target=False, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, is_jump_target=False, positions=None),
Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, is_jump_target=False, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, is_jump_target=False, positions=None),
Instruction(opname='JUMP_BACKWARD', opcode=76, arg=54, argval=284, argrepr='to 284', offset=388, start_offset=388, starts_line=False, line_number=23, is_jump_target=False, positions=None), Instruction(opname='JUMP_BACKWARD', opcode=77, arg=54, argval=284, argrepr='to 284', offset=388, start_offset=388, starts_line=False, line_number=23, is_jump_target=False, positions=None),
Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, is_jump_target=True, positions=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, is_jump_target=True, positions=None),
Instruction(opname='COPY', opcode=60, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, is_jump_target=False, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, is_jump_target=False, positions=None),
Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, is_jump_target=False, positions=None), Instruction(opname='PUSH_EXC_INFO', opcode=33, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, is_jump_target=False, positions=None),
@ -1822,7 +1822,7 @@ expected_opinfo_jumpy = [
Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, is_jump_target=False, positions=None),
Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, is_jump_target=False, positions=None),
Instruction(opname='COPY', opcode=60, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=28, is_jump_target=False, positions=None),
Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=28, is_jump_target=False, positions=None),
Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=28, is_jump_target=False, positions=None),
] ]

View File

@ -0,0 +1,3 @@
Add a new :opcode:`CALL_KW` opcode, used for calls containing keyword
arguments. Also, fix a possible crash when jumping over method calls in a
debugger.

View File

@ -411,10 +411,10 @@ mark_stacks(PyCodeObject *code_obj, int len)
case LOAD_GLOBAL: case LOAD_GLOBAL:
{ {
int j = oparg; int j = oparg;
next_stack = push_value(next_stack, Object);
if (j & 1) { if (j & 1) {
next_stack = push_value(next_stack, Null); next_stack = push_value(next_stack, Null);
} }
next_stack = push_value(next_stack, Object);
stacks[next_i] = next_stack; stacks[next_i] = next_stack;
break; break;
} }
@ -424,22 +424,12 @@ mark_stacks(PyCodeObject *code_obj, int len)
int j = oparg; int j = oparg;
if (j & 1) { if (j & 1) {
next_stack = pop_value(next_stack); next_stack = pop_value(next_stack);
next_stack = push_value(next_stack, Null);
next_stack = push_value(next_stack, Object); next_stack = push_value(next_stack, Object);
next_stack = push_value(next_stack, Null);
} }
stacks[next_i] = next_stack; stacks[next_i] = next_stack;
break; break;
} }
case CALL:
{
int args = oparg;
for (int j = 0; j < args+2; j++) {
next_stack = pop_value(next_stack);
}
next_stack = push_value(next_stack, Object);
stacks[next_i] = next_stack;
break;
}
case SWAP: case SWAP:
{ {
int n = oparg; int n = oparg;

View File

@ -2,16 +2,16 @@
unsigned char M_test_frozenmain[] = { unsigned char M_test_frozenmain[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,
0,0,0,0,0,243,164,0,0,0,149,0,83,0,83,1, 0,0,0,0,0,243,164,0,0,0,149,0,83,0,83,1,
74,0,114,0,83,0,83,1,74,1,114,1,92,2,34,0, 75,0,114,0,83,0,83,1,75,1,114,1,92,2,34,0,
83,2,53,1,0,0,0,0,0,0,32,0,92,2,34,0, 83,2,53,1,0,0,0,0,0,0,32,0,92,2,34,0,
83,3,92,0,82,6,0,0,0,0,0,0,0,0,0,0, 83,3,92,0,82,6,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,53,2,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,53,2,0,0,0,0,0,0,
32,0,92,1,82,8,0,0,0,0,0,0,0,0,0,0, 32,0,92,1,82,8,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,34,0,53,0,0,0,0,0, 0,0,0,0,0,0,0,0,34,0,53,0,0,0,0,0,
0,0,83,4,5,0,0,0,114,5,83,5,19,0,71,20, 0,0,83,4,5,0,0,0,114,5,83,5,19,0,72,20,
0,0,114,6,92,2,34,0,83,6,92,6,14,0,83,7, 0,0,114,6,92,2,34,0,83,6,92,6,14,0,83,7,
92,5,92,6,5,0,0,0,14,0,51,4,53,1,0,0, 92,5,92,6,5,0,0,0,14,0,51,4,53,1,0,0,
0,0,0,0,32,0,76,22,0,0,11,0,103,1,41,8, 0,0,0,0,32,0,77,22,0,0,11,0,103,1,41,8,
233,0,0,0,0,78,122,18,70,114,111,122,101,110,32,72, 233,0,0,0,0,78,122,18,70,114,111,122,101,110,32,72,
101,108,108,111,32,87,111,114,108,100,122,8,115,121,115,46, 101,108,108,111,32,87,111,114,108,100,122,8,115,121,115,46,
97,114,103,118,218,6,99,111,110,102,105,103,41,5,218,12, 97,114,103,118,218,6,99,111,110,102,105,103,41,5,218,12,

View File

@ -661,21 +661,21 @@
break; break;
} }
case CALL_NO_KW_TYPE_1: { case CALL_TYPE_1: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_STR_1: { case CALL_STR_1: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_TUPLE_1: { case CALL_TUPLE_1: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
@ -687,49 +687,70 @@
break; break;
} }
case CALL_NO_KW_BUILTIN_O: { case CALL_BUILTIN_CLASS: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_BUILTIN_FAST: { case CALL_BUILTIN_O: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_LEN: { case CALL_BUILTIN_FAST: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_ISINSTANCE: { case CALL_BUILTIN_FAST_WITH_KEYWORDS: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_METHOD_DESCRIPTOR_O: { case CALL_LEN: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: { case CALL_ISINSTANCE: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break; break;
} }
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: { case CALL_METHOD_DESCRIPTOR_O: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_METHOD_DESCRIPTOR_NOARGS: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_METHOD_DESCRIPTOR_FAST: {
STACK_SHRINK(oparg); STACK_SHRINK(oparg);
STACK_SHRINK(1); STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true); PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);

View File

@ -74,7 +74,6 @@ dummy_func(
unsigned int oparg, unsigned int oparg,
_Py_CODEUNIT *next_instr, _Py_CODEUNIT *next_instr,
PyObject **stack_pointer, PyObject **stack_pointer,
PyObject *kwnames,
int throwflag, int throwflag,
PyObject *args[] PyObject *args[]
) )
@ -2854,12 +2853,6 @@ dummy_func(
self = owner; self = owner;
} }
inst(KW_NAMES, (--)) {
ASSERT_KWNAMES_IS_NULL();
assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS));
kwnames = GETITEM(FRAME_CO_CONSTS, oparg);
}
inst(INSTRUMENTED_CALL, ( -- )) { inst(INSTRUMENTED_CALL, ( -- )) {
int is_meth = PEEK(oparg + 1) != NULL; int is_meth = PEEK(oparg + 1) != NULL;
int total_args = oparg + is_meth; int total_args = oparg + is_meth;
@ -2876,36 +2869,31 @@ dummy_func(
} }
// Cache layout: counter/1, func_version/2 // Cache layout: counter/1, func_version/2
// Neither CALL_INTRINSIC_1/2 nor CALL_FUNCTION_EX are members! // CALL_INTRINSIC_1/2, CALL_KW, and CALL_FUNCTION_EX aren't members!
family(CALL, INLINE_CACHE_ENTRIES_CALL) = { family(CALL, INLINE_CACHE_ENTRIES_CALL) = {
CALL_BOUND_METHOD_EXACT_ARGS, CALL_BOUND_METHOD_EXACT_ARGS,
CALL_PY_EXACT_ARGS, CALL_PY_EXACT_ARGS,
CALL_PY_WITH_DEFAULTS, CALL_PY_WITH_DEFAULTS,
CALL_NO_KW_TYPE_1, CALL_TYPE_1,
CALL_NO_KW_STR_1, CALL_STR_1,
CALL_NO_KW_TUPLE_1, CALL_TUPLE_1,
CALL_BUILTIN_CLASS, CALL_BUILTIN_CLASS,
CALL_NO_KW_BUILTIN_O, CALL_BUILTIN_O,
CALL_NO_KW_BUILTIN_FAST, CALL_BUILTIN_FAST,
CALL_BUILTIN_FAST_WITH_KEYWORDS, CALL_BUILTIN_FAST_WITH_KEYWORDS,
CALL_NO_KW_LEN, CALL_LEN,
CALL_NO_KW_ISINSTANCE, CALL_ISINSTANCE,
CALL_NO_KW_LIST_APPEND, CALL_LIST_APPEND,
CALL_NO_KW_METHOD_DESCRIPTOR_O, CALL_METHOD_DESCRIPTOR_O,
CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, CALL_METHOD_DESCRIPTOR_NOARGS,
CALL_NO_KW_METHOD_DESCRIPTOR_FAST, CALL_METHOD_DESCRIPTOR_FAST,
CALL_NO_KW_ALLOC_AND_ENTER_INIT, CALL_ALLOC_AND_ENTER_INIT,
}; };
// On entry, the stack is either
// [NULL, callable, arg1, arg2, ...]
// or
// [method, self, arg1, arg2, ...]
// (Some args may be keywords, see KW_NAMES, which sets 'kwnames'.)
// On exit, the stack is [result].
// When calling Python, inline the call using DISPATCH_INLINED(). // When calling Python, inline the call using DISPATCH_INLINED().
inst(CALL, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
// oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -2915,7 +2903,7 @@ dummy_func(
_PyCallCache *cache = (_PyCallCache *)next_instr; _PyCallCache *cache = (_PyCallCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
next_instr--; next_instr--;
_Py_Specialize_Call(callable, next_instr, total_args, kwnames); _Py_Specialize_Call(callable, next_instr, total_args);
DISPATCH_SAME_OPARG(); DISPATCH_SAME_OPARG();
} }
STAT_INC(CALL, deferred); STAT_INC(CALL, deferred);
@ -2931,7 +2919,6 @@ dummy_func(
Py_DECREF(callable); Py_DECREF(callable);
callable = method; callable = method;
} }
int positional_args = total_args - KWNAMES_LEN();
// Check if the call can be inlined or not // Check if the call can be inlined or not
if (Py_TYPE(callable) == &PyFunction_Type && if (Py_TYPE(callable) == &PyFunction_Type &&
tstate->interp->eval_frame == NULL && tstate->interp->eval_frame == NULL &&
@ -2941,9 +2928,8 @@ dummy_func(
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
tstate, (PyFunctionObject *)callable, locals, tstate, (PyFunctionObject *)callable, locals,
args, positional_args, kwnames args, total_args, NULL
); );
kwnames = NULL;
// Manipulate stack directly since we leave using DISPATCH_INLINED(). // Manipulate stack directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2); STACK_SHRINK(oparg + 2);
// The frame has stolen all the arguments from the stack, // The frame has stolen all the arguments from the stack,
@ -2958,8 +2944,8 @@ dummy_func(
/* Callable is not a normal Python function */ /* Callable is not a normal Python function */
res = PyObject_Vectorcall( res = PyObject_Vectorcall(
callable, args, callable, args,
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
kwnames); NULL);
if (opcode == INSTRUMENTED_CALL) { if (opcode == INSTRUMENTED_CALL) {
PyObject *arg = total_args == 0 ? PyObject *arg = total_args == 0 ?
&_PyInstrumentation_MISSING : args[0]; &_PyInstrumentation_MISSING : args[0];
@ -2977,7 +2963,6 @@ dummy_func(
} }
} }
} }
kwnames = NULL;
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable); Py_DECREF(callable);
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
@ -3006,7 +2991,6 @@ dummy_func(
} }
op(_CHECK_FUNCTION_EXACT_ARGS, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { op(_CHECK_FUNCTION_EXACT_ARGS, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL); DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable; PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL); DEOPT_IF(func->func_version != func_version, CALL);
@ -3081,7 +3065,6 @@ dummy_func(
_PUSH_FRAME; _PUSH_FRAME;
inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) { inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) {
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(tstate->interp->eval_frame, CALL); DEOPT_IF(tstate->interp->eval_frame, CALL);
int argcount = oparg; int argcount = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -3116,8 +3099,7 @@ dummy_func(
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
inst(CALL_NO_KW_TYPE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) { inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
PyObject *obj = args[0]; PyObject *obj = args[0];
@ -3128,8 +3110,7 @@ dummy_func(
Py_DECREF(&PyType_Type); // I.e., callable Py_DECREF(&PyType_Type); // I.e., callable
} }
inst(CALL_NO_KW_STR_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) { inst(CALL_STR_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
@ -3142,8 +3123,7 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(CALL_NO_KW_TUPLE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) { inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
@ -3156,13 +3136,12 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(CALL_NO_KW_ALLOC_AND_ENTER_INIT, (unused/1, unused/2, callable, null, args[oparg] -- unused)) { inst(CALL_ALLOC_AND_ENTER_INIT, (unused/1, unused/2, callable, null, args[oparg] -- unused)) {
/* This instruction does the following: /* This instruction does the following:
* 1. Creates the object (by calling ``object.__new__``) * 1. Creates the object (by calling ``object.__new__``)
* 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
* 3. Pushes the frame for ``__init__`` to the frame stack * 3. Pushes the frame for ``__init__`` to the frame stack
* */ * */
ASSERT_KWNAMES_IS_NULL();
_PyCallCache *cache = (_PyCallCache *)next_instr; _PyCallCache *cache = (_PyCallCache *)next_instr;
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(!PyType_Check(callable), CALL); DEOPT_IF(!PyType_Check(callable), CALL);
@ -3225,14 +3204,11 @@ dummy_func(
args--; args--;
total_args++; total_args++;
} }
int kwnames_len = KWNAMES_LEN();
DEOPT_IF(!PyType_Check(callable), CALL); DEOPT_IF(!PyType_Check(callable), CALL);
PyTypeObject *tp = (PyTypeObject *)callable; PyTypeObject *tp = (PyTypeObject *)callable;
DEOPT_IF(tp->tp_vectorcall == NULL, CALL); DEOPT_IF(tp->tp_vectorcall == NULL, CALL);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
res = tp->tp_vectorcall((PyObject *)tp, args, res = tp->tp_vectorcall((PyObject *)tp, args, total_args, NULL);
total_args - kwnames_len, kwnames);
kwnames = NULL;
/* Free the arguments. */ /* Free the arguments. */
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
Py_DECREF(args[i]); Py_DECREF(args[i]);
@ -3242,9 +3218,8 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(CALL_NO_KW_BUILTIN_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL_BUILTIN_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
/* Builtin METH_O functions */ /* Builtin METH_O functions */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -3271,9 +3246,8 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(CALL_NO_KW_BUILTIN_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL_BUILTIN_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
/* Builtin METH_FASTCALL functions, without keywords */ /* Builtin METH_FASTCALL functions, without keywords */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -3319,14 +3293,8 @@ dummy_func(
_PyCFunctionFastWithKeywords cfunc = _PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void)) (_PyCFunctionFastWithKeywords)(void(*)(void))
PyCFunction_GET_FUNCTION(callable); PyCFunction_GET_FUNCTION(callable);
res = cfunc( res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL);
PyCFunction_GET_SELF(callable),
args,
total_args - KWNAMES_LEN(),
kwnames
);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
kwnames = NULL;
/* Free the arguments. */ /* Free the arguments. */
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
@ -3337,8 +3305,7 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(CALL_NO_KW_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
/* len(o) */ /* len(o) */
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -3362,8 +3329,7 @@ dummy_func(
ERROR_IF(res == NULL, error); ERROR_IF(res == NULL, error);
} }
inst(CALL_NO_KW_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
/* isinstance(o, o2) */ /* isinstance(o, o2) */
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -3390,8 +3356,7 @@ dummy_func(
} }
// This is secretly a super-instruction // This is secretly a super-instruction
inst(CALL_NO_KW_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) { inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) {
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
PyInterpreterState *interp = tstate->interp; PyInterpreterState *interp = tstate->interp;
DEOPT_IF(callable != interp->callable_cache.list_append, CALL); DEOPT_IF(callable != interp->callable_cache.list_append, CALL);
@ -3410,8 +3375,7 @@ dummy_func(
DISPATCH(); DISPATCH();
} }
inst(CALL_NO_KW_METHOD_DESCRIPTOR_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL_METHOD_DESCRIPTOR_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -3459,9 +3423,8 @@ dummy_func(
int nargs = total_args - 1; int nargs = total_args - 1;
_PyCFunctionFastWithKeywords cfunc = _PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth;
res = cfunc(self, args + 1, nargs - KWNAMES_LEN(), kwnames); res = cfunc(self, args + 1, nargs, NULL);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
kwnames = NULL;
/* Free the arguments. */ /* Free the arguments. */
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
@ -3472,8 +3435,7 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 0 || oparg == 1); assert(oparg == 0 || oparg == 1);
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -3503,8 +3465,7 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(CALL_NO_KW_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { inst(CALL_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -3532,6 +3493,91 @@ dummy_func(
CHECK_EVAL_BREAKER(); CHECK_EVAL_BREAKER();
} }
inst(INSTRUMENTED_CALL_KW, ( -- )) {
int is_meth = PEEK(oparg + 2) != NULL;
int total_args = oparg + is_meth;
PyObject *function = PEEK(oparg + 3);
PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING
: PEEK(total_args + 1);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
frame, next_instr - 1, function, arg);
ERROR_IF(err, error);
GO_TO_INSTRUCTION(CALL_KW);
}
inst(CALL_KW, (callable, self_or_null, args[oparg], kwnames -- res)) {
// oparg counts all of the args, but *not* self:
int total_args = oparg;
if (self_or_null != NULL) {
args--;
total_args++;
}
if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) {
args--;
total_args++;
PyObject *self = ((PyMethodObject *)callable)->im_self;
args[0] = Py_NewRef(self);
PyObject *method = ((PyMethodObject *)callable)->im_func;
args[-1] = Py_NewRef(method);
Py_DECREF(callable);
callable = method;
}
int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames);
// Check if the call can be inlined or not
if (Py_TYPE(callable) == &PyFunction_Type &&
tstate->interp->eval_frame == NULL &&
((PyFunctionObject *)callable)->vectorcall == _PyFunction_Vectorcall)
{
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags;
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
tstate, (PyFunctionObject *)callable, locals,
args, positional_args, kwnames
);
Py_DECREF(kwnames);
// Manipulate stack directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 3);
// The frame has stolen all the arguments from the stack,
// so there is no need to clean them up.
if (new_frame == NULL) {
goto error;
}
frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}
/* Callable is not a normal Python function */
res = PyObject_Vectorcall(
callable, args,
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
kwnames);
if (opcode == INSTRUMENTED_CALL_KW) {
PyObject *arg = total_args == 0 ?
&_PyInstrumentation_MISSING : args[0];
if (res == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
frame, next_instr-1, callable, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
frame, next_instr-1, callable, arg);
if (err < 0) {
Py_CLEAR(res);
}
}
}
Py_DECREF(kwnames);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable);
for (int i = 0; i < total_args; i++) {
Py_DECREF(args[i]);
}
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) { inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) {
GO_TO_INSTRUCTION(CALL_FUNCTION_EX); GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
} }

View File

@ -678,7 +678,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
#endif #endif
_PyInterpreterFrame entry_frame; _PyInterpreterFrame entry_frame;
PyObject *kwnames = NULL; // Borrowed reference. Reset by CALL instructions.
@ -840,7 +839,6 @@ pop_2_error:
pop_1_error: pop_1_error:
STACK_SHRINK(1); STACK_SHRINK(1);
error: error:
kwnames = NULL;
/* Double-check exception status. */ /* Double-check exception status. */
#ifdef NDEBUG #ifdef NDEBUG
if (!_PyErr_Occurred(tstate)) { if (!_PyErr_Occurred(tstate)) {

View File

@ -311,9 +311,6 @@ GETITEM(PyObject *v, Py_ssize_t i) {
" in enclosing scope" " in enclosing scope"
#define NAME_ERROR_MSG "name '%.200s' is not defined" #define NAME_ERROR_MSG "name '%.200s' is not defined"
#define KWNAMES_LEN() \
(kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(kwnames)))
#define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \ #define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \
do { \ do { \
if (Py_REFCNT(left) == 1) { \ if (Py_REFCNT(left) == 1) { \
@ -356,8 +353,6 @@ static const convertion_func_ptr CONVERSION_FUNCTIONS[4] = {
[FVC_ASCII] = PyObject_ASCII [FVC_ASCII] = PyObject_ASCII
}; };
#define ASSERT_KWNAMES_IS_NULL() assert(kwnames == NULL)
// GH-89279: Force inlining by using a macro. // GH-89279: Force inlining by using a macro.
#if defined(_MSC_VER) && SIZEOF_INT == 4 #if defined(_MSC_VER) && SIZEOF_INT == 4
#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value))) #define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value)))

View File

@ -4982,9 +4982,13 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
VISIT_SEQ(c, keyword, kwds); VISIT_SEQ(c, keyword, kwds);
RETURN_IF_ERROR( RETURN_IF_ERROR(
compiler_call_simple_kw_helper(c, loc, kwds, kwdsl)); compiler_call_simple_kw_helper(c, loc, kwds, kwdsl));
loc = update_start_location_to_match_attr(c, LOC(e), meth);
ADDOP_I(c, loc, CALL_KW, argsl + kwdsl);
}
else {
loc = update_start_location_to_match_attr(c, LOC(e), meth);
ADDOP_I(c, loc, CALL, argsl);
} }
loc = update_start_location_to_match_attr(c, LOC(e), meth);
ADDOP_I(c, loc, CALL, argsl + kwdsl);
return 1; return 1;
} }
@ -5150,7 +5154,7 @@ compiler_subkwargs(struct compiler *c, location loc,
} }
/* Used by compiler_call_helper and maybe_optimize_method_call to emit /* Used by compiler_call_helper and maybe_optimize_method_call to emit
* KW_NAMES before CALL. * a tuple of keyword names before CALL.
*/ */
static int static int
compiler_call_simple_kw_helper(struct compiler *c, location loc, compiler_call_simple_kw_helper(struct compiler *c, location loc,
@ -5165,12 +5169,7 @@ compiler_call_simple_kw_helper(struct compiler *c, location loc,
keyword_ty kw = asdl_seq_GET(keywords, i); keyword_ty kw = asdl_seq_GET(keywords, i);
PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg)); PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
} }
Py_ssize_t arg = compiler_add_const(c->c_const_cache, c->u, names); ADDOP_LOAD_CONST_NEW(c, loc, names);
if (arg < 0) {
return ERROR;
}
Py_DECREF(names);
ADDOP_I(c, loc, KW_NAMES, arg);
return SUCCESS; return SUCCESS;
} }
@ -5215,8 +5214,11 @@ compiler_call_helper(struct compiler *c, location loc,
VISIT_SEQ(c, keyword, keywords); VISIT_SEQ(c, keyword, keywords);
RETURN_IF_ERROR( RETURN_IF_ERROR(
compiler_call_simple_kw_helper(c, loc, keywords, nkwelts)); compiler_call_simple_kw_helper(c, loc, keywords, nkwelts));
ADDOP_I(c, loc, CALL_KW, n + nelts + nkwelts);
}
else {
ADDOP_I(c, loc, CALL, n + nelts);
} }
ADDOP_I(c, loc, CALL, n + nelts + nkwelts);
return SUCCESS; return SUCCESS;
ex_call: ex_call:

View File

@ -2256,7 +2256,6 @@
self_or_null = stack_pointer[-1 - oparg]; self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
uint32_t func_version = (uint32_t)operand; uint32_t func_version = (uint32_t)operand;
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL); DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable; PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL); DEOPT_IF(func->func_version != func_version, CALL);
@ -2324,7 +2323,7 @@
break; break;
} }
case CALL_NO_KW_TYPE_1: { case CALL_TYPE_1: {
PyObject **args; PyObject **args;
PyObject *null; PyObject *null;
PyObject *callable; PyObject *callable;
@ -2332,7 +2331,6 @@
args = stack_pointer - oparg; args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg]; null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
PyObject *obj = args[0]; PyObject *obj = args[0];
@ -2347,7 +2345,7 @@
break; break;
} }
case CALL_NO_KW_STR_1: { case CALL_STR_1: {
PyObject **args; PyObject **args;
PyObject *null; PyObject *null;
PyObject *callable; PyObject *callable;
@ -2355,7 +2353,6 @@
args = stack_pointer - oparg; args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg]; null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
@ -2372,7 +2369,7 @@
break; break;
} }
case CALL_NO_KW_TUPLE_1: { case CALL_TUPLE_1: {
PyObject **args; PyObject **args;
PyObject *null; PyObject *null;
PyObject *callable; PyObject *callable;
@ -2380,7 +2377,6 @@
args = stack_pointer - oparg; args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg]; null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
@ -2411,7 +2407,38 @@
break; break;
} }
case CALL_NO_KW_BUILTIN_O: { case CALL_BUILTIN_CLASS: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
PyObject *res;
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
int total_args = oparg;
if (self_or_null != NULL) {
args--;
total_args++;
}
DEOPT_IF(!PyType_Check(callable), CALL);
PyTypeObject *tp = (PyTypeObject *)callable;
DEOPT_IF(tp->tp_vectorcall == NULL, CALL);
STAT_INC(CALL, hit);
res = tp->tp_vectorcall((PyObject *)tp, args, total_args, NULL);
/* Free the arguments. */
for (int i = 0; i < total_args; i++) {
Py_DECREF(args[i]);
}
Py_DECREF(tp);
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
CHECK_EVAL_BREAKER();
break;
}
case CALL_BUILTIN_O: {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -2420,7 +2447,6 @@
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 */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -2451,7 +2477,7 @@
break; break;
} }
case CALL_NO_KW_BUILTIN_FAST: { case CALL_BUILTIN_FAST: {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -2460,7 +2486,6 @@
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 */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -2495,7 +2520,45 @@
break; break;
} }
case CALL_NO_KW_LEN: { case CALL_BUILTIN_FAST_WITH_KEYWORDS: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
PyObject *res;
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
/* Builtin METH_FASTCALL | METH_KEYWORDS functions */
int total_args = oparg;
if (self_or_null != NULL) {
args--;
total_args++;
}
DEOPT_IF(!PyCFunction_CheckExact(callable), CALL);
DEOPT_IF(PyCFunction_GET_FLAGS(callable) !=
(METH_FASTCALL | METH_KEYWORDS), CALL);
STAT_INC(CALL, hit);
/* res = func(self, args, nargs, kwnames) */
_PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void))
PyCFunction_GET_FUNCTION(callable);
res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
/* Free the arguments. */
for (int i = 0; i < total_args; i++) {
Py_DECREF(args[i]);
}
Py_DECREF(callable);
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
CHECK_EVAL_BREAKER();
break;
}
case CALL_LEN: {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -2503,7 +2566,6 @@
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_KWNAMES_IS_NULL();
/* len(o) */ /* len(o) */
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -2531,7 +2593,7 @@
break; break;
} }
case CALL_NO_KW_ISINSTANCE: { case CALL_ISINSTANCE: {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -2539,7 +2601,6 @@
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_KWNAMES_IS_NULL();
/* isinstance(o, o2) */ /* isinstance(o, o2) */
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -2569,7 +2630,7 @@
break; break;
} }
case CALL_NO_KW_METHOD_DESCRIPTOR_O: { case CALL_METHOD_DESCRIPTOR_O: {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -2577,7 +2638,6 @@
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_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -2612,7 +2672,47 @@
break; break;
} }
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: { case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
PyObject *res;
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
int total_args = oparg;
if (self_or_null != NULL) {
args--;
total_args++;
}
PyMethodDescrObject *method = (PyMethodDescrObject *)callable;
DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type), CALL);
PyMethodDef *meth = method->d_method;
DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL);
PyTypeObject *d_type = method->d_common.d_type;
PyObject *self = args[0];
DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL);
STAT_INC(CALL, hit);
int nargs = total_args - 1;
_PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth;
res = cfunc(self, args + 1, nargs, NULL);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
/* Free the arguments. */
for (int i = 0; i < total_args; i++) {
Py_DECREF(args[i]);
}
Py_DECREF(callable);
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
CHECK_EVAL_BREAKER();
break;
}
case CALL_METHOD_DESCRIPTOR_NOARGS: {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -2620,7 +2720,6 @@
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_KWNAMES_IS_NULL();
assert(oparg == 0 || oparg == 1); assert(oparg == 0 || oparg == 1);
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -2654,7 +2753,7 @@
break; break;
} }
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: { case CALL_METHOD_DESCRIPTOR_FAST: {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -2662,7 +2761,6 @@
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_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;

View File

@ -1624,8 +1624,6 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
INSTR_SET_OP0(inst, NOP); INSTR_SET_OP0(inst, NOP);
} }
break; break;
case KW_NAMES:
break;
case LOAD_GLOBAL: case LOAD_GLOBAL:
if (nextop == PUSH_NULL && (oparg & 1) == 0) { if (nextop == PUSH_NULL && (oparg & 1) == 0) {
INSTR_SET_OP1(inst, LOAD_GLOBAL, oparg | 1); INSTR_SET_OP1(inst, LOAD_GLOBAL, oparg | 1);

View File

@ -3688,13 +3688,6 @@
DISPATCH(); DISPATCH();
} }
TARGET(KW_NAMES) {
ASSERT_KWNAMES_IS_NULL();
assert(oparg < PyTuple_GET_SIZE(FRAME_CO_CONSTS));
kwnames = GETITEM(FRAME_CO_CONSTS, oparg);
DISPATCH();
}
TARGET(INSTRUMENTED_CALL) { TARGET(INSTRUMENTED_CALL) {
int is_meth = PEEK(oparg + 1) != NULL; int is_meth = PEEK(oparg + 1) != NULL;
int total_args = oparg + is_meth; int total_args = oparg + is_meth;
@ -3720,6 +3713,7 @@
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];
// oparg counts all of the args, but *not* self:
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -3729,7 +3723,7 @@
_PyCallCache *cache = (_PyCallCache *)next_instr; _PyCallCache *cache = (_PyCallCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
next_instr--; next_instr--;
_Py_Specialize_Call(callable, next_instr, total_args, kwnames); _Py_Specialize_Call(callable, next_instr, total_args);
DISPATCH_SAME_OPARG(); DISPATCH_SAME_OPARG();
} }
STAT_INC(CALL, deferred); STAT_INC(CALL, deferred);
@ -3745,7 +3739,6 @@
Py_DECREF(callable); Py_DECREF(callable);
callable = method; callable = method;
} }
int positional_args = total_args - KWNAMES_LEN();
// Check if the call can be inlined or not // Check if the call can be inlined or not
if (Py_TYPE(callable) == &PyFunction_Type && if (Py_TYPE(callable) == &PyFunction_Type &&
tstate->interp->eval_frame == NULL && tstate->interp->eval_frame == NULL &&
@ -3755,9 +3748,8 @@
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
tstate, (PyFunctionObject *)callable, locals, tstate, (PyFunctionObject *)callable, locals,
args, positional_args, kwnames args, total_args, NULL
); );
kwnames = NULL;
// Manipulate stack directly since we leave using DISPATCH_INLINED(). // Manipulate stack directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2); STACK_SHRINK(oparg + 2);
// The frame has stolen all the arguments from the stack, // The frame has stolen all the arguments from the stack,
@ -3772,8 +3764,8 @@
/* Callable is not a normal Python function */ /* Callable is not a normal Python function */
res = PyObject_Vectorcall( res = PyObject_Vectorcall(
callable, args, callable, args,
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
kwnames); NULL);
if (opcode == INSTRUMENTED_CALL) { if (opcode == INSTRUMENTED_CALL) {
PyObject *arg = total_args == 0 ? PyObject *arg = total_args == 0 ?
&_PyInstrumentation_MISSING : args[0]; &_PyInstrumentation_MISSING : args[0];
@ -3791,7 +3783,6 @@
} }
} }
} }
kwnames = NULL;
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable); Py_DECREF(callable);
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
@ -3839,7 +3830,6 @@
callable = func; callable = func;
{ {
uint32_t func_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[1].cache);
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL); DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable; PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL); DEOPT_IF(func->func_version != func_version, CALL);
@ -3918,7 +3908,6 @@
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
{ {
uint32_t func_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[1].cache);
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL); DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable; PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL); DEOPT_IF(func->func_version != func_version, CALL);
@ -3991,7 +3980,6 @@
self_or_null = stack_pointer[-1 - oparg]; self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
uint32_t func_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[1].cache);
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(tstate->interp->eval_frame, CALL); DEOPT_IF(tstate->interp->eval_frame, CALL);
int argcount = oparg; int argcount = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -4026,7 +4014,7 @@
DISPATCH_INLINED(new_frame); DISPATCH_INLINED(new_frame);
} }
TARGET(CALL_NO_KW_TYPE_1) { TARGET(CALL_TYPE_1) {
PyObject **args; PyObject **args;
PyObject *null; PyObject *null;
PyObject *callable; PyObject *callable;
@ -4034,7 +4022,6 @@
args = stack_pointer - oparg; args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg]; null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
PyObject *obj = args[0]; PyObject *obj = args[0];
@ -4050,7 +4037,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_STR_1) { TARGET(CALL_STR_1) {
PyObject **args; PyObject **args;
PyObject *null; PyObject *null;
PyObject *callable; PyObject *callable;
@ -4058,7 +4045,6 @@
args = stack_pointer - oparg; args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg]; null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
@ -4076,7 +4062,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_TUPLE_1) { TARGET(CALL_TUPLE_1) {
PyObject **args; PyObject **args;
PyObject *null; PyObject *null;
PyObject *callable; PyObject *callable;
@ -4084,7 +4070,6 @@
args = stack_pointer - oparg; args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg]; null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
@ -4102,7 +4087,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_ALLOC_AND_ENTER_INIT) { TARGET(CALL_ALLOC_AND_ENTER_INIT) {
PyObject **args; PyObject **args;
PyObject *null; PyObject *null;
PyObject *callable; PyObject *callable;
@ -4114,7 +4099,6 @@
* 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``) * 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
* 3. Pushes the frame for ``__init__`` to the frame stack * 3. Pushes the frame for ``__init__`` to the frame stack
* */ * */
ASSERT_KWNAMES_IS_NULL();
_PyCallCache *cache = (_PyCallCache *)next_instr; _PyCallCache *cache = (_PyCallCache *)next_instr;
DEOPT_IF(null != NULL, CALL); DEOPT_IF(null != NULL, CALL);
DEOPT_IF(!PyType_Check(callable), CALL); DEOPT_IF(!PyType_Check(callable), CALL);
@ -4188,14 +4172,11 @@
args--; args--;
total_args++; total_args++;
} }
int kwnames_len = KWNAMES_LEN();
DEOPT_IF(!PyType_Check(callable), CALL); DEOPT_IF(!PyType_Check(callable), CALL);
PyTypeObject *tp = (PyTypeObject *)callable; PyTypeObject *tp = (PyTypeObject *)callable;
DEOPT_IF(tp->tp_vectorcall == NULL, CALL); DEOPT_IF(tp->tp_vectorcall == NULL, CALL);
STAT_INC(CALL, hit); STAT_INC(CALL, hit);
res = tp->tp_vectorcall((PyObject *)tp, args, res = tp->tp_vectorcall((PyObject *)tp, args, total_args, NULL);
total_args - kwnames_len, kwnames);
kwnames = NULL;
/* Free the arguments. */ /* Free the arguments. */
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
Py_DECREF(args[i]); Py_DECREF(args[i]);
@ -4210,7 +4191,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_BUILTIN_O) { TARGET(CALL_BUILTIN_O) {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -4219,7 +4200,6 @@
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 */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -4251,7 +4231,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_BUILTIN_FAST) { TARGET(CALL_BUILTIN_FAST) {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -4260,7 +4240,6 @@
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 */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -4318,14 +4297,8 @@
_PyCFunctionFastWithKeywords cfunc = _PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void)) (_PyCFunctionFastWithKeywords)(void(*)(void))
PyCFunction_GET_FUNCTION(callable); PyCFunction_GET_FUNCTION(callable);
res = cfunc( res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL);
PyCFunction_GET_SELF(callable),
args,
total_args - KWNAMES_LEN(),
kwnames
);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
kwnames = NULL;
/* Free the arguments. */ /* Free the arguments. */
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
@ -4341,7 +4314,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_LEN) { TARGET(CALL_LEN) {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -4349,7 +4322,6 @@
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_KWNAMES_IS_NULL();
/* len(o) */ /* len(o) */
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -4378,7 +4350,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_ISINSTANCE) { TARGET(CALL_ISINSTANCE) {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -4386,7 +4358,6 @@
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_KWNAMES_IS_NULL();
/* isinstance(o, o2) */ /* isinstance(o, o2) */
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -4417,14 +4388,13 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_LIST_APPEND) { TARGET(CALL_LIST_APPEND) {
PyObject **args; PyObject **args;
PyObject *self; PyObject *self;
PyObject *callable; PyObject *callable;
args = stack_pointer - oparg; args = stack_pointer - oparg;
self = stack_pointer[-1 - oparg]; self = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1); assert(oparg == 1);
PyInterpreterState *interp = tstate->interp; PyInterpreterState *interp = tstate->interp;
DEOPT_IF(callable != interp->callable_cache.list_append, CALL); DEOPT_IF(callable != interp->callable_cache.list_append, CALL);
@ -4443,7 +4413,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { TARGET(CALL_METHOD_DESCRIPTOR_O) {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -4451,7 +4421,6 @@
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_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -4511,9 +4480,8 @@
int nargs = total_args - 1; int nargs = total_args - 1;
_PyCFunctionFastWithKeywords cfunc = _PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth;
res = cfunc(self, args + 1, nargs - KWNAMES_LEN(), kwnames); res = cfunc(self, args + 1, nargs, NULL);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
kwnames = NULL;
/* Free the arguments. */ /* Free the arguments. */
for (int i = 0; i < total_args; i++) { for (int i = 0; i < total_args; i++) {
@ -4529,7 +4497,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { TARGET(CALL_METHOD_DESCRIPTOR_NOARGS) {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -4537,7 +4505,6 @@
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_KWNAMES_IS_NULL();
assert(oparg == 0 || oparg == 1); assert(oparg == 0 || oparg == 1);
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
@ -4572,7 +4539,7 @@
DISPATCH(); DISPATCH();
} }
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) { TARGET(CALL_METHOD_DESCRIPTOR_FAST) {
PyObject **args; PyObject **args;
PyObject *self_or_null; PyObject *self_or_null;
PyObject *callable; PyObject *callable;
@ -4580,7 +4547,6 @@
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_KWNAMES_IS_NULL();
int total_args = oparg; int total_args = oparg;
if (self_or_null != NULL) { if (self_or_null != NULL) {
args--; args--;
@ -4613,6 +4579,105 @@
DISPATCH(); DISPATCH();
} }
TARGET(INSTRUMENTED_CALL_KW) {
int is_meth = PEEK(oparg + 2) != NULL;
int total_args = oparg + is_meth;
PyObject *function = PEEK(oparg + 3);
PyObject *arg = total_args == 0 ? &_PyInstrumentation_MISSING
: PEEK(total_args + 1);
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_CALL,
frame, next_instr - 1, function, arg);
if (err) goto error;
GO_TO_INSTRUCTION(CALL_KW);
}
TARGET(CALL_KW) {
PREDICTED(CALL_KW);
PyObject *kwnames;
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
PyObject *res;
kwnames = stack_pointer[-1];
args = stack_pointer - 1 - oparg;
self_or_null = stack_pointer[-2 - oparg];
callable = stack_pointer[-3 - oparg];
// oparg counts all of the args, but *not* self:
int total_args = oparg;
if (self_or_null != NULL) {
args--;
total_args++;
}
if (self_or_null == NULL && Py_TYPE(callable) == &PyMethod_Type) {
args--;
total_args++;
PyObject *self = ((PyMethodObject *)callable)->im_self;
args[0] = Py_NewRef(self);
PyObject *method = ((PyMethodObject *)callable)->im_func;
args[-1] = Py_NewRef(method);
Py_DECREF(callable);
callable = method;
}
int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames);
// Check if the call can be inlined or not
if (Py_TYPE(callable) == &PyFunction_Type &&
tstate->interp->eval_frame == NULL &&
((PyFunctionObject *)callable)->vectorcall == _PyFunction_Vectorcall)
{
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags;
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
tstate, (PyFunctionObject *)callable, locals,
args, positional_args, kwnames
);
Py_DECREF(kwnames);
// Manipulate stack directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 3);
// The frame has stolen all the arguments from the stack,
// so there is no need to clean them up.
if (new_frame == NULL) {
goto error;
}
frame->return_offset = 0;
DISPATCH_INLINED(new_frame);
}
/* Callable is not a normal Python function */
res = PyObject_Vectorcall(
callable, args,
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
kwnames);
if (opcode == INSTRUMENTED_CALL_KW) {
PyObject *arg = total_args == 0 ?
&_PyInstrumentation_MISSING : args[0];
if (res == NULL) {
_Py_call_instrumentation_exc2(
tstate, PY_MONITORING_EVENT_C_RAISE,
frame, next_instr-1, callable, arg);
}
else {
int err = _Py_call_instrumentation_2args(
tstate, PY_MONITORING_EVENT_C_RETURN,
frame, next_instr-1, callable, arg);
if (err < 0) {
Py_CLEAR(res);
}
}
}
Py_DECREF(kwnames);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable);
for (int i = 0; i < total_args; i++) {
Py_DECREF(args[i]);
}
if (res == NULL) { STACK_SHRINK(oparg); goto pop_3_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(2);
stack_pointer[-1] = res;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { TARGET(INSTRUMENTED_CALL_FUNCTION_EX) {
GO_TO_INSTRUCTION(CALL_FUNCTION_EX); GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
} }

View File

@ -37,6 +37,8 @@ static const int8_t EVENT_FOR_OPCODE[256] = {
[INSTRUMENTED_RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN, [INSTRUMENTED_RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN,
[CALL] = PY_MONITORING_EVENT_CALL, [CALL] = PY_MONITORING_EVENT_CALL,
[INSTRUMENTED_CALL] = PY_MONITORING_EVENT_CALL, [INSTRUMENTED_CALL] = PY_MONITORING_EVENT_CALL,
[CALL_KW] = PY_MONITORING_EVENT_CALL,
[INSTRUMENTED_CALL_KW] = PY_MONITORING_EVENT_CALL,
[CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL, [CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL,
[INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL, [INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL,
[LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL, [LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL,
@ -69,6 +71,7 @@ static const uint8_t DE_INSTRUMENT[256] = {
[INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE, [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE,
[INSTRUMENTED_RETURN_CONST] = RETURN_CONST, [INSTRUMENTED_RETURN_CONST] = RETURN_CONST,
[INSTRUMENTED_CALL] = CALL, [INSTRUMENTED_CALL] = CALL,
[INSTRUMENTED_CALL_KW] = CALL_KW,
[INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX, [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
[INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE, [INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE,
[INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD, [INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD,
@ -90,6 +93,8 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
[INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
[CALL] = INSTRUMENTED_CALL, [CALL] = INSTRUMENTED_CALL,
[INSTRUMENTED_CALL] = INSTRUMENTED_CALL, [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
[CALL_KW] = INSTRUMENTED_CALL_KW,
[INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW,
[CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, [CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
[INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
[YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, [YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,

View File

@ -56,6 +56,7 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_FUNCTION_EX, &&TARGET_CALL_FUNCTION_EX,
&&TARGET_CALL_INTRINSIC_1, &&TARGET_CALL_INTRINSIC_1,
&&TARGET_CALL_INTRINSIC_2, &&TARGET_CALL_INTRINSIC_2,
&&TARGET_CALL_KW,
&&TARGET_COMPARE_OP, &&TARGET_COMPARE_OP,
&&TARGET_CONTAINS_OP, &&TARGET_CONTAINS_OP,
&&TARGET_CONVERT_VALUE, &&TARGET_CONVERT_VALUE,
@ -78,7 +79,6 @@ static void *opcode_targets[256] = {
&&TARGET_JUMP_BACKWARD, &&TARGET_JUMP_BACKWARD,
&&TARGET_JUMP_BACKWARD_NO_INTERRUPT, &&TARGET_JUMP_BACKWARD_NO_INTERRUPT,
&&TARGET_JUMP_FORWARD, &&TARGET_JUMP_FORWARD,
&&TARGET_KW_NAMES,
&&TARGET_LIST_APPEND, &&TARGET_LIST_APPEND,
&&TARGET_LIST_EXTEND, &&TARGET_LIST_EXTEND,
&&TARGET_LOAD_ATTR, &&TARGET_LOAD_ATTR,
@ -161,24 +161,24 @@ static void *opcode_targets[256] = {
&&TARGET_BINARY_SUBSCR_LIST_INT, &&TARGET_BINARY_SUBSCR_LIST_INT,
&&TARGET_BINARY_SUBSCR_STR_INT, &&TARGET_BINARY_SUBSCR_STR_INT,
&&TARGET_BINARY_SUBSCR_TUPLE_INT, &&TARGET_BINARY_SUBSCR_TUPLE_INT,
&&TARGET_CALL_ALLOC_AND_ENTER_INIT,
&&TARGET_CALL_BOUND_METHOD_EXACT_ARGS, &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS,
&&TARGET_CALL_BUILTIN_CLASS, &&TARGET_CALL_BUILTIN_CLASS,
&&TARGET_CALL_BUILTIN_FAST,
&&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS, &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
&&TARGET_CALL_BUILTIN_O,
&&TARGET_CALL_ISINSTANCE,
&&TARGET_CALL_LEN,
&&TARGET_CALL_LIST_APPEND,
&&TARGET_CALL_METHOD_DESCRIPTOR_FAST,
&&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, &&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
&&TARGET_CALL_NO_KW_ALLOC_AND_ENTER_INIT, &&TARGET_CALL_METHOD_DESCRIPTOR_NOARGS,
&&TARGET_CALL_NO_KW_BUILTIN_FAST, &&TARGET_CALL_METHOD_DESCRIPTOR_O,
&&TARGET_CALL_NO_KW_BUILTIN_O,
&&TARGET_CALL_NO_KW_ISINSTANCE,
&&TARGET_CALL_NO_KW_LEN,
&&TARGET_CALL_NO_KW_LIST_APPEND,
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_FAST,
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS,
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_O,
&&TARGET_CALL_NO_KW_STR_1,
&&TARGET_CALL_NO_KW_TUPLE_1,
&&TARGET_CALL_NO_KW_TYPE_1,
&&TARGET_CALL_PY_EXACT_ARGS, &&TARGET_CALL_PY_EXACT_ARGS,
&&TARGET_CALL_PY_WITH_DEFAULTS, &&TARGET_CALL_PY_WITH_DEFAULTS,
&&TARGET_CALL_STR_1,
&&TARGET_CALL_TUPLE_1,
&&TARGET_CALL_TYPE_1,
&&TARGET_COMPARE_OP_FLOAT, &&TARGET_COMPARE_OP_FLOAT,
&&TARGET_COMPARE_OP_INT, &&TARGET_COMPARE_OP_INT,
&&TARGET_COMPARE_OP_STR, &&TARGET_COMPARE_OP_STR,
@ -235,7 +235,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode, &&_unknown_opcode,
&&_unknown_opcode,
&&TARGET_INSTRUMENTED_RESUME, &&TARGET_INSTRUMENTED_RESUME,
&&TARGET_INSTRUMENTED_END_FOR, &&TARGET_INSTRUMENTED_END_FOR,
&&TARGET_INSTRUMENTED_END_SEND, &&TARGET_INSTRUMENTED_END_SEND,
@ -245,6 +244,7 @@ static void *opcode_targets[256] = {
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR, &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
&&TARGET_INSTRUMENTED_FOR_ITER, &&TARGET_INSTRUMENTED_FOR_ITER,
&&TARGET_INSTRUMENTED_CALL, &&TARGET_INSTRUMENTED_CALL,
&&TARGET_INSTRUMENTED_CALL_KW,
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX, &&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
&&TARGET_INSTRUMENTED_INSTRUCTION, &&TARGET_INSTRUMENTED_INSTRUCTION,
&&TARGET_INSTRUMENTED_JUMP_FORWARD, &&TARGET_INSTRUMENTED_JUMP_FORWARD,

View File

@ -473,7 +473,6 @@ _PyCode_Quicken(PyCodeObject *code)
#define SPEC_FAIL_CALL_STR 24 #define SPEC_FAIL_CALL_STR 24
#define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 25 #define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 25
#define SPEC_FAIL_CALL_CLASS_MUTABLE 26 #define SPEC_FAIL_CALL_CLASS_MUTABLE 26
#define SPEC_FAIL_CALL_KWNAMES 27
#define SPEC_FAIL_CALL_METHOD_WRAPPER 28 #define SPEC_FAIL_CALL_METHOD_WRAPPER 28
#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29 #define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29
#define SPEC_FAIL_CALL_INIT_NOT_SIMPLE 30 #define SPEC_FAIL_CALL_INIT_NOT_SIMPLE 30
@ -1644,24 +1643,23 @@ get_init_for_simple_managed_python_class(PyTypeObject *tp)
} }
static int static int
specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
PyObject *kwnames)
{ {
assert(PyType_Check(callable)); assert(PyType_Check(callable));
PyTypeObject *tp = _PyType_CAST(callable); PyTypeObject *tp = _PyType_CAST(callable);
if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) {
int oparg = instr->op.arg; int oparg = instr->op.arg;
if (nargs == 1 && kwnames == NULL && oparg == 1) { if (nargs == 1 && oparg == 1) {
if (tp == &PyUnicode_Type) { if (tp == &PyUnicode_Type) {
instr->op.code = CALL_NO_KW_STR_1; instr->op.code = CALL_STR_1;
return 0; return 0;
} }
else if (tp == &PyType_Type) { else if (tp == &PyType_Type) {
instr->op.code = CALL_NO_KW_TYPE_1; instr->op.code = CALL_TYPE_1;
return 0; return 0;
} }
else if (tp == &PyTuple_Type) { else if (tp == &PyTuple_Type) {
instr->op.code = CALL_NO_KW_TUPLE_1; instr->op.code = CALL_TUPLE_1;
return 0; return 0;
} }
} }
@ -1680,13 +1678,9 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
return -1; return -1;
} }
if (kwnames) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES);
return -1;
}
_PyCallCache *cache = (_PyCallCache *)(instr + 1); _PyCallCache *cache = (_PyCallCache *)(instr + 1);
write_u32(cache->func_version, tp->tp_version_tag); write_u32(cache->func_version, tp->tp_version_tag);
_Py_SET_OPCODE(*instr, CALL_NO_KW_ALLOC_AND_ENTER_INIT); _Py_SET_OPCODE(*instr, CALL_ALLOC_AND_ENTER_INIT);
return 0; return 0;
} }
return -1; return -1;
@ -1744,13 +1738,8 @@ meth_descr_call_fail_kind(int ml_flags)
static int static int
specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
int nargs, PyObject *kwnames) int nargs)
{ {
if (kwnames) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES);
return -1;
}
switch (descr->d_method->ml_flags & switch (descr->d_method->ml_flags &
(METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O |
METH_KEYWORDS | METH_METHOD)) { METH_KEYWORDS | METH_METHOD)) {
@ -1759,7 +1748,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
return -1; return -1;
} }
instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS; instr->op.code = CALL_METHOD_DESCRIPTOR_NOARGS;
return 0; return 0;
} }
case METH_O: { case METH_O: {
@ -1773,14 +1762,14 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
bool pop = (next.op.code == POP_TOP); bool pop = (next.op.code == POP_TOP);
int oparg = instr->op.arg; int oparg = instr->op.arg;
if ((PyObject *)descr == list_append && oparg == 1 && pop) { if ((PyObject *)descr == list_append && oparg == 1 && pop) {
instr->op.code = CALL_NO_KW_LIST_APPEND; instr->op.code = CALL_LIST_APPEND;
return 0; return 0;
} }
instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_O; instr->op.code = CALL_METHOD_DESCRIPTOR_O;
return 0; return 0;
} }
case METH_FASTCALL: { case METH_FASTCALL: {
instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_FAST; instr->op.code = CALL_METHOD_DESCRIPTOR_FAST;
return 0; return 0;
} }
case METH_FASTCALL | METH_KEYWORDS: { case METH_FASTCALL | METH_KEYWORDS: {
@ -1794,7 +1783,7 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
static int static int
specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
PyObject *kwnames, bool bound_method) bool bound_method)
{ {
_PyCallCache *cache = (_PyCallCache *)(instr + 1); _PyCallCache *cache = (_PyCallCache *)(instr + 1);
PyCodeObject *code = (PyCodeObject *)func->func_code; PyCodeObject *code = (PyCodeObject *)func->func_code;
@ -1804,10 +1793,6 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523); SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523);
return -1; return -1;
} }
if (kwnames) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES);
return -1;
}
if (kind != SIMPLE_FUNCTION) { if (kind != SIMPLE_FUNCTION) {
SPECIALIZATION_FAIL(CALL, kind); SPECIALIZATION_FAIL(CALL, kind);
return -1; return -1;
@ -1843,8 +1828,7 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
} }
static int static int
specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
PyObject *kwnames)
{ {
if (PyCFunction_GET_FUNCTION(callable) == NULL) { if (PyCFunction_GET_FUNCTION(callable) == NULL) {
return 1; return 1;
@ -1853,10 +1837,6 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
(METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O |
METH_KEYWORDS | METH_METHOD)) { METH_KEYWORDS | METH_METHOD)) {
case METH_O: { case METH_O: {
if (kwnames) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES);
return -1;
}
if (nargs != 1) { if (nargs != 1) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
return 1; return 1;
@ -1864,26 +1844,22 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
/* len(o) */ /* len(o) */
PyInterpreterState *interp = _PyInterpreterState_GET(); PyInterpreterState *interp = _PyInterpreterState_GET();
if (callable == interp->callable_cache.len) { if (callable == interp->callable_cache.len) {
instr->op.code = CALL_NO_KW_LEN; instr->op.code = CALL_LEN;
return 0; return 0;
} }
instr->op.code = CALL_NO_KW_BUILTIN_O; instr->op.code = CALL_BUILTIN_O;
return 0; return 0;
} }
case METH_FASTCALL: { case METH_FASTCALL: {
if (kwnames) {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES);
return -1;
}
if (nargs == 2) { if (nargs == 2) {
/* isinstance(o1, o2) */ /* isinstance(o1, o2) */
PyInterpreterState *interp = _PyInterpreterState_GET(); PyInterpreterState *interp = _PyInterpreterState_GET();
if (callable == interp->callable_cache.isinstance) { if (callable == interp->callable_cache.isinstance) {
instr->op.code = CALL_NO_KW_ISINSTANCE; instr->op.code = CALL_ISINSTANCE;
return 0; return 0;
} }
} }
instr->op.code = CALL_NO_KW_BUILTIN_FAST; instr->op.code = CALL_BUILTIN_FAST;
return 0; return 0;
} }
case METH_FASTCALL | METH_KEYWORDS: { case METH_FASTCALL | METH_KEYWORDS: {
@ -1924,12 +1900,8 @@ call_fail_kind(PyObject *callable)
#endif // Py_STATS #endif // Py_STATS
/* TODO:
- Specialize calling classes.
*/
void void
_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
PyObject *kwnames)
{ {
assert(ENABLE_SPECIALIZATION); assert(ENABLE_SPECIALIZATION);
assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL); assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL);
@ -1937,25 +1909,23 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
_PyCallCache *cache = (_PyCallCache *)(instr + 1); _PyCallCache *cache = (_PyCallCache *)(instr + 1);
int fail; int fail;
if (PyCFunction_CheckExact(callable)) { if (PyCFunction_CheckExact(callable)) {
fail = specialize_c_call(callable, instr, nargs, kwnames); fail = specialize_c_call(callable, instr, nargs);
} }
else if (PyFunction_Check(callable)) { else if (PyFunction_Check(callable)) {
fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, false);
kwnames, false);
} }
else if (PyType_Check(callable)) { else if (PyType_Check(callable)) {
fail = specialize_class_call(callable, instr, nargs, kwnames); fail = specialize_class_call(callable, instr, nargs);
} }
else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) {
fail = specialize_method_descriptor((PyMethodDescrObject *)callable, fail = specialize_method_descriptor((PyMethodDescrObject *)callable, instr, nargs);
instr, nargs, kwnames);
} }
else if (PyMethod_Check(callable)) { else if (PyMethod_Check(callable)) {
PyObject *func = ((PyMethodObject *)callable)->im_func; PyObject *func = ((PyMethodObject *)callable)->im_func;
if (PyFunction_Check(func)) { if (PyFunction_Check(func)) {
fail = specialize_py_call((PyFunctionObject *)func, fail = specialize_py_call((PyFunctionObject *)func, instr, nargs+1, true);
instr, nargs+1, kwnames, true); }
} else { else {
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD); SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD);
fail = -1; fail = -1;
} }
@ -2491,7 +2461,7 @@ success:
} }
/* Code init cleanup. /* Code init cleanup.
* CALL_NO_KW_ALLOC_AND_ENTER_INIT will set up * CALL_ALLOC_AND_ENTER_INIT will set up
* the frame to execute the EXIT_INIT_CHECK * the frame to execute the EXIT_INIT_CHECK
* instruction. * instruction.
* Ends with a RESUME so that it is not traced. * Ends with a RESUME so that it is not traced.