Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit40f3f11

Browse files
authored
gh-105481: Generate the opcode lists in dis from data extracted from bytecodes.c (#106758)
1 parent3535ef1 commit40f3f11

File tree

16 files changed

+403
-159
lines changed

16 files changed

+403
-159
lines changed

‎.gitattributes‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ Programs/test_frozenmain.h generated
8787
Python/Python-ast.cgenerated
8888
Python/executor_cases.c.hgenerated
8989
Python/generated_cases.c.hgenerated
90-
Include/internal/pycore_opcode_metadata.hgenerated
9190
Python/opcode_targets.hgenerated
9291
Python/stdlib_module_names.hgenerated
9392
Tools/peg_generator/pegen/grammar_parser.pygenerated

‎Doc/library/dis.rst‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,15 +1803,12 @@ instructions:
18031803
Sequence of bytecodes that access an attribute by name.
18041804

18051805

1806-
..data::hasjrel
1807-
1808-
Sequence of bytecodes that have a relative jump target.
1806+
..data::hasjump
18091807

1808+
Sequence of bytecodes that have a jump target. All jumps
1809+
are relative.
18101810

1811-
..data::hasjabs
1812-
1813-
Sequence of bytecodes that have an absolute jump target.
1814-
1811+
..versionadded::3.13
18151812

18161813
..data::haslocal
18171814

@@ -1827,3 +1824,20 @@ instructions:
18271824
Sequence of bytecodes that set an exception handler.
18281825

18291826
..versionadded::3.12
1827+
1828+
1829+
..data::hasjrel
1830+
1831+
Sequence of bytecodes that have a relative jump target.
1832+
1833+
..deprecated::3.13
1834+
All jumps are now relative. Use:data:`hasjump`.
1835+
1836+
1837+
..data::hasjabs
1838+
1839+
Sequence of bytecodes that have an absolute jump target.
1840+
1841+
..deprecated::3.13
1842+
All jumps are now relative. This list is empty.
1843+

‎Include/cpython/compile.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,7 @@ PyAPI_FUNC(int) PyUnstable_OpcodeHasArg(int opcode);
7373
PyAPI_FUNC(int)PyUnstable_OpcodeHasConst(intopcode);
7474
PyAPI_FUNC(int)PyUnstable_OpcodeHasName(intopcode);
7575
PyAPI_FUNC(int)PyUnstable_OpcodeHasJump(intopcode);
76+
PyAPI_FUNC(int)PyUnstable_OpcodeHasFree(intopcode);
77+
PyAPI_FUNC(int)PyUnstable_OpcodeHasLocal(intopcode);
78+
PyAPI_FUNC(int)PyUnstable_OpcodeHasExc(intopcode);
79+

‎Include/internal/pycore_opcode_metadata.h‎

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -955,10 +955,14 @@ enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC00, INSTR_FMT
955955
#defineHAS_CONST_FLAG (2)
956956
#defineHAS_NAME_FLAG (4)
957957
#defineHAS_JUMP_FLAG (8)
958+
#defineHAS_FREE_FLAG (16)
959+
#defineHAS_LOCAL_FLAG (32)
958960
#defineOPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG))
959961
#defineOPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG))
960962
#defineOPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG))
961963
#defineOPCODE_HAS_JUMP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_JUMP_FLAG))
964+
#defineOPCODE_HAS_FREE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_FREE_FLAG))
965+
#defineOPCODE_HAS_LOCAL(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_LOCAL_FLAG))
962966

963967
structopcode_metadata {
964968
boolvalid_entry;
@@ -995,16 +999,16 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
995999
[NOP]= { true,INSTR_FMT_IX,0 },
9961000
[RESUME]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
9971001
[INSTRUMENTED_RESUME]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
998-
[LOAD_CLOSURE]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
999-
[LOAD_FAST_CHECK]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1000-
[LOAD_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1001-
[LOAD_FAST_AND_CLEAR]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1002-
[LOAD_FAST_LOAD_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1002+
[LOAD_CLOSURE]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1003+
[LOAD_FAST_CHECK]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1004+
[LOAD_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1005+
[LOAD_FAST_AND_CLEAR]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1006+
[LOAD_FAST_LOAD_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
10031007
[LOAD_CONST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG |HAS_CONST_FLAG },
1004-
[STORE_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1005-
[STORE_FAST_MAYBE_NULL]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1006-
[STORE_FAST_LOAD_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1007-
[STORE_FAST_STORE_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1008+
[STORE_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1009+
[STORE_FAST_MAYBE_NULL]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1010+
[STORE_FAST_LOAD_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1011+
[STORE_FAST_STORE_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
10081012
[POP_TOP]= { true,INSTR_FMT_IX,0 },
10091013
[PUSH_NULL]= { true,INSTR_FMT_IX,0 },
10101014
[END_FOR]= { true,INSTR_FMT_IB,0 },
@@ -1028,7 +1032,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
10281032
[BINARY_OP_ADD_FLOAT]= { true,INSTR_FMT_IBC,0 },
10291033
[BINARY_OP_SUBTRACT_FLOAT]= { true,INSTR_FMT_IBC,0 },
10301034
[BINARY_OP_ADD_UNICODE]= { true,INSTR_FMT_IBC,0 },
1031-
[BINARY_OP_INPLACE_ADD_UNICODE]= { true,INSTR_FMT_IB,0 },
1035+
[BINARY_OP_INPLACE_ADD_UNICODE]= { true,INSTR_FMT_IB,HAS_LOCAL_FLAG },
10321036
[BINARY_SUBSCR]= { true,INSTR_FMT_IXC,0 },
10331037
[BINARY_SLICE]= { true,INSTR_FMT_IX,0 },
10341038
[STORE_SLICE]= { true,INSTR_FMT_IX,0 },
@@ -1080,12 +1084,12 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
10801084
[LOAD_GLOBAL]= { true,INSTR_FMT_IBC000,HAS_ARG_FLAG |HAS_NAME_FLAG },
10811085
[LOAD_GLOBAL_MODULE]= { true,INSTR_FMT_IBC000,HAS_ARG_FLAG },
10821086
[LOAD_GLOBAL_BUILTIN]= { true,INSTR_FMT_IBC000,HAS_ARG_FLAG },
1083-
[DELETE_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1084-
[MAKE_CELL]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1085-
[DELETE_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1086-
[LOAD_FROM_DICT_OR_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1087-
[LOAD_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1088-
[STORE_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
1087+
[DELETE_FAST]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_LOCAL_FLAG},
1088+
[MAKE_CELL]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_FREE_FLAG},
1089+
[DELETE_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_FREE_FLAG},
1090+
[LOAD_FROM_DICT_OR_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_FREE_FLAG},
1091+
[LOAD_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_FREE_FLAG},
1092+
[STORE_DEREF]= { true,INSTR_FMT_IB,HAS_ARG_FLAG|HAS_FREE_FLAG},
10891093
[COPY_FREE_VARS]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
10901094
[BUILD_STRING]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },
10911095
[BUILD_TUPLE]= { true,INSTR_FMT_IB,HAS_ARG_FLAG },

‎Lib/opcode.py‎

Lines changed: 49 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
operate on bytecodes (e.g. peephole optimizers).
55
"""
66

7-
__all__= ["cmp_op","hasarg","hasconst","hasname","hasjrel","hasjabs",
8-
"haslocal","hascompare","hasfree","hasexc","opname","opmap",
9-
"stack_effect","HAVE_ARGUMENT","EXTENDED_ARG"]
107

8+
# Note that __all__ is further extended below
9+
__all__= ["cmp_op","opname","opmap","stack_effect","hascompare",
10+
"HAVE_ARGUMENT","EXTENDED_ARG"]
11+
12+
import_opcode
1113
from_opcodeimportstack_effect
1214

1315
importsys
@@ -17,55 +19,24 @@
1719

1820
cmp_op= ('<','<=','==','!=','>','>=')
1921

20-
hasarg= []
21-
hasconst= []
22-
hasname= []
23-
hasjrel= []
24-
hasjabs= []
25-
haslocal= []
26-
hascompare= []
27-
hasfree= []
28-
hasexc= []
29-
3022

3123
ENABLE_SPECIALIZATION=True
3224

3325
defis_pseudo(op):
3426
returnop>=MIN_PSEUDO_OPCODEandop<=MAX_PSEUDO_OPCODE
3527

36-
oplists= [hasarg,hasconst,hasname,hasjrel,hasjabs,
37-
haslocal,hascompare,hasfree,hasexc]
38-
3928
opmap= {}
4029

41-
## pseudo opcodes (used in the compiler) mapped to the values
42-
## they can become in the actual code.
30+
# pseudo opcodes (used in the compiler) mapped to the values
31+
# they can become in the actual code.
4332
_pseudo_ops= {}
4433

4534
defdef_op(name,op):
4635
opmap[name]=op
4736

48-
defname_op(name,op):
49-
def_op(name,op)
50-
hasname.append(op)
51-
52-
defjrel_op(name,op):
53-
def_op(name,op)
54-
hasjrel.append(op)
55-
56-
defjabs_op(name,op):
57-
def_op(name,op)
58-
hasjabs.append(op)
59-
6037
defpseudo_op(name,op,real_ops):
6138
def_op(name,op)
6239
_pseudo_ops[name]=real_ops
63-
# add the pseudo opcode to the lists its targets are in
64-
foroplistinoplists:
65-
res= [opmap[rop]inoplistforropinreal_ops]
66-
ifany(res):
67-
assertall(res)
68-
oplist.append(op)
6940

7041

7142
# Instruction opcodes for compiled code
@@ -137,74 +108,61 @@ def pseudo_op(name, op, real_ops):
137108

138109
HAVE_ARGUMENT=90# real opcodes from here have an argument:
139110

140-
name_op('STORE_NAME',90)# Index in name list
141-
name_op('DELETE_NAME',91)# ""
111+
def_op('STORE_NAME',90)# Index in name list
112+
def_op('DELETE_NAME',91)# ""
142113
def_op('UNPACK_SEQUENCE',92)# Number of tuple items
143-
jrel_op('FOR_ITER',93)
114+
def_op('FOR_ITER',93)
144115
def_op('UNPACK_EX',94)
145-
name_op('STORE_ATTR',95)# Index in name list
146-
name_op('DELETE_ATTR',96)# ""
147-
name_op('STORE_GLOBAL',97)# ""
148-
name_op('DELETE_GLOBAL',98)# ""
116+
def_op('STORE_ATTR',95)# Index in name list
117+
def_op('DELETE_ATTR',96)# ""
118+
def_op('STORE_GLOBAL',97)# ""
119+
def_op('DELETE_GLOBAL',98)# ""
149120
def_op('SWAP',99)
150121
def_op('LOAD_CONST',100)# Index in const list
151-
hasconst.append(100)
152-
name_op('LOAD_NAME',101)# Index in name list
122+
def_op('LOAD_NAME',101)# Index in name list
153123
def_op('BUILD_TUPLE',102)# Number of tuple items
154124
def_op('BUILD_LIST',103)# Number of list items
155125
def_op('BUILD_SET',104)# Number of set items
156126
def_op('BUILD_MAP',105)# Number of dict entries
157-
name_op('LOAD_ATTR',106)# Index in name list
127+
def_op('LOAD_ATTR',106)# Index in name list
158128
def_op('COMPARE_OP',107)# Comparison operator
159-
hascompare.append(107)
160-
name_op('IMPORT_NAME',108)# Index in name list
161-
name_op('IMPORT_FROM',109)# Index in name list
162-
jrel_op('JUMP_FORWARD',110)# Number of words to skip
163-
164-
jrel_op('POP_JUMP_IF_FALSE',114)
165-
jrel_op('POP_JUMP_IF_TRUE',115)
166-
name_op('LOAD_GLOBAL',116)# Index in name list
129+
def_op('IMPORT_NAME',108)# Index in name list
130+
def_op('IMPORT_FROM',109)# Index in name list
131+
def_op('JUMP_FORWARD',110)# Number of words to skip
132+
133+
def_op('POP_JUMP_IF_FALSE',114)
134+
def_op('POP_JUMP_IF_TRUE',115)
135+
def_op('LOAD_GLOBAL',116)# Index in name list
167136
def_op('IS_OP',117)
168137
def_op('CONTAINS_OP',118)
169138
def_op('RERAISE',119)
170139
def_op('COPY',120)
171140
def_op('RETURN_CONST',121)
172-
hasconst.append(121)
173141
def_op('BINARY_OP',122)
174-
jrel_op('SEND',123)# Number of words to skip
142+
def_op('SEND',123)# Number of words to skip
175143
def_op('LOAD_FAST',124)# Local variable number, no null check
176-
haslocal.append(124)
177144
def_op('STORE_FAST',125)# Local variable number
178-
haslocal.append(125)
179145
def_op('DELETE_FAST',126)# Local variable number
180-
haslocal.append(126)
181146
def_op('LOAD_FAST_CHECK',127)# Local variable number
182-
haslocal.append(127)
183-
jrel_op('POP_JUMP_IF_NOT_NONE',128)
184-
jrel_op('POP_JUMP_IF_NONE',129)
147+
def_op('POP_JUMP_IF_NOT_NONE',128)
148+
def_op('POP_JUMP_IF_NONE',129)
185149
def_op('RAISE_VARARGS',130)# Number of raise arguments (1, 2, or 3)
186150
def_op('GET_AWAITABLE',131)
187151
def_op('BUILD_SLICE',133)# Number of items
188-
jrel_op('JUMP_BACKWARD_NO_INTERRUPT',134)# Number of words to skip (backwards)
152+
def_op('JUMP_BACKWARD_NO_INTERRUPT',134)# Number of words to skip (backwards)
189153
def_op('MAKE_CELL',135)
190-
hasfree.append(135)
191154
def_op('LOAD_DEREF',137)
192-
hasfree.append(137)
193155
def_op('STORE_DEREF',138)
194-
hasfree.append(138)
195156
def_op('DELETE_DEREF',139)
196-
hasfree.append(139)
197-
jrel_op('JUMP_BACKWARD',140)# Number of words to skip (backwards)
198-
name_op('LOAD_SUPER_ATTR',141)
157+
def_op('JUMP_BACKWARD',140)# Number of words to skip (backwards)
158+
def_op('LOAD_SUPER_ATTR',141)
199159
def_op('CALL_FUNCTION_EX',142)# Flags
200160
def_op('LOAD_FAST_AND_CLEAR',143)# Local variable number
201-
haslocal.append(143)
202161
def_op('EXTENDED_ARG',144)
203-
EXTENDED_ARG=144
162+
EXTENDED_ARG=opmap['EXTENDED_ARG']
204163
def_op('LIST_APPEND',145)
205164
def_op('SET_ADD',146)
206165
def_op('MAP_ADD',147)
207-
hasfree.append(148)
208166
def_op('COPY_FREE_VARS',149)
209167
def_op('YIELD_VALUE',150)
210168
def_op('RESUME',151)# This must be kept in sync with deepfreeze.py
@@ -224,12 +182,10 @@ def pseudo_op(name, op, real_ops):
224182
def_op('STORE_FAST_STORE_FAST',170)
225183
def_op('CALL',171)
226184
def_op('KW_NAMES',172)
227-
hasconst.append(172)
228185
def_op('CALL_INTRINSIC_1',173)
229186
def_op('CALL_INTRINSIC_2',174)
230-
name_op('LOAD_FROM_DICT_OR_GLOBALS',175)
187+
def_op('LOAD_FROM_DICT_OR_GLOBALS',175)
231188
def_op('LOAD_FROM_DICT_OR_DEREF',176)
232-
hasfree.append(176)
233189
def_op('SET_FUNCTION_ATTRIBUTE',177)# Attribute
234190

235191
# Optimizer hook
@@ -258,16 +214,12 @@ def pseudo_op(name, op, real_ops):
258214
def_op('INSTRUMENTED_LINE',254)
259215
# 255 is reserved
260216

261-
hasarg.extend([opforopinopmap.values()ifop>=HAVE_ARGUMENT])
262217

263218
MIN_PSEUDO_OPCODE=256
264219

265220
pseudo_op('SETUP_FINALLY',256, ['NOP'])
266-
hasexc.append(256)
267221
pseudo_op('SETUP_CLEANUP',257, ['NOP'])
268-
hasexc.append(257)
269222
pseudo_op('SETUP_WITH',258, ['NOP'])
270-
hasexc.append(258)
271223
pseudo_op('POP_BLOCK',259, ['NOP'])
272224

273225
pseudo_op('JUMP',260, ['JUMP_FORWARD','JUMP_BACKWARD'])
@@ -283,12 +235,29 @@ def pseudo_op(name, op, real_ops):
283235

284236
MAX_PSEUDO_OPCODE=MIN_PSEUDO_OPCODE+len(_pseudo_ops)-1
285237

286-
deldef_op,name_op,jrel_op,jabs_op,pseudo_op
238+
deldef_op,pseudo_op
287239

288240
opname= ['<%r>'% (op,)foropinrange(MAX_PSEUDO_OPCODE+1)]
289241
forop,iinopmap.items():
290242
opname[i]=op
291243

244+
# The build uses older versions of Python which do not have _opcode.has_* functions
245+
ifsys.version_info[:2]>= (3,13):
246+
# These lists are documented as part of the dis module's API
247+
hasarg= [opforopinopmap.values()if_opcode.has_arg(op)]
248+
hasconst= [opforopinopmap.values()if_opcode.has_const(op)]
249+
hasname= [opforopinopmap.values()if_opcode.has_name(op)]
250+
hasjump= [opforopinopmap.values()if_opcode.has_jump(op)]
251+
hasjrel=hasjump# for backward compatibility
252+
hasjabs= []
253+
hasfree= [opforopinopmap.values()if_opcode.has_free(op)]
254+
haslocal= [opforopinopmap.values()if_opcode.has_local(op)]
255+
hasexc= [opforopinopmap.values()if_opcode.has_exc(op)]
256+
257+
__all__.extend(["hasarg","hasconst","hasname","hasjump","hasjrel",
258+
"hasjabs","hasfree","haslocal","hasexc"])
259+
260+
hascompare= [opmap["COMPARE_OP"]]
292261

293262
_nb_ops= [
294263
("NB_ADD","+"),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp