4
4
operate on bytecodes (e.g. peephole optimizers).
5
5
"""
6
6
7
- __all__ = ["cmp_op" , "hasarg" , "hasconst" , "hasname" , "hasjrel" , "hasjabs" ,
8
- "haslocal" , "hascompare" , "hasfree" , "hasexc" , "opname" , "opmap" ,
9
- "stack_effect" , "HAVE_ARGUMENT" , "EXTENDED_ARG" ]
10
7
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
11
13
from _opcode import stack_effect
12
14
13
15
import sys
17
19
18
20
cmp_op = ('<' , '<=' , '==' , '!=' , '>' , '>=' )
19
21
20
- hasarg = []
21
- hasconst = []
22
- hasname = []
23
- hasjrel = []
24
- hasjabs = []
25
- haslocal = []
26
- hascompare = []
27
- hasfree = []
28
- hasexc = []
29
-
30
22
31
23
ENABLE_SPECIALIZATION = True
32
24
33
25
def is_pseudo (op ):
34
26
return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE
35
27
36
- oplists = [hasarg , hasconst , hasname , hasjrel , hasjabs ,
37
- haslocal , hascompare , hasfree , hasexc ]
38
-
39
28
opmap = {}
40
29
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.
43
32
_pseudo_ops = {}
44
33
45
34
def def_op (name , op ):
46
35
opmap [name ] = op
47
36
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
-
60
37
def pseudo_op (name , op , real_ops ):
61
38
def_op (name , op )
62
39
_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 )
69
40
70
41
71
42
# Instruction opcodes for compiled code
@@ -137,74 +108,61 @@ def pseudo_op(name, op, real_ops):
137
108
138
109
HAVE_ARGUMENT = 90 # real opcodes from here have an argument:
139
110
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 ) # ""
142
113
def_op ('UNPACK_SEQUENCE' , 92 ) # Number of tuple items
143
- jrel_op ('FOR_ITER' , 93 )
114
+ def_op ('FOR_ITER' , 93 )
144
115
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 ) # ""
149
120
def_op ('SWAP' , 99 )
150
121
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
153
123
def_op ('BUILD_TUPLE' , 102 ) # Number of tuple items
154
124
def_op ('BUILD_LIST' , 103 ) # Number of list items
155
125
def_op ('BUILD_SET' , 104 ) # Number of set items
156
126
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
158
128
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
167
136
def_op ('IS_OP' , 117 )
168
137
def_op ('CONTAINS_OP' , 118 )
169
138
def_op ('RERAISE' , 119 )
170
139
def_op ('COPY' , 120 )
171
140
def_op ('RETURN_CONST' , 121 )
172
- hasconst .append (121 )
173
141
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
175
143
def_op ('LOAD_FAST' , 124 ) # Local variable number, no null check
176
- haslocal .append (124 )
177
144
def_op ('STORE_FAST' , 125 ) # Local variable number
178
- haslocal .append (125 )
179
145
def_op ('DELETE_FAST' , 126 ) # Local variable number
180
- haslocal .append (126 )
181
146
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 )
185
149
def_op ('RAISE_VARARGS' , 130 ) # Number of raise arguments (1, 2, or 3)
186
150
def_op ('GET_AWAITABLE' , 131 )
187
151
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)
189
153
def_op ('MAKE_CELL' , 135 )
190
- hasfree .append (135 )
191
154
def_op ('LOAD_DEREF' , 137 )
192
- hasfree .append (137 )
193
155
def_op ('STORE_DEREF' , 138 )
194
- hasfree .append (138 )
195
156
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 )
199
159
def_op ('CALL_FUNCTION_EX' , 142 ) # Flags
200
160
def_op ('LOAD_FAST_AND_CLEAR' , 143 ) # Local variable number
201
- haslocal .append (143 )
202
161
def_op ('EXTENDED_ARG' , 144 )
203
- EXTENDED_ARG = 144
162
+ EXTENDED_ARG = opmap [ 'EXTENDED_ARG' ]
204
163
def_op ('LIST_APPEND' , 145 )
205
164
def_op ('SET_ADD' , 146 )
206
165
def_op ('MAP_ADD' , 147 )
207
- hasfree .append (148 )
208
166
def_op ('COPY_FREE_VARS' , 149 )
209
167
def_op ('YIELD_VALUE' , 150 )
210
168
def_op ('RESUME' , 151 ) # This must be kept in sync with deepfreeze.py
@@ -224,12 +182,10 @@ def pseudo_op(name, op, real_ops):
224
182
def_op ('STORE_FAST_STORE_FAST' , 170 )
225
183
def_op ('CALL' , 171 )
226
184
def_op ('KW_NAMES' , 172 )
227
- hasconst .append (172 )
228
185
def_op ('CALL_INTRINSIC_1' , 173 )
229
186
def_op('CALL_INTRINSIC_2' , 174 )
230
- name_op ('LOAD_FROM_DICT_OR_GLOBALS' , 175 )
187
+ def_op ('LOAD_FROM_DICT_OR_GLOBALS' , 175 )
231
188
def_op ('LOAD_FROM_DICT_OR_DEREF' , 176 )
232
- hasfree .append (176 )
233
189
def_op ('SET_FUNCTION_ATTRIBUTE' , 177 ) # Attribute
234
190
235
191
# Optimizer hook
@@ -258,16 +214,12 @@ def pseudo_op(name, op, real_ops):
258
214
def_op ('INSTRUMENTED_LINE' , 254 )
259
215
# 255 is reserved
260
216
261
- hasarg .extend ([op for op in opmap .values () if op >= HAVE_ARGUMENT ])
262
217
263
218
MIN_PSEUDO_OPCODE = 256
264
219
265
220
pseudo_op ('SETUP_FINALLY' , 256 , ['NOP' ])
266
- hasexc .append (256 )
267
221
pseudo_op ('SETUP_CLEANUP' , 257 , ['NOP' ])
268
- hasexc .append (257 )
269
222
pseudo_op ('SETUP_WITH' , 258 , ['NOP' ])
270
- hasexc .append (258 )
271
223
pseudo_op ('POP_BLOCK' , 259 , ['NOP' ])
272
224
273
225
pseudo_op ('JUMP' , 260 , ['JUMP_FORWARD' , 'JUMP_BACKWARD' ])
@@ -283,12 +235,29 @@ def pseudo_op(name, op, real_ops):
283
235
284
236
MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len (_pseudo_ops ) - 1
285
237
286
- del def_op , name_op , jrel_op , jabs_op , pseudo_op
238
+ del def_op , pseudo_op
287
239
288
240
opname = ['<%r>' % (op ,) for op in range (MAX_PSEUDO_OPCODE + 1 )]
289
241
for op , i in opmap .items ():
290
242
opname [i ] = op
291
243
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" ]]
292
261
293
262
_nb_ops = [
294
263
("NB_ADD" , "+" ),
0 commit comments