Skip to content

Commit 3af4084

Browse files
committed
Avoid conditional stack effects when compiling f-strings.
1 parent 9d35a71 commit 3af4084

File tree

14 files changed

+486
-468
lines changed

14 files changed

+486
-468
lines changed

Include/internal/pycore_opcode.h

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

Include/opcode.h

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

Lib/dis.py

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,8 @@
2525
_have_code = (types.MethodType, types.FunctionType, types.CodeType,
2626
classmethod, staticmethod, type)
2727

28-
FORMAT_VALUE = opmap['FORMAT_VALUE']
29-
FORMAT_VALUE_CONVERTERS = (
30-
(None, ''),
31-
(str, 'str'),
32-
(repr, 'repr'),
33-
(ascii, 'ascii'),
34-
)
28+
CONVERT_VALUE = opmap['CONVERT_VALUE']
29+
3530
MAKE_FUNCTION = opmap['MAKE_FUNCTION']
3631
MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
3732

@@ -508,13 +503,9 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
508503
elif deop in hascompare:
509504
argval = cmp_op[arg>>4]
510505
argrepr = argval
511-
elif deop == FORMAT_VALUE:
512-
argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3]
513-
argval = (argval, bool(arg & 0x4))
514-
if argval[1]:
515-
if argrepr:
516-
argrepr += ', '
517-
argrepr += 'with format'
506+
elif deop == CONVERT_VALUE:
507+
argval = (None, str, repr, ascii)[arg]
508+
argrepr = ('', 'str', 'repr', 'ascii')[arg]
518509
elif deop == MAKE_FUNCTION:
519510
argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS)
520511
if arg & (1<<i))

Lib/importlib/_bootstrap_external.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ def _write_atomic(path, data, mode=0o666):
447447
# Python 3.12b1 3531 (Add PEP 695 changes)
448448
# Python 3.13a1 3550 (Plugin optimizer support)
449449
# Python 3.13a1 3551 (Compact superinstructions)
450+
# Python 3.8a1 3553 (more efficient bytecodes for f-strings #33092)
450451

451452
# Python 3.14 will start with 3600
452453

@@ -463,7 +464,7 @@ def _write_atomic(path, data, mode=0o666):
463464
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
464465
# in PC/launcher.c must also be updated.
465466

466-
MAGIC_NUMBER = (3551).to_bytes(2, 'little') + b'\r\n'
467+
MAGIC_NUMBER = (3553).to_bytes(2, 'little') + b'\r\n'
467468

468469
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
469470

Lib/opcode.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ def pseudo_op(name, op, real_ops):
109109
def_op('CHECK_EXC_MATCH', 36)
110110
def_op('CHECK_EG_MATCH', 37)
111111

112+
def_op('FORMAT_SIMPLE', 40)
113+
def_op('FORMAT_WITH_SPEC', 41)
114+
112115
def_op('WITH_EXCEPT_START', 49)
113116
def_op('GET_AITER', 50)
114117
def_op('GET_ANEXT', 51)
@@ -213,9 +216,9 @@ def pseudo_op(name, op, real_ops):
213216
def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py
214217
def_op('MATCH_CLASS', 152)
215218

216-
def_op('FORMAT_VALUE', 155)
217219
def_op('BUILD_CONST_KEY_MAP', 156)
218220
def_op('BUILD_STRING', 157)
221+
def_op('CONVERT_VALUE', 158)
219222

220223
def_op('LIST_EXTEND', 162)
221224
def_op('SET_UPDATE', 163)

Lib/test/test_dis.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -443,18 +443,20 @@ def _fstring(a, b, c, d):
443443
%3d RESUME 0
444444
445445
%3d LOAD_FAST 0 (a)
446-
FORMAT_VALUE 0
446+
FORMAT_SIMPLE
447447
LOAD_CONST 1 (' ')
448448
LOAD_FAST 1 (b)
449449
LOAD_CONST 2 ('4')
450-
FORMAT_VALUE 4 (with format)
450+
FORMAT_WITH_SPEC
451451
LOAD_CONST 1 (' ')
452452
LOAD_FAST 2 (c)
453-
FORMAT_VALUE 2 (repr)
453+
CONVERT_VALUE 2 (repr)
454+
FORMAT_SIMPLE
454455
LOAD_CONST 1 (' ')
455456
LOAD_FAST 3 (d)
457+
CONVERT_VALUE 2 (repr)
456458
LOAD_CONST 2 ('4')
457-
FORMAT_VALUE 6 (repr, with format)
459+
FORMAT_WITH_SPEC
458460
BUILD_STRING 7
459461
RETURN_VALUE
460462
""" % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Simplify and speed up interpreter for f-strings. Removes ``FORMAT_VALUE``
2+
opcode. Add ``CONVERT_VALUE``, ``FORMAT_SIMPLE`` and ``FORMAT_WITH_SPEC``
3+
opcode. Compiler emits more efficient sequence for each format expression.

Programs/test_frozenmain.h

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

0 commit comments

Comments
 (0)