GH-105678: Split MAKE_FUNCTION into MAKE_FUNCTION and SET_FUNCTION_ATTRIBUTE (GH-105680)

This commit is contained in:
Mark Shannon 2023-06-13 09:51:05 +01:00 committed by GitHub
parent 217589d4f3
commit 09ffa69e2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 480 additions and 430 deletions

View file

@ -214,6 +214,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
[SEND_GEN] = SEND,
[SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
[SET_ADD] = SET_ADD,
[SET_FUNCTION_ATTRIBUTE] = SET_FUNCTION_ATTRIBUTE,
[SET_UPDATE] = SET_UPDATE,
[STORE_ATTR] = STORE_ATTR,
[STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
@ -269,20 +270,21 @@ static const char *const _PyOpcode_OpName[267] = {
[BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT",
[BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT",
[CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
[CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS",
[MAKE_FUNCTION] = "MAKE_FUNCTION",
[BINARY_SUBSCR] = "BINARY_SUBSCR",
[BINARY_SLICE] = "BINARY_SLICE",
[STORE_SLICE] = "STORE_SLICE",
[CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS",
[CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
[CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
[GET_LEN] = "GET_LEN",
[MATCH_MAPPING] = "MATCH_MAPPING",
[MATCH_SEQUENCE] = "MATCH_SEQUENCE",
[MATCH_KEYS] = "MATCH_KEYS",
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
[CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
[PUSH_EXC_INFO] = "PUSH_EXC_INFO",
[CHECK_EXC_MATCH] = "CHECK_EXC_MATCH",
[CHECK_EG_MATCH] = "CHECK_EG_MATCH",
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
[CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST",
[CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O",
@ -293,7 +295,6 @@ static const char *const _PyOpcode_OpName[267] = {
[CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS",
[CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O",
[CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1",
[CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1",
[WITH_EXCEPT_START] = "WITH_EXCEPT_START",
[GET_AITER] = "GET_AITER",
[GET_ANEXT] = "GET_ANEXT",
@ -301,39 +302,39 @@ static const char *const _PyOpcode_OpName[267] = {
[BEFORE_WITH] = "BEFORE_WITH",
[END_ASYNC_FOR] = "END_ASYNC_FOR",
[CLEANUP_THROW] = "CLEANUP_THROW",
[CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1",
[CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1",
[COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT",
[COMPARE_OP_INT] = "COMPARE_OP_INT",
[COMPARE_OP_STR] = "COMPARE_OP_STR",
[STORE_SUBSCR] = "STORE_SUBSCR",
[DELETE_SUBSCR] = "DELETE_SUBSCR",
[COMPARE_OP_STR] = "COMPARE_OP_STR",
[FOR_ITER_LIST] = "FOR_ITER_LIST",
[FOR_ITER_TUPLE] = "FOR_ITER_TUPLE",
[FOR_ITER_RANGE] = "FOR_ITER_RANGE",
[FOR_ITER_GEN] = "FOR_ITER_GEN",
[LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR",
[LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
[GET_ITER] = "GET_ITER",
[GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER",
[LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
[LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD",
[LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS",
[LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS",
[LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN",
[LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
[LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR",
[RETURN_GENERATOR] = "RETURN_GENERATOR",
[LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE",
[LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE",
[LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY",
[LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT",
[LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT",
[LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT",
[LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT",
[LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
[RETURN_VALUE] = "RETURN_VALUE",
[LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
[LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES",
[SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
[LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
[LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
[LOAD_LOCALS] = "LOAD_LOCALS",
[STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
[LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
[POP_EXCEPT] = "POP_EXCEPT",
[STORE_NAME] = "STORE_NAME",
[DELETE_NAME] = "DELETE_NAME",
@ -356,9 +357,9 @@ static const char *const _PyOpcode_OpName[267] = {
[IMPORT_NAME] = "IMPORT_NAME",
[IMPORT_FROM] = "IMPORT_FROM",
[JUMP_FORWARD] = "JUMP_FORWARD",
[STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
[STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
[STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT",
[STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
[POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
[POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
[LOAD_GLOBAL] = "LOAD_GLOBAL",
@ -377,7 +378,7 @@ static const char *const _PyOpcode_OpName[267] = {
[POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE",
[RAISE_VARARGS] = "RAISE_VARARGS",
[GET_AWAITABLE] = "GET_AWAITABLE",
[MAKE_FUNCTION] = "MAKE_FUNCTION",
[STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT",
[BUILD_SLICE] = "BUILD_SLICE",
[JUMP_BACKWARD_NO_INTERRUPT] = "JUMP_BACKWARD_NO_INTERRUPT",
[MAKE_CELL] = "MAKE_CELL",
@ -422,7 +423,7 @@ static const char *const _PyOpcode_OpName[267] = {
[CALL_INTRINSIC_2] = "CALL_INTRINSIC_2",
[LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS",
[LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF",
[177] = "<177>",
[SET_FUNCTION_ATTRIBUTE] = "SET_FUNCTION_ATTRIBUTE",
[178] = "<178>",
[179] = "<179>",
[180] = "<180>",
@ -520,7 +521,6 @@ static const char *const _PyOpcode_OpName[267] = {
case 161: \
case 166: \
case 167: \
case 177: \
case 178: \
case 179: \
case 180: \

85
Include/opcode.h generated
View file

@ -19,6 +19,7 @@ extern "C" {
#define UNARY_NOT 12
#define UNARY_INVERT 15
#define RESERVED 17
#define MAKE_FUNCTION 24
#define BINARY_SUBSCR 25
#define BINARY_SLICE 26
#define STORE_SLICE 27
@ -87,7 +88,6 @@ extern "C" {
#define POP_JUMP_IF_NONE 129
#define RAISE_VARARGS 130
#define GET_AWAITABLE 131
#define MAKE_FUNCTION 132
#define BUILD_SLICE 133
#define JUMP_BACKWARD_NO_INTERRUPT 134
#define MAKE_CELL 135
@ -123,6 +123,7 @@ extern "C" {
#define CALL_INTRINSIC_2 174
#define LOAD_FROM_DICT_OR_GLOBALS 175
#define LOAD_FROM_DICT_OR_DEREF 176
#define SET_FUNCTION_ATTRIBUTE 177
#define ENTER_EXECUTOR 230
#define MIN_INSTRUMENTED_OPCODE 237
#define INSTRUMENTED_LOAD_SUPER_ATTR 237
@ -169,47 +170,47 @@ extern "C" {
#define BINARY_SUBSCR_LIST_INT 21
#define BINARY_SUBSCR_TUPLE_INT 22
#define CALL_PY_EXACT_ARGS 23
#define CALL_PY_WITH_DEFAULTS 24
#define CALL_BOUND_METHOD_EXACT_ARGS 28
#define CALL_BUILTIN_CLASS 29
#define CALL_BUILTIN_FAST_WITH_KEYWORDS 34
#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 38
#define CALL_NO_KW_BUILTIN_FAST 39
#define CALL_NO_KW_BUILTIN_O 40
#define CALL_NO_KW_ISINSTANCE 41
#define CALL_NO_KW_LEN 42
#define CALL_NO_KW_LIST_APPEND 43
#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 44
#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 45
#define CALL_NO_KW_METHOD_DESCRIPTOR_O 46
#define CALL_NO_KW_STR_1 47
#define CALL_NO_KW_TUPLE_1 48
#define CALL_NO_KW_TYPE_1 56
#define COMPARE_OP_FLOAT 57
#define COMPARE_OP_INT 58
#define COMPARE_OP_STR 59
#define FOR_ITER_LIST 62
#define FOR_ITER_TUPLE 63
#define FOR_ITER_RANGE 64
#define FOR_ITER_GEN 65
#define LOAD_SUPER_ATTR_ATTR 66
#define LOAD_SUPER_ATTR_METHOD 67
#define LOAD_ATTR_CLASS 70
#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 72
#define LOAD_ATTR_INSTANCE_VALUE 73
#define LOAD_ATTR_MODULE 76
#define LOAD_ATTR_PROPERTY 77
#define LOAD_ATTR_SLOT 78
#define LOAD_ATTR_WITH_HINT 79
#define LOAD_ATTR_METHOD_LAZY_DICT 80
#define LOAD_ATTR_METHOD_NO_DICT 81
#define LOAD_ATTR_METHOD_WITH_VALUES 82
#define LOAD_GLOBAL_BUILTIN 84
#define LOAD_GLOBAL_MODULE 86
#define STORE_ATTR_INSTANCE_VALUE 88
#define STORE_ATTR_SLOT 111
#define STORE_ATTR_WITH_HINT 112
#define STORE_SUBSCR_DICT 113
#define CALL_PY_WITH_DEFAULTS 28
#define CALL_BOUND_METHOD_EXACT_ARGS 29
#define CALL_BUILTIN_CLASS 34
#define CALL_BUILTIN_FAST_WITH_KEYWORDS 38
#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 39
#define CALL_NO_KW_BUILTIN_FAST 40
#define CALL_NO_KW_BUILTIN_O 41
#define CALL_NO_KW_ISINSTANCE 42
#define CALL_NO_KW_LEN 43
#define CALL_NO_KW_LIST_APPEND 44
#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 45
#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 46
#define CALL_NO_KW_METHOD_DESCRIPTOR_O 47
#define CALL_NO_KW_STR_1 48
#define CALL_NO_KW_TUPLE_1 56
#define CALL_NO_KW_TYPE_1 57
#define COMPARE_OP_FLOAT 58
#define COMPARE_OP_INT 59
#define COMPARE_OP_STR 62
#define FOR_ITER_LIST 63
#define FOR_ITER_TUPLE 64
#define FOR_ITER_RANGE 65
#define FOR_ITER_GEN 66
#define LOAD_SUPER_ATTR_ATTR 67
#define LOAD_SUPER_ATTR_METHOD 70
#define LOAD_ATTR_CLASS 72
#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 73
#define LOAD_ATTR_INSTANCE_VALUE 76
#define LOAD_ATTR_MODULE 77
#define LOAD_ATTR_PROPERTY 78
#define LOAD_ATTR_SLOT 79
#define LOAD_ATTR_WITH_HINT 80
#define LOAD_ATTR_METHOD_LAZY_DICT 81
#define LOAD_ATTR_METHOD_NO_DICT 82
#define LOAD_ATTR_METHOD_WITH_VALUES 84
#define LOAD_GLOBAL_BUILTIN 86
#define LOAD_GLOBAL_MODULE 88
#define STORE_ATTR_INSTANCE_VALUE 111
#define STORE_ATTR_SLOT 112
#define STORE_ATTR_WITH_HINT 113
#define STORE_SUBSCR_DICT 132
#define STORE_SUBSCR_LIST_INT 148
#define UNPACK_SEQUENCE_LIST 153
#define UNPACK_SEQUENCE_TUPLE 154

View file

@ -32,8 +32,8 @@ FORMAT_VALUE_CONVERTERS = (
(repr, 'repr'),
(ascii, 'ascii'),
)
MAKE_FUNCTION = opmap['MAKE_FUNCTION']
MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
SET_FUNCTION_ATTRIBUTE = opmap['SET_FUNCTION_ATTRIBUTE']
FUNCTION_ATTR_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
LOAD_CONST = opmap['LOAD_CONST']
RETURN_CONST = opmap['RETURN_CONST']
@ -586,8 +586,8 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
if argrepr:
argrepr += ', '
argrepr += 'with format'
elif deop == MAKE_FUNCTION:
argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS)
elif deop == SET_FUNCTION_ATTRIBUTE:
argrepr = ', '.join(s for i, s in enumerate(FUNCTION_ATTR_FLAGS)
if arg & (1<<i))
elif deop == BINARY_OP:
_, argrepr = _nb_ops[arg]

View file

@ -448,6 +448,8 @@ _code_type = type(_write_atomic.__code__)
# Python 3.13a1 3550 (Plugin optimizer support)
# Python 3.13a1 3551 (Compact superinstructions)
# Python 3.13a1 3554 (Add SET_FUNCTION_ATTRIBUTE)
# Python 3.14 will start with 3600
# Please don't copy-paste the same pre-release tag for new entries above!!!
@ -463,7 +465,7 @@ _code_type = type(_write_atomic.__code__)
# 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 = (3554).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

View file

@ -96,6 +96,7 @@ def_op('UNARY_INVERT', 15)
# This helps us catch cases where we attempt to execute a cache.
def_op('RESERVED', 17)
def_op('MAKE_FUNCTION', 24)
def_op('BINARY_SUBSCR', 25)
def_op('BINARY_SLICE', 26)
def_op('STORE_SLICE', 27)
@ -183,7 +184,6 @@ jrel_op('POP_JUMP_IF_NOT_NONE', 128)
jrel_op('POP_JUMP_IF_NONE', 129)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('GET_AWAITABLE', 131)
def_op('MAKE_FUNCTION', 132) # Flags
def_op('BUILD_SLICE', 133) # Number of items
jrel_op('JUMP_BACKWARD_NO_INTERRUPT', 134) # Number of words to skip (backwards)
def_op('MAKE_CELL', 135)
@ -234,6 +234,7 @@ def_op('CALL_INTRINSIC_2', 174)
name_op('LOAD_FROM_DICT_OR_GLOBALS', 175)
def_op('LOAD_FROM_DICT_OR_DEREF', 176)
hasfree.append(176)
def_op('SET_FUNCTION_ATTRIBUTE', 177) # Attribute
# Optimizer hook
def_op('ENTER_EXECUTOR', 230)

View file

@ -163,7 +163,7 @@ dis_bug1333982 = """\
%3d LOAD_ASSERTION_ERROR
LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>)
MAKE_FUNCTION 0
MAKE_FUNCTION
LOAD_FAST 0 (x)
GET_ITER
CALL 0
@ -686,7 +686,8 @@ dis_nested_0 = """\
%3d LOAD_CLOSURE 0 (y)
BUILD_TUPLE 1
LOAD_CONST 1 (<code object foo at 0x..., file "%s", line %d>)
MAKE_FUNCTION 8 (closure)
MAKE_FUNCTION
SET_FUNCTION_ATTRIBUTE 8 (closure)
STORE_FAST 1 (foo)
%3d LOAD_FAST 1 (foo)
@ -709,7 +710,8 @@ Disassembly of <code object foo at 0x..., file "%s", line %d>:
LOAD_CLOSURE 0 (x)
BUILD_TUPLE 1
LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>)
MAKE_FUNCTION 8 (closure)
MAKE_FUNCTION
SET_FUNCTION_ATTRIBUTE 8 (closure)
LOAD_DEREF 1 (y)
GET_ITER
CALL 0
@ -1566,7 +1568,7 @@ expected_jumpy_line = 1
def _stringify_instruction(instr):
# Since line numbers and other offsets change a lot for these
# test cases, ignore them.
return str(instr._replace(positions=None))
return repr(instr._replace(positions=None))
def _prepare_test_cases():
_instructions = dis.get_instructions(outer, first_line=expected_outer_line)
@ -1596,20 +1598,22 @@ expected_opinfo_outer = [
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='b', argrepr='b', offset=10, start_offset=10, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=12, start_offset=12, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, start_offset=14, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, start_offset=16, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=18, start_offset=18, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=20, start_offset=20, starts_line=7, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=30, start_offset=30, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=32, start_offset=32, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='', argrepr="''", offset=34, start_offset=34, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=1, argrepr='1', offset=36, start_offset=36, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=38, start_offset=38, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=40, start_offset=40, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=42, start_offset=42, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=44, start_offset=44, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, start_offset=52, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=54, start_offset=54, starts_line=8, is_jump_target=False, positions=None),
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=16, start_offset=16, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=8, argval=8, argrepr='closure', offset=18, start_offset=18, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=1, argval=1, argrepr='defaults', offset=20, start_offset=20, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=22, start_offset=22, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=24, start_offset=24, starts_line=7, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=34, start_offset=34, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=36, start_offset=36, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='', argrepr="''", offset=38, start_offset=38, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=1, argrepr='1', offset=40, start_offset=40, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=42, start_offset=42, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=44, start_offset=44, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=46, start_offset=46, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=48, start_offset=48, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=58, start_offset=58, starts_line=8, is_jump_target=False, positions=None),
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=None, is_jump_target=False, positions=None),
]
expected_opinfo_f = [
@ -1624,17 +1628,19 @@ expected_opinfo_f = [
Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='d', argrepr='d', offset=16, start_offset=16, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=18, start_offset=18, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, start_offset=20, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=22, start_offset=22, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=24, start_offset=24, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=26, start_offset=26, starts_line=5, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=36, start_offset=36, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=38, start_offset=38, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=40, start_offset=40, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=42, start_offset=42, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=44, start_offset=44, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, start_offset=52, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=54, start_offset=54, starts_line=6, is_jump_target=False, positions=None),
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='MAKE_FUNCTION', opcode=24, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=8, argval=8, argrepr='closure', offset=24, start_offset=24, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='SET_FUNCTION_ATTRIBUTE', opcode=177, arg=1, argval=1, argrepr='defaults', offset=26, start_offset=26, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=28, start_offset=28, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=30, start_offset=30, starts_line=5, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=40, start_offset=40, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=42, start_offset=42, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=44, start_offset=44, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=46, start_offset=46, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=48, start_offset=48, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=56, start_offset=56, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=58, start_offset=58, starts_line=6, is_jump_target=False, positions=None),
Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=60, start_offset=60, starts_line=None, is_jump_target=False, positions=None),
]
expected_opinfo_inner = [

View file

@ -0,0 +1,4 @@
Break the ``MAKE_FUNCTION`` instruction into two parts, ``MAKE_FUNCTION``
which makes the function and ``SET_FUNCTION_ATTRIBUTE`` which sets the
attributes on the function. This makes the stack effect of ``MAKE_FUNCTION``
regular to ease optimization and code generation.

View file

@ -83,15 +83,14 @@ dummy_func(
// Dummy labels.
pop_1_error:
// Dummy locals.
PyObject *annotations;
PyObject *dummy;
PyObject *attr;
PyObject *attrs;
PyObject *bottom;
PyObject *callable;
PyObject *callargs;
PyObject *closure;
PyObject *codeobj;
PyObject *cond;
PyObject *defaults;
PyObject *descr;
_PyInterpreterFrame entry_frame;
PyObject *exc;
@ -3297,11 +3296,7 @@ dummy_func(
CHECK_EVAL_BREAKER();
}
inst(MAKE_FUNCTION, (defaults if (oparg & MAKE_FUNCTION_DEFAULTS),
kwdefaults if (oparg & MAKE_FUNCTION_KWDEFAULTS),
annotations if (oparg & MAKE_FUNCTION_ANNOTATIONS),
closure if (oparg & MAKE_FUNCTION_CLOSURE),
codeobj -- func)) {
inst(MAKE_FUNCTION, (codeobj -- func)) {
PyFunctionObject *func_obj = (PyFunctionObject *)
PyFunction_New(codeobj, GLOBALS());
@ -3311,27 +3306,37 @@ dummy_func(
goto error;
}
if (oparg & MAKE_FUNCTION_CLOSURE) {
assert(PyTuple_CheckExact(closure));
func_obj->func_closure = closure;
}
if (oparg & MAKE_FUNCTION_ANNOTATIONS) {
assert(PyTuple_CheckExact(annotations));
func_obj->func_annotations = annotations;
}
if (oparg & MAKE_FUNCTION_KWDEFAULTS) {
assert(PyDict_CheckExact(kwdefaults));
func_obj->func_kwdefaults = kwdefaults;
}
if (oparg & MAKE_FUNCTION_DEFAULTS) {
assert(PyTuple_CheckExact(defaults));
func_obj->func_defaults = defaults;
}
func_obj->func_version = ((PyCodeObject *)codeobj)->co_version;
func = (PyObject *)func_obj;
}
inst(SET_FUNCTION_ATTRIBUTE, (attr, func -- func)) {
assert(PyFunction_Check(func));
PyFunctionObject *func_obj = (PyFunctionObject *)func;
switch(oparg) {
case MAKE_FUNCTION_CLOSURE:
assert(func_obj->func_closure == NULL);
func_obj->func_closure = attr;
break;
case MAKE_FUNCTION_ANNOTATIONS:
assert(func_obj->func_annotations == NULL);
func_obj->func_annotations = attr;
break;
case MAKE_FUNCTION_KWDEFAULTS:
assert(PyDict_CheckExact(attr));
assert(func_obj->func_kwdefaults == NULL);
func_obj->func_kwdefaults = attr;
break;
case MAKE_FUNCTION_DEFAULTS:
assert(PyTuple_CheckExact(attr));
assert(func_obj->func_defaults == NULL);
func_obj->func_defaults = attr;
break;
default:
Py_UNREACHABLE();
}
}
inst(RETURN_GENERATOR, (--)) {
assert(PyFunction_Check(frame->f_funcobj));
PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;

View file

@ -1823,7 +1823,21 @@ compiler_make_closure(struct compiler *c, location loc,
ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
}
ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
ADDOP_I(c, loc, MAKE_FUNCTION, flags);
ADDOP(c, loc, MAKE_FUNCTION);
if (flags & MAKE_FUNCTION_CLOSURE) {
ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_CLOSURE);
}
if (flags & MAKE_FUNCTION_ANNOTATIONS) {
ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATIONS);
}
if (flags & MAKE_FUNCTION_KWDEFAULTS) {
ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_KWDEFAULTS);
}
if (flags & MAKE_FUNCTION_DEFAULTS) {
ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_DEFAULTS);
}
return SUCCESS;
}

File diff suppressed because it is too large Load diff

View file

@ -395,7 +395,9 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
case CALL_FUNCTION_EX:
return ((oparg & 1) ? 1 : 0) + 3;
case MAKE_FUNCTION:
return ((oparg & MAKE_FUNCTION_DEFAULTS) ? 1 : 0) + ((oparg & MAKE_FUNCTION_KWDEFAULTS) ? 1 : 0) + ((oparg & MAKE_FUNCTION_ANNOTATIONS) ? 1 : 0) + ((oparg & MAKE_FUNCTION_CLOSURE) ? 1 : 0) + 1;
return 1;
case SET_FUNCTION_ATTRIBUTE:
return 2;
case RETURN_GENERATOR:
return 0;
case BUILD_SLICE:
@ -812,6 +814,8 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
return 1;
case MAKE_FUNCTION:
return 1;
case SET_FUNCTION_ATTRIBUTE:
return 1;
case RETURN_GENERATOR:
return 0;
case BUILD_SLICE:
@ -1049,7 +1053,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[512] = {
[CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00 },
[INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX },
[CALL_FUNCTION_EX] = { true, INSTR_FMT_IB },
[MAKE_FUNCTION] = { true, INSTR_FMT_IB },
[MAKE_FUNCTION] = { true, INSTR_FMT_IX },
[SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB },
[RETURN_GENERATOR] = { true, INSTR_FMT_IX },
[BUILD_SLICE] = { true, INSTR_FMT_IB },
[FORMAT_VALUE] = { true, INSTR_FMT_IB },

View file

@ -23,20 +23,21 @@ static void *opcode_targets[256] = {
&&TARGET_BINARY_SUBSCR_LIST_INT,
&&TARGET_BINARY_SUBSCR_TUPLE_INT,
&&TARGET_CALL_PY_EXACT_ARGS,
&&TARGET_CALL_PY_WITH_DEFAULTS,
&&TARGET_MAKE_FUNCTION,
&&TARGET_BINARY_SUBSCR,
&&TARGET_BINARY_SLICE,
&&TARGET_STORE_SLICE,
&&TARGET_CALL_PY_WITH_DEFAULTS,
&&TARGET_CALL_BOUND_METHOD_EXACT_ARGS,
&&TARGET_CALL_BUILTIN_CLASS,
&&TARGET_GET_LEN,
&&TARGET_MATCH_MAPPING,
&&TARGET_MATCH_SEQUENCE,
&&TARGET_MATCH_KEYS,
&&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
&&TARGET_CALL_BUILTIN_CLASS,
&&TARGET_PUSH_EXC_INFO,
&&TARGET_CHECK_EXC_MATCH,
&&TARGET_CHECK_EG_MATCH,
&&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
&&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
&&TARGET_CALL_NO_KW_BUILTIN_FAST,
&&TARGET_CALL_NO_KW_BUILTIN_O,
@ -47,7 +48,6 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS,
&&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_O,
&&TARGET_CALL_NO_KW_STR_1,
&&TARGET_CALL_NO_KW_TUPLE_1,
&&TARGET_WITH_EXCEPT_START,
&&TARGET_GET_AITER,
&&TARGET_GET_ANEXT,
@ -55,39 +55,39 @@ static void *opcode_targets[256] = {
&&TARGET_BEFORE_WITH,
&&TARGET_END_ASYNC_FOR,
&&TARGET_CLEANUP_THROW,
&&TARGET_CALL_NO_KW_TUPLE_1,
&&TARGET_CALL_NO_KW_TYPE_1,
&&TARGET_COMPARE_OP_FLOAT,
&&TARGET_COMPARE_OP_INT,
&&TARGET_COMPARE_OP_STR,
&&TARGET_STORE_SUBSCR,
&&TARGET_DELETE_SUBSCR,
&&TARGET_COMPARE_OP_STR,
&&TARGET_FOR_ITER_LIST,
&&TARGET_FOR_ITER_TUPLE,
&&TARGET_FOR_ITER_RANGE,
&&TARGET_FOR_ITER_GEN,
&&TARGET_LOAD_SUPER_ATTR_ATTR,
&&TARGET_LOAD_SUPER_ATTR_METHOD,
&&TARGET_GET_ITER,
&&TARGET_GET_YIELD_FROM_ITER,
&&TARGET_LOAD_ATTR_CLASS,
&&TARGET_LOAD_SUPER_ATTR_METHOD,
&&TARGET_LOAD_BUILD_CLASS,
&&TARGET_LOAD_ATTR_CLASS,
&&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN,
&&TARGET_LOAD_ATTR_INSTANCE_VALUE,
&&TARGET_LOAD_ASSERTION_ERROR,
&&TARGET_RETURN_GENERATOR,
&&TARGET_LOAD_ATTR_INSTANCE_VALUE,
&&TARGET_LOAD_ATTR_MODULE,
&&TARGET_LOAD_ATTR_PROPERTY,
&&TARGET_LOAD_ATTR_SLOT,
&&TARGET_LOAD_ATTR_WITH_HINT,
&&TARGET_LOAD_ATTR_METHOD_LAZY_DICT,
&&TARGET_LOAD_ATTR_METHOD_NO_DICT,
&&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
&&TARGET_RETURN_VALUE,
&&TARGET_LOAD_GLOBAL_BUILTIN,
&&TARGET_LOAD_ATTR_METHOD_WITH_VALUES,
&&TARGET_SETUP_ANNOTATIONS,
&&TARGET_LOAD_GLOBAL_MODULE,
&&TARGET_LOAD_GLOBAL_BUILTIN,
&&TARGET_LOAD_LOCALS,
&&TARGET_STORE_ATTR_INSTANCE_VALUE,
&&TARGET_LOAD_GLOBAL_MODULE,
&&TARGET_POP_EXCEPT,
&&TARGET_STORE_NAME,
&&TARGET_DELETE_NAME,
@ -110,9 +110,9 @@ static void *opcode_targets[256] = {
&&TARGET_IMPORT_NAME,
&&TARGET_IMPORT_FROM,
&&TARGET_JUMP_FORWARD,
&&TARGET_STORE_ATTR_INSTANCE_VALUE,
&&TARGET_STORE_ATTR_SLOT,
&&TARGET_STORE_ATTR_WITH_HINT,
&&TARGET_STORE_SUBSCR_DICT,
&&TARGET_POP_JUMP_IF_FALSE,
&&TARGET_POP_JUMP_IF_TRUE,
&&TARGET_LOAD_GLOBAL,
@ -131,7 +131,7 @@ static void *opcode_targets[256] = {
&&TARGET_POP_JUMP_IF_NONE,
&&TARGET_RAISE_VARARGS,
&&TARGET_GET_AWAITABLE,
&&TARGET_MAKE_FUNCTION,
&&TARGET_STORE_SUBSCR_DICT,
&&TARGET_BUILD_SLICE,
&&TARGET_JUMP_BACKWARD_NO_INTERRUPT,
&&TARGET_MAKE_CELL,
@ -176,7 +176,7 @@ static void *opcode_targets[256] = {
&&TARGET_CALL_INTRINSIC_2,
&&TARGET_LOAD_FROM_DICT_OR_GLOBALS,
&&TARGET_LOAD_FROM_DICT_OR_DEREF,
&&_unknown_opcode,
&&TARGET_SET_FUNCTION_ATTRIBUTE,
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,