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
.. 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:
+ Calls a callable object with the number of arguments specified by ``argc``.
+ On the stack are (in ascending order):
- * NULL
* The callable
- * The positional arguments
- * The named arguments
-
- or:
-
- * 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
.. 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)
.. 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]``.
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,
return 1;
case LOAD_ATTR_METHOD_LAZY_DICT:
return 1;
- case KW_NAMES:
- return 0;
case INSTRUMENTED_CALL:
return 0;
case CALL:
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:
return 1;
case LOAD_ATTR_METHOD_LAZY_DICT:
return 2;
- case KW_NAMES:
- return 0;
case INSTRUMENTED_CALL:
return 0;
case CALL:
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;
[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 },
[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 },
[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 } } },
[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",
[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",
[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",
[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",
[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,
[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,
[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,
case 233: \
case 234: \
case 235: \
- case 236: \
case 255: \
;
#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
#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
#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
"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",
],
}
'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,
'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,
'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,
'SETUP_WITH': 266,
'STORE_FAST_MAYBE_NULL': 267,
}
-MIN_INSTRUMENTED_OPCODE = 237
+MIN_INSTRUMENTED_OPCODE = 236
HAVE_ARGUMENT = 45
# 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
# 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
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):
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,
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):
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")
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
]
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),
]
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),
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),
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),
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),
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),
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),
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),
]
--- /dev/null
+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.
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;
}
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;
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,
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);
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);
unsigned int oparg,
_Py_CODEUNIT *next_instr,
PyObject **stack_pointer,
- PyObject *kwnames,
int throwflag,
PyObject *args[]
)
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;
}
// 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--;
_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);
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 &&
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,
/* 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];
}
}
}
- kwnames = NULL;
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable);
for (int i = 0; i < total_args; i++) {
}
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);
_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) {
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];
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);
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);
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);
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]);
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--;
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--;
_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++) {
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) {
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) {
}
// 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);
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--;
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++) {
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) {
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--;
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);
}
#endif
_PyInterpreterFrame entry_frame;
- PyObject *kwnames = NULL; // Borrowed reference. Reset by CALL instructions.
pop_1_error:
STACK_SHRINK(1);
error:
- kwnames = NULL;
/* Double-check exception status. */
#ifdef NDEBUG
if (!_PyErr_Occurred(tstate)) {
" 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) { \
[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)))
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;
}
}
/* 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,
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;
}
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:
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);
break;
}
- case CALL_NO_KW_TYPE_1: {
+ case CALL_TYPE_1: {
PyObject **args;
PyObject *null;
PyObject *callable;
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];
break;
}
- case CALL_NO_KW_STR_1: {
+ case CALL_STR_1: {
PyObject **args;
PyObject *null;
PyObject *callable;
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);
break;
}
- case CALL_NO_KW_TUPLE_1: {
+ case CALL_TUPLE_1: {
PyObject **args;
PyObject *null;
PyObject *callable;
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);
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;
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--;
break;
}
- case CALL_NO_KW_BUILTIN_FAST: {
+ case CALL_BUILTIN_FAST: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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--;
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;
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) {
break;
}
- case CALL_NO_KW_ISINSTANCE: {
+ case CALL_ISINSTANCE: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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) {
break;
}
- case CALL_NO_KW_METHOD_DESCRIPTOR_O: {
+ case CALL_METHOD_DESCRIPTOR_O: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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--;
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;
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) {
break;
}
- case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: {
+ case CALL_METHOD_DESCRIPTOR_FAST: {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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--;
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);
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;
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--;
_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);
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 &&
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,
/* 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];
}
}
}
- kwnames = NULL;
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
Py_DECREF(callable);
for (int i = 0; i < total_args; i++) {
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);
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);
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) {
DISPATCH_INLINED(new_frame);
}
- TARGET(CALL_NO_KW_TYPE_1) {
+ TARGET(CALL_TYPE_1) {
PyObject **args;
PyObject *null;
PyObject *callable;
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];
DISPATCH();
}
- TARGET(CALL_NO_KW_STR_1) {
+ TARGET(CALL_STR_1) {
PyObject **args;
PyObject *null;
PyObject *callable;
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);
DISPATCH();
}
- TARGET(CALL_NO_KW_TUPLE_1) {
+ TARGET(CALL_TUPLE_1) {
PyObject **args;
PyObject *null;
PyObject *callable;
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);
DISPATCH();
}
- TARGET(CALL_NO_KW_ALLOC_AND_ENTER_INIT) {
+ TARGET(CALL_ALLOC_AND_ENTER_INIT) {
PyObject **args;
PyObject *null;
PyObject *callable;
* 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);
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]);
DISPATCH();
}
- TARGET(CALL_NO_KW_BUILTIN_O) {
+ TARGET(CALL_BUILTIN_O) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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--;
DISPATCH();
}
- TARGET(CALL_NO_KW_BUILTIN_FAST) {
+ TARGET(CALL_BUILTIN_FAST) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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--;
_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++) {
DISPATCH();
}
- TARGET(CALL_NO_KW_LEN) {
+ TARGET(CALL_LEN) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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) {
DISPATCH();
}
- TARGET(CALL_NO_KW_ISINSTANCE) {
+ TARGET(CALL_ISINSTANCE) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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) {
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);
DISPATCH();
}
- TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) {
+ TARGET(CALL_METHOD_DESCRIPTOR_O) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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--;
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++) {
DISPATCH();
}
- TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) {
+ TARGET(CALL_METHOD_DESCRIPTOR_NOARGS) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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) {
DISPATCH();
}
- TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) {
+ TARGET(CALL_METHOD_DESCRIPTOR_FAST) {
PyObject **args;
PyObject *self_or_null;
PyObject *callable;
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--;
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);
}
[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,
[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,
[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,
&&TARGET_CALL_FUNCTION_EX,
&&TARGET_CALL_INTRINSIC_1,
&&TARGET_CALL_INTRINSIC_2,
+ &&TARGET_CALL_KW,
&&TARGET_COMPARE_OP,
&&TARGET_CONTAINS_OP,
&&TARGET_CONVERT_VALUE,
&&TARGET_JUMP_BACKWARD,
&&TARGET_JUMP_BACKWARD_NO_INTERRUPT,
&&TARGET_JUMP_FORWARD,
- &&TARGET_KW_NAMES,
&&TARGET_LIST_APPEND,
&&TARGET_LIST_EXTEND,
&&TARGET_LOAD_ATTR,
&&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,
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_INSTRUMENTED_RESUME,
&&TARGET_INSTRUMENTED_END_FOR,
&&TARGET_INSTRUMENTED_END_SEND,
&&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,
#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
}
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;
}
}
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;
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)) {
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: {
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: {
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;
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;
}
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;
(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;
/* 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: {
#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);
_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;
}
}
/* 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.