Skip to content

Commit

Permalink
Avoid conditional stack effects when compiling f-strings.
Browse files Browse the repository at this point in the history
  • Loading branch information
markshannon committed Jun 5, 2023
1 parent 9d35a71 commit 3af4084
Show file tree
Hide file tree
Showing 14 changed files with 486 additions and 468 deletions.
52 changes: 26 additions & 26 deletions Include/internal/pycore_opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 45 additions & 43 deletions Include/opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 5 additions & 14 deletions Lib/dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,8 @@
_have_code = (types.MethodType, types.FunctionType, types.CodeType,
classmethod, staticmethod, type)

FORMAT_VALUE = opmap['FORMAT_VALUE']
FORMAT_VALUE_CONVERTERS = (
(None, ''),
(str, 'str'),
(repr, 'repr'),
(ascii, 'ascii'),
)
CONVERT_VALUE = opmap['CONVERT_VALUE']

MAKE_FUNCTION = opmap['MAKE_FUNCTION']
MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')

Expand Down Expand Up @@ -508,13 +503,9 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
elif deop in hascompare:
argval = cmp_op[arg>>4]
argrepr = argval
elif deop == FORMAT_VALUE:
argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3]
argval = (argval, bool(arg & 0x4))
if argval[1]:
if argrepr:
argrepr += ', '
argrepr += 'with format'
elif deop == CONVERT_VALUE:
argval = (None, str, repr, ascii)[arg]
argrepr = ('', 'str', 'repr', 'ascii')[arg]
elif deop == MAKE_FUNCTION:
argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS)
if arg & (1<<i))
Expand Down
3 changes: 2 additions & 1 deletion Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.12b1 3531 (Add PEP 695 changes)
# Python 3.13a1 3550 (Plugin optimizer support)
# Python 3.13a1 3551 (Compact superinstructions)
# Python 3.8a1 3553 (more efficient bytecodes for f-strings #33092)

# Python 3.14 will start with 3600

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

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

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

Expand Down
5 changes: 4 additions & 1 deletion Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ def pseudo_op(name, op, real_ops):
def_op('CHECK_EXC_MATCH', 36)
def_op('CHECK_EG_MATCH', 37)

def_op('FORMAT_SIMPLE', 40)
def_op('FORMAT_WITH_SPEC', 41)

def_op('WITH_EXCEPT_START', 49)
def_op('GET_AITER', 50)
def_op('GET_ANEXT', 51)
Expand Down Expand Up @@ -213,9 +216,9 @@ def pseudo_op(name, op, real_ops):
def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py
def_op('MATCH_CLASS', 152)

def_op('FORMAT_VALUE', 155)
def_op('BUILD_CONST_KEY_MAP', 156)
def_op('BUILD_STRING', 157)
def_op('CONVERT_VALUE', 158)

def_op('LIST_EXTEND', 162)
def_op('SET_UPDATE', 163)
Expand Down
10 changes: 6 additions & 4 deletions Lib/test/test_dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,18 +443,20 @@ def _fstring(a, b, c, d):
%3d RESUME 0
%3d LOAD_FAST 0 (a)
FORMAT_VALUE 0
FORMAT_SIMPLE
LOAD_CONST 1 (' ')
LOAD_FAST 1 (b)
LOAD_CONST 2 ('4')
FORMAT_VALUE 4 (with format)
FORMAT_WITH_SPEC
LOAD_CONST 1 (' ')
LOAD_FAST 2 (c)
FORMAT_VALUE 2 (repr)
CONVERT_VALUE 2 (repr)
FORMAT_SIMPLE
LOAD_CONST 1 (' ')
LOAD_FAST 3 (d)
CONVERT_VALUE 2 (repr)
LOAD_CONST 2 ('4')
FORMAT_VALUE 6 (repr, with format)
FORMAT_WITH_SPEC
BUILD_STRING 7
RETURN_VALUE
""" % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Simplify and speed up interpreter for f-strings. Removes ``FORMAT_VALUE``
opcode. Add ``CONVERT_VALUE``, ``FORMAT_SIMPLE`` and ``FORMAT_WITH_SPEC``
opcode. Compiler emits more efficient sequence for each format expression.
4 changes: 2 additions & 2 deletions Programs/test_frozenmain.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3af4084

Please sign in to comment.