summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/dis.rst58
-rw-r--r--Include/internal/pycore_code.h2
-rw-r--r--Include/internal/pycore_opcode_metadata.h165
-rw-r--r--Include/opcode_ids.h103
-rw-r--r--Lib/_opcode_metadata.py127
-rw-r--r--Lib/importlib/_bootstrap_external.py3
-rw-r--r--Lib/test/test_descr.py10
-rw-r--r--Lib/test/test_dis.py46
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-09-07-20-52-27.gh-issue-105848.p799D1.rst3
-rw-r--r--Objects/frameobject.c14
-rw-r--r--Programs/test_frozenmain.h6
-rw-r--r--Python/abstract_interp_cases.c.h41
-rw-r--r--Python/bytecodes.c190
-rw-r--r--Python/ceval.c2
-rw-r--r--Python/ceval_macros.h5
-rw-r--r--Python/compile.c22
-rw-r--r--Python/executor_cases.c.h140
-rw-r--r--Python/flowgraph.c2
-rw-r--r--Python/generated_cases.c.h173
-rw-r--r--Python/instrumentation.c5
-rw-r--r--Python/opcode_targets.h28
-rw-r--r--Python/specialize.c82
22 files changed, 719 insertions, 508 deletions
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index d087c7c..b835f1e 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -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:
+ 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
@@ -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]``.
diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h
index 257b058..a77fa11 100644
--- a/Include/internal/pycore_code.h
+++ b/Include/internal/pycore_code.h
@@ -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,
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index 4086b30..856c3ac 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -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: \
;
diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h
index 8af9684..ba25bd4 100644
--- a/Include/opcode_ids.h
+++ b/Include/opcode_ids.h
@@ -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
diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py
index 4f76371..5dd06ae 100644
--- a/Lib/_opcode_metadata.py
+++ b/Lib/_opcode_metadata.py
@@ -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
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index d671d17..0019897 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -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
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index f6bd909..35ddb79 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -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):
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 0f066d8..568200c 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -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),
]
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-07-20-52-27.gh-issue-105848.p799D1.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-20-52-27.gh-issue-105848.p799D1.rst
new file mode 100644
index 0000000..14661d1
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-07-20-52-27.gh-issue-105848.p799D1.rst
@@ -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.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 53764a4..d754443 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -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;
diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h
index c208272..4fb78cf 100644
--- a/Programs/test_frozenmain.h
+++ b/Programs/test_frozenmain.h
@@ -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,
diff --git a/Python/abstract_interp_cases.c.h b/Python/abstract_interp_cases.c.h
index 1b96ca1..5a3848c 100644
--- a/Python/abstract_interp_cases.c.h
+++ b/Python/abstract_interp_cases.c.h
@@ -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);
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 08d91b5..e5be62c 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -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);
}
diff --git a/Python/ceval.c b/Python/ceval.c
index b02bf60..cae29e0 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -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)) {
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index f5d9155..012750d 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -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)))
diff --git a/Python/compile.c b/Python/compile.c
index 1f08e46..b05c1ad 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -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:
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 8f3febe..befb972 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -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--;
diff --git a/Python/flowgraph.c b/Python/flowgraph.c
index 55b871d..44858b9 100644
--- a/Python/flowgraph.c
+++ b/Python/flowgraph.c
@@ -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);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 9742c95..fff47a1 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -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);
}
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index fee6eae..0768c82 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -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,
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index f00eb31..bcd6ea7 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -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,
diff --git a/Python/specialize.c b/Python/specialize.c
index 47e0bd7..d9b748c 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -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.