Skip to content

Commit 6174448

Browse files
Preserve the LOAD_CLOSURE opcode as an alias for LOAD_FAST.
1 parent 37d3ab7 commit 6174448

File tree

10 files changed

+41
-39
lines changed

10 files changed

+41
-39
lines changed

Doc/library/dis.rst

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,20 +1043,7 @@ All of the following opcodes use their arguments.
10431043

10441044
.. opcode:: LOAD_FAST (var_num)
10451045

1046-
Pushes a reference to a local variable or closure cell onto the stack.
1047-
The corresponding variable name is
1048-
``(co_varnames + co_cellvars + co_freevars)[var_num]``.
1049-
1050-
For closures, note that ``LOAD_FAST`` loads the cell object contained
1051-
in the corresponding slot of the cell and free variable storage,
1052-
at index ``var_num - len(co_varnames)``.
1053-
In contrast, ``LOAD_DEREF`` gets the object the cell references.
1054-
1055-
Use of ``LOAD_FAST`` for closures is primarily to share cells objects
1056-
from an outer closure when creating an inner one with ``MAKE_FUNCTION``.
1057-
1058-
.. versionchanged:: 3.10
1059-
Closure cells are handled here now instead of ``LOAD_CLOSURE`` (removed).
1046+
Pushes a reference to the local ``co_varnames[var_num]`` onto the stack.
10601047

10611048

10621049
.. opcode:: STORE_FAST (var_num)
@@ -1069,6 +1056,19 @@ All of the following opcodes use their arguments.
10691056
Deletes local ``co_varnames[var_num]``.
10701057

10711058

1059+
.. opcode:: LOAD_CLOSURE (i)
1060+
1061+
Pushes a reference to the cell contained in slot ``i - len(co_varnames)``
1062+
of the cell and free variable storage. The name of the variable is
1063+
``(co_varnames + co_cellvars + co_freevars)[i]``.
1064+
1065+
Note that ``LOAD_CLOSURE`` is effectively an alias for ``LOAD_FAST``.
1066+
It exists to keep bytecode a little more readable.
1067+
1068+
.. versionchanged:: 3.10
1069+
``i`` is offset by the length of ``co_varnames``.
1070+
1071+
10721072
.. opcode:: LOAD_DEREF (i)
10731073

10741074
Loads the cell contained in slot ``i - len(co_varnames)`` of the cell

Include/opcode.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/opcode.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ def jabs_op(name, op):
181181
def_op('MAKE_FUNCTION', 132) # Flags
182182
def_op('BUILD_SLICE', 133) # Number of items
183183

184+
def_op('LOAD_CLOSURE', 135)
185+
hasfree.append(135)
184186
def_op('LOAD_DEREF', 136)
185187
hasfree.append(136)
186188
def_op('STORE_DEREF', 137)

Lib/test/test_dis.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ def foo(x):
427427
return foo
428428

429429
dis_nested_0 = """\
430-
%3d 0 LOAD_FAST 2 (y)
430+
%3d 0 LOAD_CLOSURE 2 (y)
431431
2 BUILD_TUPLE 1
432432
4 LOAD_CONST 1 (<code object foo at 0x..., file "%s", line %d>)
433433
6 LOAD_CONST 2 ('_h.<locals>.foo')
@@ -444,7 +444,7 @@ def foo(x):
444444

445445
dis_nested_1 = """%s
446446
Disassembly of <code object foo at 0x..., file "%s", line %d>:
447-
%3d 0 LOAD_FAST 1 (x)
447+
%3d 0 LOAD_CLOSURE 1 (x)
448448
2 BUILD_TUPLE 1
449449
4 LOAD_CONST 1 (<code object <listcomp> at 0x..., file "%s", line %d>)
450450
6 LOAD_CONST 2 ('_h.<locals>.foo.<locals>.<listcomp>')
@@ -962,8 +962,8 @@ def jumpy():
962962
Instruction = dis.Instruction
963963
expected_opinfo_outer = [
964964
Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval=(3, 4), argrepr='(3, 4)', offset=0, starts_line=2, is_jump_target=False),
965-
Instruction(opname='LOAD_FAST', opcode=124, arg=3, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
966-
Instruction(opname='LOAD_FAST', opcode=124, arg=4, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
965+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
966+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=4, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
967967
Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=6, starts_line=None, is_jump_target=False),
968968
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=8, starts_line=None, is_jump_target=False),
969969
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f', argrepr="'outer.<locals>.f'", offset=10, starts_line=None, is_jump_target=False),
@@ -985,10 +985,10 @@ def jumpy():
985985

986986
expected_opinfo_f = [
987987
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(5, 6), argrepr='(5, 6)', offset=0, starts_line=3, is_jump_target=False),
988-
Instruction(opname='LOAD_FAST', opcode=124, arg=5, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
989-
Instruction(opname='LOAD_FAST', opcode=124, arg=6, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
990-
Instruction(opname='LOAD_FAST', opcode=124, arg=3, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
991-
Instruction(opname='LOAD_FAST', opcode=124, arg=4, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
988+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=5, argval='a', argrepr='a', offset=2, starts_line=None, is_jump_target=False),
989+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=6, argval='b', argrepr='b', offset=4, starts_line=None, is_jump_target=False),
990+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=3, argval='c', argrepr='c', offset=6, starts_line=None, is_jump_target=False),
991+
Instruction(opname='LOAD_CLOSURE', opcode=135, arg=4, argval='d', argrepr='d', offset=8, starts_line=None, is_jump_target=False),
992992
Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=10, starts_line=None, is_jump_target=False),
993993
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=12, starts_line=None, is_jump_target=False),
994994
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='outer.<locals>.f.<locals>.inner', argrepr="'outer.<locals>.f.<locals>.inner'", offset=14, starts_line=None, is_jump_target=False),
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
Compute cell offsets relative to locals in compiler. Allows the interpreter
22
to treats locals and cells a single array, which is slightly more efficient.
3-
4-
Delete the LOAD_CLOSURE bytecode.
3+
Also make the LOAD_CLOSURE opcode an alias for LOAD_FAST. Preserving
4+
LOAD_CLOSURE helps keep bytecode a bit more readable.

Python/ceval.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,6 +1814,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
18141814
DISPATCH();
18151815
}
18161816

1817+
/* We keep LOAD_CLOSURE so that the bytecode stays more readable. */
1818+
case TARGET(LOAD_CLOSURE):
18171819
case TARGET(LOAD_FAST): {
18181820
PyObject *value = GETLOCAL(oparg);
18191821
if (value == NULL) {

Python/compile.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,6 @@
7575
#define SETUP_WITH 253
7676
#define POP_BLOCK 252
7777

78-
/* Artificial instruction, will be converted to LOAD_FAST */
79-
#define LOAD_CLOSURE 251
80-
8178
#define IS_TOP_LEVEL_AWAIT(c) ( \
8279
(c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
8380
&& (c->u->u_ste->ste_type == ModuleBlock))
@@ -1193,6 +1190,8 @@ stack_effect(int opcode, int oparg, int jump)
11931190
return -1;
11941191

11951192
/* Closures */
1193+
case LOAD_CLOSURE:
1194+
return 1;
11961195
case LOAD_DEREF:
11971196
case LOAD_CLASSDEREF:
11981197
return 1;
@@ -7285,8 +7284,6 @@ offset_derefs(basicblock *entryblock, int nlocals)
72857284
struct instr *inst = &b->b_instr[i];
72867285
switch(inst->i_opcode) {
72877286
case LOAD_CLOSURE:
7288-
inst->i_opcode = LOAD_FAST;
7289-
/* fall through */
72907287
case LOAD_DEREF:
72917288
case STORE_DEREF:
72927289
case DELETE_DEREF:

Python/importlib.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/importlib_external.h

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/opcode_targets.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)