Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6ad9f7b

Browse files
authoredJan 29, 2022
Revert "bpo-46329: Split calls into precall and call instructions. (GH-30855)"
This reverts commit 89fd7c3.
1 parent 8fb3649 commit 6ad9f7b

File tree

16 files changed

+629
-912
lines changed

16 files changed

+629
-912
lines changed
 

‎Doc/library/dis.rst

+30-40
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,10 @@ the following command can be used to display the disassembly of
3434
:func:`myfunc`::
3535

3636
>>> dis.dis(myfunc)
37-
1 0 RESUME 0
38-
39-
2 2 LOAD_GLOBAL 0 (len)
40-
4 LOAD_FAST 0 (alist)
41-
6 PRECALL_FUNCTION 1
42-
8 CALL 0
43-
10 RETURN_VALUE
37+
2 0 LOAD_GLOBAL 0 (len)
38+
2 LOAD_FAST 0 (alist)
39+
4 CALL_NO_KW 1
40+
6 RETURN_VALUE
4441

4542
(The "2" is a line number).
4643

@@ -105,11 +102,9 @@ Example::
105102
>>> for instr in bytecode:
106103
... print(instr.opname)
107104
...
108-
RESUME
109105
LOAD_GLOBAL
110106
LOAD_FAST
111-
PRECALL_FUNCTION
112-
CALL
107+
CALL_NO_KW
113108
RETURN_VALUE
114109

115110

@@ -622,7 +617,7 @@ iterations of the loop.
622617
.. opcode:: LOAD_BUILD_CLASS
623618

624619
Pushes :func:`builtins.__build_class__` onto the stack. It is later called
625-
to construct a class.
620+
by :opcode:`CALL_NO_KW` to construct a class.
626621

627622

628623
.. opcode:: BEFORE_WITH (delta)
@@ -1063,19 +1058,30 @@ iterations of the loop.
10631058
with ``__cause__`` set to ``TOS``)
10641059

10651060

1066-
.. opcode:: CALL (named)
1061+
.. opcode:: CALL_NO_KW (argc)
1062+
1063+
Calls a callable object with positional arguments.
1064+
*argc* indicates the number of positional arguments.
1065+
The top of the stack contains positional arguments, with the right-most
1066+
argument on top. Below the arguments is a callable object to call.
1067+
``CALL_NO_KW`` pops all arguments and the callable object off the stack,
1068+
calls the callable object with those arguments, and pushes the return value
1069+
returned by the callable object.
1070+
1071+
.. versionadded:: 3.11
10671072

1068-
Calls a callable object with the number of positional arguments specified by
1069-
the preceding :opcode:`PRECALL_FUNCTION` or :opcode:`PRECALL_METHOD` and
1070-
the named arguments specified by the preceding :opcode:`KW_NAMES`, if any.
1071-
*named* indicates the number of named arguments.
1072-
On the stack are (in ascending order):
10731073

1074-
* The callable
1075-
* The positional arguments
1076-
* The named arguments
1074+
.. opcode:: CALL_KW (argc)
10771075

1078-
``CALL`` pops all arguments and the callable object off the stack,
1076+
Calls a callable object with positional (if any) and keyword arguments.
1077+
*argc* indicates the total number of positional and keyword arguments.
1078+
The top element on the stack contains a tuple with the names of the
1079+
keyword arguments, which must be strings.
1080+
Below that are the values for the keyword arguments,
1081+
in the order corresponding to the tuple.
1082+
Below that are positional arguments, with the right-most parameter on
1083+
top. Below the arguments is a callable object to call.
1084+
``CALL_KW`` pops all arguments and the callable object off the stack,
10791085
calls the callable object with those arguments, and pushes the return value
10801086
returned by the callable object.
10811087

@@ -1102,7 +1108,7 @@ iterations of the loop.
11021108
Loads a method named ``co_names[namei]`` from the TOS object. TOS is popped.
11031109
This bytecode distinguishes two cases: if TOS has a method with the correct
11041110
name, the bytecode pushes the unbound method and TOS. TOS will be used as
1105-
the first argument (``self``) by :opcode:`PRECALL_METHOD` when calling the
1111+
the first argument (``self``) by :opcode:`CALL_METHOD` when calling the
11061112
unbound method. Otherwise, ``NULL`` and the object return by the attribute
11071113
lookup are pushed.
11081114

@@ -1111,30 +1117,14 @@ iterations of the loop.
11111117

11121118
.. opcode:: PRECALL_METHOD (argc)
11131119

1114-
Prefixes :opcode:`CALL` (possibly with an intervening ``KW_NAMES``).
1120+
Prefixes either :opcode:`CALL_NO_KW` or :opcode:`CALL_KW`.
11151121
This opcode is designed to be used with :opcode:`LOAD_METHOD`.
1116-
Sets internal variables, so that :opcode:`CALL`
1122+
Sets internal variables, so that :opcode:`CALL_NO_KW` or :opcode:`CALL_KW`
11171123
clean up after :opcode:`LOAD_METHOD` correctly.
11181124

11191125
.. versionadded:: 3.11
11201126

11211127

1122-
.. opcode:: PRECALL_FUNCTION (args)
1123-
1124-
Prefixes :opcode:`CALL` (possibly with an intervening ``KW_NAMES``).
1125-
Sets internal variables, so that :opcode:`CALL` can execute correctly.
1126-
1127-
.. versionadded:: 3.11
1128-
1129-
1130-
.. opcode:: KW_NAMES (i)
1131-
1132-
Stores a reference to ``co_consts[consti]`` into an internal variable
1133-
for use by :opcode:`CALL`. ``co_consts[consti]`` must be a tuple of strings.
1134-
1135-
.. versionadded:: 3.11
1136-
1137-
11381128
.. opcode:: MAKE_FUNCTION (flags)
11391129

11401130
Pushes a new function object on the stack. From bottom to top, the consumed

‎Doc/whatsnew/3.11.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,7 @@ CPython bytecode changes
400400

401401
* Replaced the three call instructions: :opcode:`CALL_FUNCTION`,
402402
:opcode:`CALL_FUNCTION_KW` and :opcode:`CALL_METHOD` with
403-
:opcode:`PRECALL_FUNCTION`, :opcode:`PRECALL_METHOD`, :opcode:`CALL`,
404-
and :opcode:`KW_NAMES`.
403+
:opcode:`CALL_NO_KW`, :opcode:`CALL_KW` and :opcode:`PRECALL_METHOD`.
405404
This decouples the argument shifting for methods from the handling of
406405
keyword arguments and allows better specialization of calls.
407406

‎Include/internal/pycore_code.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ typedef struct {
3838

3939
typedef struct {
4040
uint32_t func_version;
41-
uint16_t min_args;
41+
uint16_t defaults_start;
4242
uint16_t defaults_len;
4343
} _PyCallCache;
4444

@@ -271,8 +271,7 @@ int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNI
271271
int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache);
272272
int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache);
273273
int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr);
274-
int _Py_Specialize_CallNoKw(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
275-
PyObject *kwnames, SpecializedCacheEntry *cache, PyObject *builtins);
274+
int _Py_Specialize_CallNoKw(PyObject *callable, _Py_CODEUNIT *instr, int nargs, SpecializedCacheEntry *cache, PyObject *builtins);
276275
void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
277276
SpecializedCacheEntry *cache);
278277
void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, SpecializedCacheEntry *cache);

‎Include/internal/pycore_frame.h

-3
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,6 @@ _PyThreadState_BumpFramePointer(PyThreadState *tstate, size_t size)
189189

190190
void _PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame *frame);
191191

192-
InterpreterFrame *
193-
_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func);
194-
195192
#ifdef __cplusplus
196193
}
197194
#endif

‎Include/opcode.h

+36-43
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Lib/importlib/_bootstrap_external.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -384,14 +384,9 @@ def _write_atomic(path, data, mode=0o666):
384384
# Python 3.11a5 3476 (Add ASYNC_GEN_WRAP opcode)
385385
# Python 3.11a5 3477 (Replace DUP_TOP/DUP_TOP_TWO with COPY and
386386
# ROT_TWO/ROT_THREE/ROT_FOUR/ROT_N with SWAP)
387-
# Python 3.11a5 3478 (New CALL opcodes)
388387

389388
# Python 3.12 will start with magic number 3500
390389

391-
392-
# Python 3.12 will start with magic number 3500
393-
394-
395390
#
396391
# MAGIC must change whenever the bytecode emitted by the compiler may no
397392
# longer be understood by older implementations of the eval loop (usually
@@ -402,7 +397,7 @@ def _write_atomic(path, data, mode=0o666):
402397
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
403398
# in PC/launcher.c must also be updated.
404399

405-
MAGIC_NUMBER = (3478).to_bytes(2, 'little') + b'\r\n'
400+
MAGIC_NUMBER = (3477).to_bytes(2, 'little') + b'\r\n'
406401
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
407402

408403
_PYCACHE = '__pycache__'

‎Lib/opcode.py

+5-13
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,9 @@ def jabs_op(name, op):
188188
def_op('DICT_MERGE', 164)
189189
def_op('DICT_UPDATE', 165)
190190

191-
def_op('PRECALL_FUNCTION', 167)
192191
def_op('PRECALL_METHOD', 168)
193-
194-
def_op('CALL', 171)
195-
def_op('KW_NAMES', 172)
196-
hasconst.append(172)
192+
def_op('CALL_NO_KW', 169)
193+
def_op('CALL_KW', 170)
197194

198195
del def_op, name_op, jrel_op, jabs_op
199196

@@ -248,21 +245,16 @@ def jabs_op(name, op):
248245
"STORE_SUBSCR_ADAPTIVE",
249246
"STORE_SUBSCR_LIST_INT",
250247
"STORE_SUBSCR_DICT",
251-
"CALL_ADAPTIVE",
252-
"CALL_BUILTIN_CLASS",
248+
"CALL_NO_KW_ADAPTIVE",
253249
"CALL_NO_KW_BUILTIN_O",
254250
"CALL_NO_KW_BUILTIN_FAST",
255-
"CALL_BUILTIN_FAST_WITH_KEYWORDS",
256251
"CALL_NO_KW_LEN",
257252
"CALL_NO_KW_ISINSTANCE",
258-
"CALL_PY_EXACT_ARGS",
259-
"CALL_PY_WITH_DEFAULTS",
253+
"CALL_NO_KW_PY_SIMPLE",
260254
"CALL_NO_KW_LIST_APPEND",
261255
"CALL_NO_KW_METHOD_DESCRIPTOR_O",
262-
"CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
263-
"CALL_NO_KW_STR_1",
264-
"CALL_NO_KW_TUPLE_1",
265256
"CALL_NO_KW_TYPE_1",
257+
"CALL_NO_KW_BUILTIN_CLASS_1",
266258
"CALL_NO_KW_METHOD_DESCRIPTOR_FAST",
267259
"JUMP_ABSOLUTE_QUICK",
268260
"LOAD_ATTR_ADAPTIVE",

‎Lib/test/test_compile.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -837,8 +837,9 @@ def foo(x):
837837
opcodes = list(dis.get_instructions(func))
838838
instructions = [opcode.opname for opcode in opcodes]
839839
self.assertNotIn('LOAD_METHOD', instructions)
840+
self.assertNotIn('CALL_METHOD', instructions)
840841
self.assertIn('LOAD_ATTR', instructions)
841-
self.assertIn('PRECALL_FUNCTION', instructions)
842+
self.assertIn('CALL_NO_KW', instructions)
842843

843844
def test_lineno_procedure_call(self):
844845
def call():
@@ -1095,7 +1096,7 @@ def test_multiline_expression(self):
10951096
)
10961097
"""
10971098
compiled_code, _ = self.check_positions_against_ast(snippet)
1098-
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL',
1099+
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL_NO_KW',
10991100
line=1, end_line=3, column=0, end_column=1)
11001101

11011102
def test_very_long_line_end_offset(self):
@@ -1105,7 +1106,7 @@ def test_very_long_line_end_offset(self):
11051106
snippet = f"g('{long_string}')"
11061107

11071108
compiled_code, _ = self.check_positions_against_ast(snippet)
1108-
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL',
1109+
self.assertOpcodeSourcePositionIs(compiled_code, 'CALL_NO_KW',
11091110
line=1, end_line=1, column=None, end_column=None)
11101111

11111112
def test_complex_single_line_expression(self):

0 commit comments

Comments
 (0)
Please sign in to comment.