44operate 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
1113from _opcode import stack_effect
1214
1315import sys
1719
1820cmp_op = ('<' ,'<=' ,'==' ,'!=' ,'>' ,'>=' )
1921
20- hasarg = []
21- hasconst = []
22- hasname = []
23- hasjrel = []
24- hasjabs = []
25- haslocal = []
26- hascompare = []
27- hasfree = []
28- hasexc = []
29-
3022
3123ENABLE_SPECIALIZATION = True
3224
3325def is_pseudo (op ):
3426return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE
3527
36- oplists = [hasarg ,hasconst ,hasname ,hasjrel ,hasjabs ,
37- haslocal ,hascompare ,hasfree ,hasexc ]
38-
3928opmap = {}
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
4534def def_op (name ,op ):
4635opmap [name ]= op
4736
48- def name_op (name ,op ):
49- def_op (name ,op )
50- hasname .append (op )
51-
52- def jrel_op (name ,op ):
53- def_op (name ,op )
54- hasjrel .append (op )
55-
56- def jabs_op (name ,op ):
57- def_op (name ,op )
58- hasjabs .append (op )
59-
6037def pseudo_op (name ,op ,real_ops ):
6138def_op (name ,op )
6239_pseudo_ops [name ]= real_ops
63- # add the pseudo opcode to the lists its targets are in
64- for oplist in oplists :
65- res = [opmap [rop ]in oplist for rop in real_ops ]
66- if any (res ):
67- assert all (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
138109HAVE_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 )# ""
142113def_op ('UNPACK_SEQUENCE' ,92 )# Number of tuple items
143- jrel_op ('FOR_ITER' ,93 )
114+ def_op ('FOR_ITER' ,93 )
144115def_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 )# ""
149120def_op ('SWAP' ,99 )
150121def_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
153123def_op ('BUILD_TUPLE' ,102 )# Number of tuple items
154124def_op ('BUILD_LIST' ,103 )# Number of list items
155125def_op ('BUILD_SET' ,104 )# Number of set items
156126def_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
158128def_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
167136def_op ('IS_OP' ,117 )
168137def_op ('CONTAINS_OP' ,118 )
169138def_op ('RERAISE' ,119 )
170139def_op ('COPY' ,120 )
171140def_op ('RETURN_CONST' ,121 )
172- hasconst .append (121 )
173141def_op ('BINARY_OP' ,122 )
174- jrel_op ('SEND' ,123 )# Number of words to skip
142+ def_op ('SEND' ,123 )# Number of words to skip
175143def_op ('LOAD_FAST' ,124 )# Local variable number, no null check
176- haslocal .append (124 )
177144def_op ('STORE_FAST' ,125 )# Local variable number
178- haslocal .append (125 )
179145def_op ('DELETE_FAST' ,126 )# Local variable number
180- haslocal .append (126 )
181146def_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 )
185149def_op ('RAISE_VARARGS' ,130 )# Number of raise arguments (1, 2, or 3)
186150def_op ('GET_AWAITABLE' ,131 )
187151def_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)
189153def_op ('MAKE_CELL' ,135 )
190- hasfree .append (135 )
191154def_op ('LOAD_DEREF' ,137 )
192- hasfree .append (137 )
193155def_op ('STORE_DEREF' ,138 )
194- hasfree .append (138 )
195156def_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 )
199159def_op ('CALL_FUNCTION_EX' ,142 )# Flags
200160def_op ('LOAD_FAST_AND_CLEAR' ,143 )# Local variable number
201- haslocal .append (143 )
202161def_op ('EXTENDED_ARG' ,144 )
203- EXTENDED_ARG = 144
162+ EXTENDED_ARG = opmap [ 'EXTENDED_ARG' ]
204163def_op ('LIST_APPEND' ,145 )
205164def_op ('SET_ADD' ,146 )
206165def_op ('MAP_ADD' ,147 )
207- hasfree .append (148 )
208166def_op ('COPY_FREE_VARS' ,149 )
209167def_op ('YIELD_VALUE' ,150 )
210168def_op ('RESUME' ,151 )# This must be kept in sync with deepfreeze.py
@@ -224,12 +182,10 @@ def pseudo_op(name, op, real_ops):
224182def_op ('STORE_FAST_STORE_FAST' ,170 )
225183def_op ('CALL' ,171 )
226184def_op ('KW_NAMES' ,172 )
227- hasconst .append (172 )
228185def_op ('CALL_INTRINSIC_1' ,173 )
229186def_op ('CALL_INTRINSIC_2' ,174 )
230- name_op ('LOAD_FROM_DICT_OR_GLOBALS' ,175 )
187+ def_op ('LOAD_FROM_DICT_OR_GLOBALS' ,175 )
231188def_op ('LOAD_FROM_DICT_OR_DEREF' ,176 )
232- hasfree .append (176 )
233189def_op ('SET_FUNCTION_ATTRIBUTE' ,177 )# Attribute
234190
235191# Optimizer hook
@@ -258,16 +214,12 @@ def pseudo_op(name, op, real_ops):
258214def_op ('INSTRUMENTED_LINE' ,254 )
259215# 255 is reserved
260216
261- hasarg .extend ([op for op in opmap .values ()if op >= HAVE_ARGUMENT ])
262217
263218MIN_PSEUDO_OPCODE = 256
264219
265220pseudo_op ('SETUP_FINALLY' ,256 , ['NOP' ])
266- hasexc .append (256 )
267221pseudo_op ('SETUP_CLEANUP' ,257 , ['NOP' ])
268- hasexc .append (257 )
269222pseudo_op ('SETUP_WITH' ,258 , ['NOP' ])
270- hasexc .append (258 )
271223pseudo_op ('POP_BLOCK' ,259 , ['NOP' ])
272224
273225pseudo_op ('JUMP' ,260 , ['JUMP_FORWARD' ,'JUMP_BACKWARD' ])
@@ -283,12 +235,29 @@ def pseudo_op(name, op, real_ops):
283235
284236MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len (_pseudo_ops )- 1
285237
286- del def_op ,name_op , jrel_op , jabs_op , pseudo_op
238+ del def_op ,pseudo_op
287239
288240opname = ['<%r>' % (op ,)for op in range (MAX_PSEUDO_OPCODE + 1 )]
289241for op ,i in opmap .items ():
290242opname [i ]= op
291243
244+ # The build uses older versions of Python which do not have _opcode.has_* functions
245+ if sys .version_info [:2 ]>= (3 ,13 ):
246+ # These lists are documented as part of the dis module's API
247+ hasarg = [op for op in opmap .values ()if _opcode .has_arg (op )]
248+ hasconst = [op for op in opmap .values ()if _opcode .has_const (op )]
249+ hasname = [op for op in opmap .values ()if _opcode .has_name (op )]
250+ hasjump = [op for op in opmap .values ()if _opcode .has_jump (op )]
251+ hasjrel = hasjump # for backward compatibility
252+ hasjabs = []
253+ hasfree = [op for op in opmap .values ()if _opcode .has_free (op )]
254+ haslocal = [op for op in opmap .values ()if _opcode .has_local (op )]
255+ hasexc = [op for op in opmap .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" ,"+" ),