8000 Don't load StopIteration as a constant · python/cpython@d557e41 · GitHub
[go: up one dir, main page]

Skip to content

Commit d557e41

Browse files
committed
Don't load StopIteration as a constant
1 parent 819e0df commit d557e41

File tree

14 files changed

+60
-67
lines changed

14 files changed

+60
-67
lines changed

Doc/library/dis.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -671,12 +671,14 @@ iterations of the loop.
671671
Exception representation on the stack now consist of one, not three, items.
672672

673673

674-
.. opcode:: LOAD_ASSERTION_ERROR
674+
.. opcode:: LOAD_EXCEPTION_TYPE (type)
675675

676-
Pushes :exc:`AssertionError` onto the stack. Used by the :keyword:`assert`
677-
statement.
676+
Pushes an exception type onto the stack, depending on the value of *type*:
678677

679-
.. versionadded:: 3.9
678+
* ``0``: :exc:`AssertionError`
679+
* ``1``: :exc:`StopIteration`
680+
681+
.. versionadded:: 3.11
680682

681683

682684
.. opcode:: LOAD_BUILD_CLASS

Include/internal/pycore_opcode.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.

Include/opcode.h

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

Lib/dis.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
LOAD_GLOBAL = opmap['LOAD_GLOBAL']
3232
BINARY_OP = opmap['BINARY_OP']
3333
JUMP_BACKWARD = opmap['JUMP_BACKWARD']
34+
LOAD_EXCEPTION_TYPE = opmap['LOAD_EXCEPTION_TYPE']
3435

3536
CACHE = opmap["CACHE"]
3637

@@ -491,6 +492,8 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
491492
if arg & (1<<i))
492493
elif deop == BINARY_OP:
493494
_, argrepr = _nb_ops[arg]
495+
elif deop == LOAD_EXCEPTION_TYPE:
496+
argrepr = "StopIteration" if arg else "AssertionError"
494497
yield Instruction(_all_opname[op], op,
495498
arg, argval, argrepr,
496499
offset, starts_line, is_jump_target, positions)

Lib/importlib/_bootstrap_external.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,11 @@ def _write_atomic(path, data, mode=0o666):
402402
# add JUMP_BACKWARD_NO_INTERRUPT, make JUMP_NO_INTERRUPT virtual)
403403
# Python 3.11a7 3492 (make POP_JUMP_IF_NONE/NOT_NONE/TRUE/FALSE relative)
404404
# Python 3.11a7 3493 (Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative)
405-
# Python 3.11a7 3494 (New location info table)
406-
# Python 3.12 will start with magic number 3500
405+
# Python 3.11a7 3494 (New location info table)
406+
# Python 3.11a7 3495 (Replace LOAD_ASSERTION_ERROR with LOAD_EXCEPTION_TYPE)
407+
407408

409+
# Python 3.12 will start with magic number 3500
408410

409411
#
410412
# MAGIC must change whenever the bytecode emitted by the compiler may no
@@ -416,7 +418,7 @@ def _write_atomic(path, data, mode=0o666):
416418
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
417419
# in PC/launcher.c must also be updated.
418420

419-
MAGIC_NUMBER = (3494).to_bytes(2, 'little') + b'\r\n'
421+
MAGIC_NUMBER = (3495).to_bytes(2, 'little') + b'\r\n'
420422

421423
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
422424

Lib/opcode.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ def jabs_op(name, op, entries=0):
9494
def_op('PRINT_EXPR', 70)
9595
def_op('LOAD_BUILD_CLASS', 71)
9696

97-
def_op('LOAD_ASSERTION_ERROR', 74)
9897
def_op('RETURN_GENERATOR', 75)
9998

10099
def_op('LIST_TO_TUPLE', 82)
@@ -166,7 +165,7 @@ def jabs_op(name, op, entries=0):
166165
def_op('DELETE_DEREF', 139)
167166
hasfree.append(139)
168167
jrel_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards)
169-
168+
def_op('LOAD_EXCEPTION_TYPE', 141)
170169
def_op('CALL_FUNCTION_EX', 142) # Flags
171170

172171
def_op('EXTENDED_ARG', 144)

Lib/test/test_dis.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def bug1333982(x=[]):
169169
dis_bug1333982 = """\
170170
%3d RESUME 0
171171
172-
%3d LOAD_ASSERTION_ERROR
172+
%3d LOAD_EXCEPTION_TYPE 0 (AssertionError)
173173
LOAD_CONST 2 (<code object <listcomp> at 0x..., file "%s", line %d>)
174174
MAKE_FUNCTION 0
175175
LOAD_FAST 0 (x)
@@ -1171,7 +1171,6 @@ async def async_def():
11711171
Constants:
11721172
0: None
11731173
1: 1
1174-
2: <class 'StopIteration'>
11751174
Names:
11761175
0: value
11771176
1: b

Objects/codeobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,8 @@ PyCode_New(int argcount, int kwonlyargcount,
628628
}
629629

630630
static const char assert0[4] = {
631-
LOAD_ASSERTION_ERROR,
632-
0,
631+
LOAD_EXCEPTION_TYPE,
632+
0, // AssertionError
633633
RAISE_VARARGS,
634634
1
635635
};

Objects/exceptions.c

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -600,23 +600,17 @@ StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg)
600600
return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg);
601601
}
602602

603-
// Don't use ComplexExtendsException for this, since deepfreeze doesn't work if
604-
// the type is static:
605-
PyTypeObject _PyExc_StopIteration = {
606-
PyVarObject_HEAD_INIT(NULL, 0)
607-
.tp_name = "StopIteration",
608-
.tp_basicsize = sizeof(PyStopIterationObject),
609-
.tp_dealloc = (destructor)StopIteration_dealloc,
610-
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
611-
.tp_doc = PyDoc_STR("Signal the end from iterator.__next__()."),
612-
.tp_traverse = (traverseproc)StopIteration_traverse,
613-
.tp_clear = (inquiry)StopIteration_clear,
614-
.tp_members = StopIteration_members,
615-
.tp_base = &_PyExc_Exception,
616-
.tp_dictoffset = offsetof(PyStopIterationObject, dict),
617-
.tp_init = (initproc)StopIteration_init,
618-
};
619-
PyObject *PyExc_StopIteration = (PyObject *)&_PyExc_StopIteration;
603+
ComplexExtendsException(
604+
PyExc_Exception, /* base */
605+
StopIteration, /* name */
606+
StopIteration, /* prefix for *_init, etc */
607+
0, /* new */
608+
0, /* methods */
609+
StopIteration_members, /* members */
610+
0, /* getset */
611+
0, /* str */
612+
"Signal the end from iterator.__next__()."
613+
);
620614

621615

622616
/*

Python/ceval.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,8 +2778,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
27782778
}
27792779
}
27802780

2781-
TARGET(LOAD_ASSERTION_ERROR) {
2782-
PyObject *value = PyExc_AssertionError;
2781+
TARGET(LOAD_EXCEPTION_TYPE) {
2782+
assert(oparg < 2);
2783+
PyObject *value = oparg ? PyExc_StopIteration: PyExc_AssertionError;
27832784
Py_INCREF(value);
27842785
PUSH(value);
27852786
DISPATCH();

Python/compile.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,7 @@ stack_effect(int opcode, int oparg, int jump)
11691169
return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0;
11701170
case LOAD_METHOD:
11711171
return 1;
1172-
case LOAD_ASSERTION_ERROR:
1172+
case LOAD_EXCEPTION_TYPE:
11731173
return 1;
11741174
case LIST_TO_TUPLE:
11751175
return 0;
@@ -1961,7 +1961,6 @@ compiler_add_yield_from(struct compiler *c, int await)
19611961
RETURN_IF_FALSE(stopiter = compiler_new_block(c));
19621962
RETURN_IF_FALSE(error = compiler_new_block(c));
19631963
RETURN_IF_FALSE(exit = compiler_new_block(c));
1964-
19651964
compiler_use_next_block(c, start);
19661965
ADDOP_JUMP(c, SEND, exit);
19671966
compiler_use_next_block(c, resume);
@@ -1976,7 +1975,7 @@ compiler_add_yield_from(struct compiler *c, int await)
19761975
ADDOP_I(c, RESUME, await ? 3 : 2);
19771976
ADDOP_JUMP(c, JUMP_NO_INTERRUPT, start);
19781977
compiler_use_next_block(c, stopiter);
1979-
ADDOP_LOAD_CONST(c, PyExc_StopIteration); // StopIteration is marshallable!
1978+
ADDOP_I(c, LOAD_EXCEPTION_TYPE, 1); // StopIteration
19801979
ADDOP(c, CHECK_EXC_MATCH);
19811980
ADDOP_JUMP(c, POP_JUMP_IF_FALSE, error);
19821981
// StopIteration was raised. Push the return value and continue execution:
@@ -4018,7 +4017,7 @@ compiler_assert(struct compiler *c, stmt_ty s)
40184017
return 0;
40194018
if (!compiler_jump_if(c, s->v.Assert.test, end, 1))
40204019
return 0;
4021-
ADDOP(c, LOAD_ASSERTION_ERROR);
4020+
ADDOP_I(c, LOAD_EXCEPTION_TYPE, 0); // AssertionError
40224021
if (s->v.Assert.msg) {
40234022
VISIT(c, expr, s->v.Assert.msg);
40244023
ADDOP_I(c, PRECALL, 0);

Python/opcode_targets.h

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

Tools/scripts/deepfreeze.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ def __init__(self, file: TextIO) -> None:
117117
self.write('#include "internal/pycore_code.h"')
118118
self.write('#include "internal/pycore_long.h"')
119119
self.write("")
120-
self.write("extern PyTypeObject _PyExc_StopIteration;")
121-
self.write("")
122120

123121
@contextlib.contextmanager
124122
def indent(self) -> None:
@@ -404,8 +402,6 @@ def generate(self, name: str, obj: object) -> str:
404402
return "Py_Ellipsis"
405403
elif obj is None:
406404
return "Py_None"
407-
elif obj is StopIteration:
408-
return "(PyObject *)&_PyExc_StopIteration"
409405
else:
410406
raise TypeError(
411407
f"Cannot generate code for {type(obj).__name__} object")

Tools/scripts/umarshal.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,6 @@ def R_REF(obj: Any) -> Any:
296296
retval = self.refs[n]
297297
assert retval is not None
298298
return retval
299-
elif type == Type.STOPITER:
300-
return StopIteration
301299
else:
302300
breakpoint()
303301
raise AssertionError(f"Unknown type {type} {chr(type)!r}")

0 commit comments

Comments
 (0)
0