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
correct name, the bytecode pushes the unbound method and ``STACK[-1]``.
``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.
.. versionchanged:: 3.12
@ -1390,25 +1391,14 @@ iterations of the loop.
.. opcode:: CALL (argc)
Calls a callable object with the number of arguments specified by ``argc``,
including the named arguments specified by the preceding
:opcode:`KW_NAMES`, if any.
On the stack are (in ascending order), either:
* NULL
* The callable
* The positional arguments
* The named arguments
or:
Calls a callable object with the number of arguments specified by ``argc``.
On the stack are (in ascending order):
* The callable
* ``self``
* ``self`` or ``NULL``
* The remaining positional arguments
* The named arguments
``argc`` is the total of the positional and named arguments, excluding
``self`` when a ``NULL`` is not present.
``argc`` is the total of the positional arguments, excluding ``self``.
``CALL`` pops all arguments and the callable object off the stack,
calls the callable object with those arguments, and pushes the return value
@ -1416,6 +1406,33 @@ iterations of the loop.
.. 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)
@ -1441,15 +1458,6 @@ iterations of the loop.
.. 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
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,
_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,
int oparg, PyObject **locals);
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;
case LOAD_ATTR_METHOD_LAZY_DICT:
return 1;
case KW_NAMES:
return 0;
case INSTRUMENTED_CALL:
return 0;
case CALL:
@ -506,38 +504,42 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
return oparg + 2;
case CALL_PY_WITH_DEFAULTS:
return oparg + 2;
case CALL_NO_KW_TYPE_1:
case CALL_TYPE_1:
return oparg + 2;
case CALL_NO_KW_STR_1:
case CALL_STR_1:
return oparg + 2;
case CALL_NO_KW_TUPLE_1:
case CALL_TUPLE_1:
return oparg + 2;
case CALL_NO_KW_ALLOC_AND_ENTER_INIT:
case CALL_ALLOC_AND_ENTER_INIT:
return oparg + 2;
case EXIT_INIT_CHECK:
return 1;
case CALL_BUILTIN_CLASS:
return oparg + 2;
case CALL_NO_KW_BUILTIN_O:
case CALL_BUILTIN_O:
return oparg + 2;
case CALL_NO_KW_BUILTIN_FAST:
case CALL_BUILTIN_FAST:
return oparg + 2;
case CALL_BUILTIN_FAST_WITH_KEYWORDS:
return oparg + 2;
case CALL_NO_KW_LEN:
case CALL_LEN:
return oparg + 2;
case CALL_NO_KW_ISINSTANCE:
case CALL_ISINSTANCE:
return oparg + 2;
case CALL_NO_KW_LIST_APPEND:
case CALL_LIST_APPEND:
return oparg + 2;
case CALL_NO_KW_METHOD_DESCRIPTOR_O:
case CALL_METHOD_DESCRIPTOR_O:
return oparg + 2;
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
return oparg + 2;
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS:
case CALL_METHOD_DESCRIPTOR_NOARGS:
return oparg + 2;
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST:
case CALL_METHOD_DESCRIPTOR_FAST:
return oparg + 2;
case INSTRUMENTED_CALL_KW:
return 0;
case CALL_KW:
return oparg + 3;
case INSTRUMENTED_CALL_FUNCTION_EX:
return 0;
case CALL_FUNCTION_EX:
@ -1010,8 +1012,6 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 1;
case LOAD_ATTR_METHOD_LAZY_DICT:
return 2;
case KW_NAMES:
return 0;
case INSTRUMENTED_CALL:
return 0;
case CALL:
@ -1036,37 +1036,41 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 1;
case CALL_PY_WITH_DEFAULTS:
return 1;
case CALL_NO_KW_TYPE_1:
case CALL_TYPE_1:
return 1;
case CALL_NO_KW_STR_1:
case CALL_STR_1:
return 1;
case CALL_NO_KW_TUPLE_1:
case CALL_TUPLE_1:
return 1;
case CALL_NO_KW_ALLOC_AND_ENTER_INIT:
case CALL_ALLOC_AND_ENTER_INIT:
return 1;
case EXIT_INIT_CHECK:
return 0;
case CALL_BUILTIN_CLASS:
return 1;
case CALL_NO_KW_BUILTIN_O:
case CALL_BUILTIN_O:
return 1;
case CALL_NO_KW_BUILTIN_FAST:
case CALL_BUILTIN_FAST:
return 1;
case CALL_BUILTIN_FAST_WITH_KEYWORDS:
return 1;
case CALL_NO_KW_LEN:
case CALL_LEN:
return 1;
case CALL_NO_KW_ISINSTANCE:
case CALL_ISINSTANCE:
return 1;
case CALL_NO_KW_LIST_APPEND:
case CALL_LIST_APPEND:
return 1;
case CALL_NO_KW_METHOD_DESCRIPTOR_O:
case CALL_METHOD_DESCRIPTOR_O:
return 1;
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
return 1;
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS:
case CALL_METHOD_DESCRIPTOR_NOARGS:
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;
case INSTRUMENTED_CALL_FUNCTION_EX:
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_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 },
[KW_NAMES] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_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 },
[_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_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_NO_KW_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_NO_KW_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_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
[CALL_STR_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_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 },
[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_NO_KW_BUILTIN_FAST] = { 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_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_NO_KW_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_NO_KW_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_LEN] = { 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_LIST_APPEND] = { true, INSTR_FMT_IBC00, HAS_ARG_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_NO_KW_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_NOARGS] = { 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 },
[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 },
@ -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 } } },
[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_NO_KW_TYPE_1] = { .nuops = 1, .uops = { { CALL_NO_KW_TYPE_1, 0, 0 } } },
[CALL_NO_KW_STR_1] = { .nuops = 1, .uops = { { CALL_NO_KW_STR_1, 0, 0 } } },
[CALL_NO_KW_TUPLE_1] = { .nuops = 1, .uops = { { CALL_NO_KW_TUPLE_1, 0, 0 } } },
[CALL_TYPE_1] = { .nuops = 1, .uops = { { CALL_TYPE_1, 0, 0 } } },
[CALL_STR_1] = { .nuops = 1, .uops = { { CALL_STR_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 } } },
[CALL_NO_KW_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_NO_KW_BUILTIN_O, 0, 0 } } },
[CALL_NO_KW_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_NO_KW_BUILTIN_FAST, 0, 0 } } },
[CALL_NO_KW_LEN] = { .nuops = 1, .uops = { { CALL_NO_KW_LEN, 0, 0 } } },
[CALL_NO_KW_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_NO_KW_ISINSTANCE, 0, 0 } } },
[CALL_NO_KW_METHOD_DESCRIPTOR_O] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_O, 0, 0 } } },
[CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, 0, 0 } } },
[CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { .nuops = 1, .uops = { { CALL_NO_KW_METHOD_DESCRIPTOR_FAST, 0, 0 } } },
[CALL_BUILTIN_CLASS] = { .nuops = 1, .uops = { { CALL_BUILTIN_CLASS, 0, 0 } } },
[CALL_BUILTIN_O] = { .nuops = 1, .uops = { { CALL_BUILTIN_O, 0, 0 } } },
[CALL_BUILTIN_FAST] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST, 0, 0 } } },
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 1, .uops = { { CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 } } },
[CALL_LEN] = { .nuops = 1, .uops = { { CALL_LEN, 0, 0 } } },
[CALL_ISINSTANCE] = { .nuops = 1, .uops = { { CALL_ISINSTANCE, 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 } } },
[SET_FUNCTION_ATTRIBUTE] = { .nuops = 1, .uops = { { SET_FUNCTION_ATTRIBUTE, 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_INTRINSIC_1] = "CALL_INTRINSIC_1",
[CALL_INTRINSIC_2] = "CALL_INTRINSIC_2",
[CALL_KW] = "CALL_KW",
[COMPARE_OP] = "COMPARE_OP",
[CONTAINS_OP] = "CONTAINS_OP",
[CONVERT_VALUE] = "CONVERT_VALUE",
@ -1739,7 +1748,6 @@ const char *const _PyOpcode_OpName[268] = {
[JUMP_BACKWARD] = "JUMP_BACKWARD",
[JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT",
[JUMP_FORWARD] = "JUMP_FORWARD",
[KW_NAMES] = "KW_NAMES",
[LIST_APPEND] = "LIST_APPEND",
[LIST_EXTEND] = "LIST_EXTEND",
[LOAD_ATTR] = "LOAD_ATTR",
@ -1791,24 +1799,24 @@ const char *const _PyOpcode_OpName[268] = {
[BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT",
[BINARY_SUBSCR_STR_INT] = "BINARY_SUBSCR_STR_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_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
[CALL_BUILTIN_FAST] = "CALL_BUILTIN_FAST",
[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_NO_KW_ALLOC_AND_ENTER_INIT] = "CALL_NO_KW_ALLOC_AND_ENTER_INIT",
[CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST",
[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_METHOD_DESCRIPTOR_NOARGS] = "CALL_METHOD_DESCRIPTOR_NOARGS",
[CALL_METHOD_DESCRIPTOR_O] = "CALL_METHOD_DESCRIPTOR_O",
[CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
[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_INT] = "COMPARE_OP_INT",
[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_FOR_ITER] = "INSTRUMENTED_FOR_ITER",
[INSTRUMENTED_CALL] = "INSTRUMENTED_CALL",
[INSTRUMENTED_CALL_KW] = "INSTRUMENTED_CALL_KW",
[INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX",
[INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION",
[INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD",
@ -1935,27 +1944,28 @@ const uint8_t _PyOpcode_Deopt[256] = {
[BUILD_TUPLE] = BUILD_TUPLE,
[CACHE] = CACHE,
[CALL] = CALL,
[CALL_ALLOC_AND_ENTER_INIT] = CALL,
[CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
[CALL_BUILTIN_CLASS] = CALL,
[CALL_BUILTIN_FAST] = CALL,
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
[CALL_BUILTIN_O] = CALL,
[CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
[CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
[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_NO_KW_ALLOC_AND_ENTER_INIT] = CALL,
[CALL_NO_KW_BUILTIN_FAST] = 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_METHOD_DESCRIPTOR_NOARGS] = CALL,
[CALL_METHOD_DESCRIPTOR_O] = CALL,
[CALL_PY_EXACT_ARGS] = 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_EXC_MATCH] = CHECK_EXC_MATCH,
[CLEANUP_THROW] = CLEANUP_THROW,
@ -1998,6 +2008,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[IMPORT_NAME] = IMPORT_NAME,
[INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
[INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
[INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW,
[INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
[INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
[INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
@ -2019,7 +2030,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
[JUMP_BACKWARD] = JUMP_BACKWARD,
[JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
[JUMP_FORWARD] = JUMP_FORWARD,
[KW_NAMES] = KW_NAMES,
[LIST_APPEND] = LIST_APPEND,
[LIST_EXTEND] = LIST_EXTEND,
[LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
@ -2166,7 +2176,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
case 233: \
case 234: \
case 235: \
case 236: \
case 255: \
;

103
Include/opcode_ids.h generated
View File

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

127
Lib/_opcode_metadata.py generated
View File

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

View File

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

View File

@ -240,8 +240,8 @@ dis_kw_names = """\
LOAD_CONST 1 (1)
LOAD_CONST 2 (2)
LOAD_CONST 3 (5)
KW_NAMES 4 (('c',))
CALL 3
LOAD_CONST 4 (('c',))
CALL_KW 3
POP_TOP
RETURN_CONST 0 (None)
""" % (wrap_func_w_kwargs.__code__.co_firstlineno,
@ -1003,7 +1003,7 @@ class DisTests(DisTestBase):
self.do_disassembly_test(bug46724, dis_bug46724)
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)
def test_intrinsic_1(self):
@ -1256,7 +1256,7 @@ class DisTests(DisTestBase):
1 LOAD_NAME 0 (str)
PUSH_NULL
LOAD_CONST 0 (1)
CALL_NO_KW_STR_1 1
CALL_STR_1 1
RETURN_VALUE
"""
co = compile("str(1)", "", "eval")
@ -1636,7 +1636,7 @@ def _prepare_test_cases():
result = result.replace(repr(code_object_inner), "code_object_inner")
print(result)
# _prepare_test_cases()
# from test.test_dis import _prepare_test_cases; _prepare_test_cases()
Instruction = dis.Instruction
@ -1668,7 +1668,7 @@ expected_opinfo_outer = [
]
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=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),
@ -1695,7 +1695,7 @@ expected_opinfo_f = [
]
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='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),
@ -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='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='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='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),
@ -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='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='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='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_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='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='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='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),
@ -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='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='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='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_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='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='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='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_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),
@ -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_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='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='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='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=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='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),
@ -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='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='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='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='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),
@ -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='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='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='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:
{
int j = oparg;
next_stack = push_value(next_stack, Object);
if (j & 1) {
next_stack = push_value(next_stack, Null);
}
next_stack = push_value(next_stack, Object);
stacks[next_i] = next_stack;
break;
}
@ -424,22 +424,12 @@ mark_stacks(PyCodeObject *code_obj, int len)
int j = oparg;
if (j & 1) {
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, Null);
}
stacks[next_i] = next_stack;
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:
{
int n = oparg;

View File

@ -2,16 +2,16 @@
unsigned char M_test_frozenmain[] = {
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,
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,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,
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,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,
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,
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,

View File

@ -661,21 +661,21 @@
break;
}
case CALL_NO_KW_TYPE_1: {
case CALL_TYPE_1: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_NO_KW_STR_1: {
case CALL_STR_1: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_NO_KW_TUPLE_1: {
case CALL_TUPLE_1: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
@ -687,49 +687,70 @@
break;
}
case CALL_NO_KW_BUILTIN_O: {
case CALL_BUILTIN_CLASS: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_NO_KW_BUILTIN_FAST: {
case CALL_BUILTIN_O: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_NO_KW_LEN: {
case CALL_BUILTIN_FAST: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_NO_KW_ISINSTANCE: {
case CALL_BUILTIN_FAST_WITH_KEYWORDS: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_NO_KW_METHOD_DESCRIPTOR_O: {
case CALL_LEN: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
break;
}
case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: {
case CALL_ISINSTANCE: {
STACK_SHRINK(oparg);
STACK_SHRINK(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);
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(1);
PARTITIONNODE_OVERWRITE((_Py_PARTITIONNODE_t *)PARTITIONNODE_NULLROOT, PEEK(-(-1)), true);

View File

@ -74,7 +74,6 @@ dummy_func(
unsigned int oparg,
_Py_CODEUNIT *next_instr,
PyObject **stack_pointer,
PyObject *kwnames,
int throwflag,
PyObject *args[]
)
@ -2854,12 +2853,6 @@ dummy_func(
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, ( -- )) {
int is_meth = PEEK(oparg + 1) != NULL;
int total_args = oparg + is_meth;
@ -2876,36 +2869,31 @@ dummy_func(
}
// 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) = {
CALL_BOUND_METHOD_EXACT_ARGS,
CALL_PY_EXACT_ARGS,
CALL_PY_WITH_DEFAULTS,
CALL_NO_KW_TYPE_1,
CALL_NO_KW_STR_1,
CALL_NO_KW_TUPLE_1,
CALL_TYPE_1,
CALL_STR_1,
CALL_TUPLE_1,
CALL_BUILTIN_CLASS,
CALL_NO_KW_BUILTIN_O,
CALL_NO_KW_BUILTIN_FAST,
CALL_BUILTIN_O,
CALL_BUILTIN_FAST,
CALL_BUILTIN_FAST_WITH_KEYWORDS,
CALL_NO_KW_LEN,
CALL_NO_KW_ISINSTANCE,
CALL_NO_KW_LIST_APPEND,
CALL_NO_KW_METHOD_DESCRIPTOR_O,
CALL_LEN,
CALL_ISINSTANCE,
CALL_LIST_APPEND,
CALL_METHOD_DESCRIPTOR_O,
CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS,
CALL_NO_KW_METHOD_DESCRIPTOR_FAST,
CALL_NO_KW_ALLOC_AND_ENTER_INIT,
CALL_METHOD_DESCRIPTOR_NOARGS,
CALL_METHOD_DESCRIPTOR_FAST,
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().
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;
if (self_or_null != NULL) {
args--;
@ -2915,7 +2903,7 @@ dummy_func(
_PyCallCache *cache = (_PyCallCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
next_instr--;
_Py_Specialize_Call(callable, next_instr, total_args, kwnames);
_Py_Specialize_Call(callable, next_instr, total_args);
DISPATCH_SAME_OPARG();
}
STAT_INC(CALL, deferred);
@ -2931,7 +2919,6 @@ dummy_func(
Py_DECREF(callable);
callable = method;
}
int positional_args = total_args - KWNAMES_LEN();
// Check if the call can be inlined or not
if (Py_TYPE(callable) == &PyFunction_Type &&
tstate->interp->eval_frame == NULL &&
@ -2941,9 +2928,8 @@ dummy_func(
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
args, total_args, NULL
);
kwnames = NULL;
// Manipulate stack directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2);
// The frame has stolen all the arguments from the stack,
@ -2958,8 +2944,8 @@ dummy_func(
/* Callable is not a normal Python function */
res = PyObject_Vectorcall(
callable, args,
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
kwnames);
total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
NULL);
if (opcode == INSTRUMENTED_CALL) {
PyObject *arg = total_args == 0 ?
&_PyInstrumentation_MISSING : args[0];
@ -2977,7 +2963,6 @@ dummy_func(
}
}
}
kwnames = NULL;
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable);
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])) {
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL);
@ -3081,7 +3065,6 @@ dummy_func(
_PUSH_FRAME;
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);
int argcount = oparg;
if (self_or_null != NULL) {
@ -3116,8 +3099,7 @@ dummy_func(
DISPATCH_INLINED(new_frame);
}
inst(CALL_NO_KW_TYPE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
PyObject *obj = args[0];
@ -3128,8 +3110,7 @@ dummy_func(
Py_DECREF(&PyType_Type); // I.e., callable
}
inst(CALL_NO_KW_STR_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_STR_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
@ -3142,8 +3123,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}
inst(CALL_NO_KW_TUPLE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
@ -3156,13 +3136,12 @@ dummy_func(
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:
* 1. Creates the object (by calling ``object.__new__``)
* 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
* 3. Pushes the frame for ``__init__`` to the frame stack
* */
ASSERT_KWNAMES_IS_NULL();
_PyCallCache *cache = (_PyCallCache *)next_instr;
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(!PyType_Check(callable), CALL);
@ -3225,14 +3204,11 @@ dummy_func(
args--;
total_args++;
}
int kwnames_len = KWNAMES_LEN();
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 - kwnames_len, kwnames);
kwnames = NULL;
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]);
@ -3242,9 +3218,8 @@ dummy_func(
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 */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3271,9 +3246,8 @@ dummy_func(
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 */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3319,14 +3293,8 @@ dummy_func(
_PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void))
PyCFunction_GET_FUNCTION(callable);
res = cfunc(
PyCFunction_GET_SELF(callable),
args,
total_args - KWNAMES_LEN(),
kwnames
);
res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
kwnames = NULL;
/* Free the arguments. */
for (int i = 0; i < total_args; i++) {
@ -3337,8 +3305,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}
inst(CALL_NO_KW_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
/* len(o) */
int total_args = oparg;
if (self_or_null != NULL) {
@ -3362,8 +3329,7 @@ dummy_func(
ERROR_IF(res == NULL, error);
}
inst(CALL_NO_KW_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
/* isinstance(o, o2) */
int total_args = oparg;
if (self_or_null != NULL) {
@ -3390,8 +3356,7 @@ dummy_func(
}
// This is secretly a super-instruction
inst(CALL_NO_KW_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) {
assert(oparg == 1);
PyInterpreterState *interp = tstate->interp;
DEOPT_IF(callable != interp->callable_cache.list_append, CALL);
@ -3410,8 +3375,7 @@ dummy_func(
DISPATCH();
}
inst(CALL_NO_KW_METHOD_DESCRIPTOR_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_METHOD_DESCRIPTOR_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3459,9 +3423,8 @@ dummy_func(
int nargs = total_args - 1;
_PyCFunctionFastWithKeywords cfunc =
(_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));
kwnames = NULL;
/* Free the arguments. */
for (int i = 0; i < total_args; i++) {
@ -3472,8 +3435,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}
inst(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
assert(oparg == 0 || oparg == 1);
int total_args = oparg;
if (self_or_null != NULL) {
@ -3503,8 +3465,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}
inst(CALL_NO_KW_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
ASSERT_KWNAMES_IS_NULL();
inst(CALL_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3532,6 +3493,91 @@ dummy_func(
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, ( -- )) {
GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
}

View File

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

View File

@ -311,9 +311,6 @@ GETITEM(PyObject *v, Py_ssize_t i) {
" in enclosing scope"
#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) \
do { \
if (Py_REFCNT(left) == 1) { \
@ -356,8 +353,6 @@ static const convertion_func_ptr CONVERSION_FUNCTIONS[4] = {
[FVC_ASCII] = PyObject_ASCII
};
#define ASSERT_KWNAMES_IS_NULL() assert(kwnames == NULL)
// GH-89279: Force inlining by using a macro.
#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)))

View File

@ -4982,9 +4982,13 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
VISIT_SEQ(c, keyword, kwds);
RETURN_IF_ERROR(
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;
}
@ -5150,7 +5154,7 @@ compiler_subkwargs(struct compiler *c, location loc,
}
/* 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
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);
PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
}
Py_ssize_t arg = compiler_add_const(c->c_const_cache, c->u, names);
if (arg < 0) {
return ERROR;
}
Py_DECREF(names);
ADDOP_I(c, loc, KW_NAMES, arg);
ADDOP_LOAD_CONST_NEW(c, loc, names);
return SUCCESS;
}
@ -5215,8 +5214,11 @@ compiler_call_helper(struct compiler *c, location loc,
VISIT_SEQ(c, keyword, keywords);
RETURN_IF_ERROR(
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;
ex_call:

View File

@ -2256,7 +2256,6 @@
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
uint32_t func_version = (uint32_t)operand;
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL);
@ -2324,7 +2323,7 @@
break;
}
case CALL_NO_KW_TYPE_1: {
case CALL_TYPE_1: {
PyObject **args;
PyObject *null;
PyObject *callable;
@ -2332,7 +2331,6 @@
args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
PyObject *obj = args[0];
@ -2347,7 +2345,7 @@
break;
}
case CALL_NO_KW_STR_1: {
case CALL_STR_1: {
PyObject **args;
PyObject *null;
PyObject *callable;
@ -2355,7 +2353,6 @@
args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
@ -2372,7 +2369,7 @@
break;
}
case CALL_NO_KW_TUPLE_1: {
case CALL_TUPLE_1: {
PyObject **args;
PyObject *null;
PyObject *callable;
@ -2380,7 +2377,6 @@
args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
@ -2411,7 +2407,38 @@
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 *self_or_null;
PyObject *callable;
@ -2420,7 +2447,6 @@
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
/* Builtin METH_O functions */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -2451,7 +2477,7 @@
break;
}
case CALL_NO_KW_BUILTIN_FAST: {
case CALL_BUILTIN_FAST: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -2460,7 +2486,6 @@
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
/* Builtin METH_FASTCALL functions, without keywords */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -2495,7 +2520,45 @@
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 *self_or_null;
PyObject *callable;
@ -2503,7 +2566,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
/* len(o) */
int total_args = oparg;
if (self_or_null != NULL) {
@ -2531,7 +2593,7 @@
break;
}
case CALL_NO_KW_ISINSTANCE: {
case CALL_ISINSTANCE: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -2539,7 +2601,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
/* isinstance(o, o2) */
int total_args = oparg;
if (self_or_null != NULL) {
@ -2569,7 +2630,7 @@
break;
}
case CALL_NO_KW_METHOD_DESCRIPTOR_O: {
case CALL_METHOD_DESCRIPTOR_O: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -2577,7 +2638,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -2612,7 +2672,47 @@
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 *self_or_null;
PyObject *callable;
@ -2620,7 +2720,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 0 || oparg == 1);
int total_args = oparg;
if (self_or_null != NULL) {
@ -2654,7 +2753,7 @@
break;
}
case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: {
case CALL_METHOD_DESCRIPTOR_FAST: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -2662,7 +2761,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;

View File

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

View File

@ -3688,13 +3688,6 @@
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) {
int is_meth = PEEK(oparg + 1) != NULL;
int total_args = oparg + is_meth;
@ -3720,6 +3713,7 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
// oparg counts all of the args, but *not* self:
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3729,7 +3723,7 @@
_PyCallCache *cache = (_PyCallCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
next_instr--;
_Py_Specialize_Call(callable, next_instr, total_args, kwnames);
_Py_Specialize_Call(callable, next_instr, total_args);
DISPATCH_SAME_OPARG();
}
STAT_INC(CALL, deferred);
@ -3745,7 +3739,6 @@
Py_DECREF(callable);
callable = method;
}
int positional_args = total_args - KWNAMES_LEN();
// Check if the call can be inlined or not
if (Py_TYPE(callable) == &PyFunction_Type &&
tstate->interp->eval_frame == NULL &&
@ -3755,9 +3748,8 @@
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
args, total_args, NULL
);
kwnames = NULL;
// Manipulate stack directly since we leave using DISPATCH_INLINED().
STACK_SHRINK(oparg + 2);
// The frame has stolen all the arguments from the stack,
@ -3772,8 +3764,8 @@
/* Callable is not a normal Python function */
res = PyObject_Vectorcall(
callable, args,
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
kwnames);
total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
NULL);
if (opcode == INSTRUMENTED_CALL) {
PyObject *arg = total_args == 0 ?
&_PyInstrumentation_MISSING : args[0];
@ -3791,7 +3783,6 @@
}
}
}
kwnames = NULL;
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable);
for (int i = 0; i < total_args; i++) {
@ -3839,7 +3830,6 @@
callable = func;
{
uint32_t func_version = read_u32(&next_instr[1].cache);
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL);
@ -3918,7 +3908,6 @@
callable = stack_pointer[-2 - oparg];
{
uint32_t func_version = read_u32(&next_instr[1].cache);
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(!PyFunction_Check(callable), CALL);
PyFunctionObject *func = (PyFunctionObject *)callable;
DEOPT_IF(func->func_version != func_version, CALL);
@ -3991,7 +3980,6 @@
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
uint32_t func_version = read_u32(&next_instr[1].cache);
ASSERT_KWNAMES_IS_NULL();
DEOPT_IF(tstate->interp->eval_frame, CALL);
int argcount = oparg;
if (self_or_null != NULL) {
@ -4026,7 +4014,7 @@
DISPATCH_INLINED(new_frame);
}
TARGET(CALL_NO_KW_TYPE_1) {
TARGET(CALL_TYPE_1) {
PyObject **args;
PyObject *null;
PyObject *callable;
@ -4034,7 +4022,6 @@
args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
PyObject *obj = args[0];
@ -4050,7 +4037,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_STR_1) {
TARGET(CALL_STR_1) {
PyObject **args;
PyObject *null;
PyObject *callable;
@ -4058,7 +4045,6 @@
args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
@ -4076,7 +4062,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_TUPLE_1) {
TARGET(CALL_TUPLE_1) {
PyObject **args;
PyObject *null;
PyObject *callable;
@ -4084,7 +4070,6 @@
args = stack_pointer - oparg;
null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1);
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
@ -4102,7 +4087,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_ALLOC_AND_ENTER_INIT) {
TARGET(CALL_ALLOC_AND_ENTER_INIT) {
PyObject **args;
PyObject *null;
PyObject *callable;
@ -4114,7 +4099,6 @@
* 2. Pushes a shim frame to the frame stack (to cleanup after ``__init__``)
* 3. Pushes the frame for ``__init__`` to the frame stack
* */
ASSERT_KWNAMES_IS_NULL();
_PyCallCache *cache = (_PyCallCache *)next_instr;
DEOPT_IF(null != NULL, CALL);
DEOPT_IF(!PyType_Check(callable), CALL);
@ -4188,14 +4172,11 @@
args--;
total_args++;
}
int kwnames_len = KWNAMES_LEN();
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 - kwnames_len, kwnames);
kwnames = NULL;
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]);
@ -4210,7 +4191,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_BUILTIN_O) {
TARGET(CALL_BUILTIN_O) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -4219,7 +4200,6 @@
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
/* Builtin METH_O functions */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -4251,7 +4231,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_BUILTIN_FAST) {
TARGET(CALL_BUILTIN_FAST) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -4260,7 +4240,6 @@
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
/* Builtin METH_FASTCALL functions, without keywords */
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -4318,14 +4297,8 @@
_PyCFunctionFastWithKeywords cfunc =
(_PyCFunctionFastWithKeywords)(void(*)(void))
PyCFunction_GET_FUNCTION(callable);
res = cfunc(
PyCFunction_GET_SELF(callable),
args,
total_args - KWNAMES_LEN(),
kwnames
);
res = cfunc(PyCFunction_GET_SELF(callable), args, total_args, NULL);
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
kwnames = NULL;
/* Free the arguments. */
for (int i = 0; i < total_args; i++) {
@ -4341,7 +4314,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_LEN) {
TARGET(CALL_LEN) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -4349,7 +4322,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
/* len(o) */
int total_args = oparg;
if (self_or_null != NULL) {
@ -4378,7 +4350,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_ISINSTANCE) {
TARGET(CALL_ISINSTANCE) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -4386,7 +4358,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
/* isinstance(o, o2) */
int total_args = oparg;
if (self_or_null != NULL) {
@ -4417,14 +4388,13 @@
DISPATCH();
}
TARGET(CALL_NO_KW_LIST_APPEND) {
TARGET(CALL_LIST_APPEND) {
PyObject **args;
PyObject *self;
PyObject *callable;
args = stack_pointer - oparg;
self = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 1);
PyInterpreterState *interp = tstate->interp;
DEOPT_IF(callable != interp->callable_cache.list_append, CALL);
@ -4443,7 +4413,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) {
TARGET(CALL_METHOD_DESCRIPTOR_O) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -4451,7 +4421,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -4511,9 +4480,8 @@
int nargs = total_args - 1;
_PyCFunctionFastWithKeywords cfunc =
(_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));
kwnames = NULL;
/* Free the arguments. */
for (int i = 0; i < total_args; i++) {
@ -4529,7 +4497,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) {
TARGET(CALL_METHOD_DESCRIPTOR_NOARGS) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -4537,7 +4505,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
assert(oparg == 0 || oparg == 1);
int total_args = oparg;
if (self_or_null != NULL) {
@ -4572,7 +4539,7 @@
DISPATCH();
}
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) {
TARGET(CALL_METHOD_DESCRIPTOR_FAST) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
@ -4580,7 +4547,6 @@
args = stack_pointer - oparg;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
ASSERT_KWNAMES_IS_NULL();
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -4613,6 +4579,105 @@
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) {
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,
[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,
[INSTRUMENTED_CALL_FUNCTION_EX] = 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_CONST] = RETURN_CONST,
[INSTRUMENTED_CALL] = CALL,
[INSTRUMENTED_CALL_KW] = CALL_KW,
[INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
[INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE,
[INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD,
@ -90,6 +93,8 @@ static const uint8_t INSTRUMENTED_OPCODES[256] = {
[INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
[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,
[INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
[YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,

View File

@ -56,6 +56,7 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_FUNCTION_EX,
&&TARGET_CALL_INTRINSIC_1,
&&TARGET_CALL_INTRINSIC_2,
&&TARGET_CALL_KW,
&&TARGET_COMPARE_OP,
&&TARGET_CONTAINS_OP,
&&TARGET_CONVERT_VALUE,
@ -78,7 +79,6 @@ static void *opcode_targets[256] = {
&&TARGET_JUMP_BACKWARD,
&&TARGET_JUMP_BACKWARD_NO_INTERRUPT,
&&TARGET_JUMP_FORWARD,
&&TARGET_KW_NAMES,
&&TARGET_LIST_APPEND,
&&TARGET_LIST_EXTEND,
&&TARGET_LOAD_ATTR,
@ -161,24 +161,24 @@ static void *opcode_targets[256] = {
&&TARGET_BINARY_SUBSCR_LIST_INT,
&&TARGET_BINARY_SUBSCR_STR_INT,
&&TARGET_BINARY_SUBSCR_TUPLE_INT,
&&TARGET_CALL_ALLOC_AND_ENTER_INIT,
&&TARGET_CALL_BOUND_METHOD_EXACT_ARGS,
&&TARGET_CALL_BUILTIN_CLASS,
&&TARGET_CALL_BUILTIN_FAST,
&&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_NO_KW_ALLOC_AND_ENTER_INIT,
&&TARGET_CALL_NO_KW_BUILTIN_FAST,
&&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_METHOD_DESCRIPTOR_NOARGS,
&&TARGET_CALL_METHOD_DESCRIPTOR_O,
&&TARGET_CALL_PY_EXACT_ARGS,
&&TARGET_CALL_PY_WITH_DEFAULTS,
&&TARGET_CALL_STR_1,
&&TARGET_CALL_TUPLE_1,
&&TARGET_CALL_TYPE_1,
&&TARGET_COMPARE_OP_FLOAT,
&&TARGET_COMPARE_OP_INT,
&&TARGET_COMPARE_OP_STR,
@ -235,7 +235,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
&&TARGET_INSTRUMENTED_RESUME,
&&TARGET_INSTRUMENTED_END_FOR,
&&TARGET_INSTRUMENTED_END_SEND,
@ -245,6 +244,7 @@ static void *opcode_targets[256] = {
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
&&TARGET_INSTRUMENTED_FOR_ITER,
&&TARGET_INSTRUMENTED_CALL,
&&TARGET_INSTRUMENTED_CALL_KW,
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
&&TARGET_INSTRUMENTED_INSTRUCTION,
&&TARGET_INSTRUMENTED_JUMP_FORWARD,

View File

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