23
23
"""
24
24
25
25
import sys
26
- import uncompyle6 .scanners .scanner2 as scan
27
26
28
27
# bytecode verification, verify(), uses JUMP_OPs from here
29
28
from xdis import iscode
30
- from xdis .opcodes import opcode_26
31
29
from xdis .bytecode import _get_const_info
30
+ from xdis .opcodes import opcode_26
32
31
32
+ import uncompyle6 .scanners .scanner2 as scan
33
33
from uncompyle6 .scanner import Token
34
34
35
35
intern = sys .intern
36
36
37
37
JUMP_OPS = opcode_26 .JUMP_OPS
38
38
39
+
39
40
class Scanner26 (scan .Scanner2 ):
40
41
def __init__ (self , show_asm = False ):
41
42
super (Scanner26 , self ).__init__ ((2 , 6 ), show_asm )
42
43
43
44
# "setup" opcodes
44
- self .setup_ops = frozenset ([
45
- self .opc .SETUP_EXCEPT , self .opc .SETUP_FINALLY ,
46
- ])
45
+ self .setup_ops = frozenset (
46
+ [
47
+ self .opc .SETUP_EXCEPT ,
48
+ self .opc .SETUP_FINALLY ,
49
+ ]
50
+ )
47
51
48
52
return
49
53
@@ -76,8 +80,9 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
76
80
77
81
# show_asm = 'after'
78
82
if show_asm in ("both" , "before" ):
83
+ print ("\n # ---- before tokenization:" )
79
84
for instr in bytecode .get_instructions (co ):
80
- print (instr .disassemble ())
85
+ print (instr .disassemble (self . opc ))
81
86
82
87
# Container for tokens
83
88
tokens = []
@@ -96,17 +101,18 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
96
101
# 'LOAD_ASSERT' is used in assert statements.
97
102
self .load_asserts = set ()
98
103
for i in self .op_range (0 , codelen ):
99
-
100
104
# We need to detect the difference between:
101
105
# raise AssertionError
102
106
# and
103
107
# assert ...
104
- if (self .code [i ] == self .opc .JUMP_IF_TRUE and
105
- i + 4 < codelen and
106
- self .code [i + 3 ] == self .opc .POP_TOP and
107
- self .code [i + 4 ] == self .opc .LOAD_GLOBAL ):
108
- if names [self .get_argument (i + 4 )] == 'AssertionError' :
109
- self .load_asserts .add (i + 4 )
108
+ if (
109
+ self .code [i ] == self .opc .JUMP_IF_TRUE
110
+ and i + 4 < codelen
111
+ and self .code [i + 3 ] == self .opc .POP_TOP
112
+ and self .code [i + 4 ] == self .opc .LOAD_GLOBAL
113
+ ):
114
+ if names [self .get_argument (i + 4 )] == "AssertionError" :
115
+ self .load_asserts .add (i + 4 )
110
116
111
117
jump_targets = self .find_jump_targets (show_asm )
112
118
# contains (code, [addrRefToCode])
@@ -131,7 +137,8 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
131
137
i += 1
132
138
op = self .code [offset ]
133
139
op_name = self .opname [op ]
134
- oparg = None ; pattr = None
140
+ oparg = None
141
+ pattr = None
135
142
136
143
if offset in jump_targets :
137
144
jump_idx = 0
@@ -142,28 +149,37 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
142
149
# properly. For example, a "loop" with an "if" nested in it should have the
143
150
# "loop" tag last so the grammar rule matches that properly.
144
151
last_jump_offset = - 1
145
- for jump_offset in sorted (jump_targets [offset ], reverse = True ):
152
+ for jump_offset in sorted (jump_targets [offset ], reverse = True ):
146
153
if jump_offset != last_jump_offset :
147
- tokens .append (Token (
148
- 'COME_FROM' , jump_offset , repr (jump_offset ),
149
- offset = "%s_%d" % (offset , jump_idx ),
150
- has_arg = True ))
154
+ tokens .append (
155
+ Token (
156
+ "COME_FROM" ,
157
+ jump_offset ,
158
+ repr (jump_offset ),
159
+ offset = "%s_%d" % (offset , jump_idx ),
160
+ has_arg = True ,
161
+ )
162
+ )
151
163
jump_idx += 1
152
164
last_jump_offset = jump_offset
153
165
elif offset in self .thens :
154
- tokens .append (Token (
155
- 'THEN' , None , self .thens [offset ],
156
- offset = "%s_0" % offset ,
157
- has_arg = True ))
166
+ tokens .append (
167
+ Token (
168
+ "THEN" ,
169
+ None ,
170
+ self .thens [offset ],
171
+ offset = "%s_0" % offset ,
172
+ has_arg = True ,
173
+ )
174
+ )
158
175
159
- has_arg = ( op >= self .opc .HAVE_ARGUMENT )
176
+ has_arg = op >= self .opc .HAVE_ARGUMENT
160
177
if has_arg :
161
178
oparg = self .get_argument (offset ) + extended_arg
162
179
extended_arg = 0
163
180
if op == self .opc .EXTENDED_ARG :
164
- extended_arg += self .extended_arg_val (oparg )
165
- continue
166
-
181
+ extended_arg += self .extended_arg_val (oparg )
182
+ continue
167
183
168
184
# Note: name used to match on rather than op since
169
185
# BUILD_SET isn't in earlier Pythons.
@@ -172,7 +188,14 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
172
188
"BUILD_SET" ,
173
189
):
174
190
t = Token (
175
- op_name , oparg , pattr , offset , self .linestarts .get (offset , None ), op , has_arg , self .opc
191
+ op_name ,
192
+ oparg ,
193
+ pattr ,
194
+ offset ,
195
+ self .linestarts .get (offset , None ),
196
+ op ,
197
+ has_arg ,
198
+ self .opc ,
176
199
)
177
200
178
201
collection_type = op_name .split ("_" )[1 ]
@@ -221,8 +244,8 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
221
244
# FIXME: this is a hack to catch stuff like:
222
245
# if x: continue
223
246
# the "continue" is not on a new line.
224
- if len (tokens ) and tokens [- 1 ].kind == ' JUMP_BACK' :
225
- tokens [- 1 ].kind = intern (' CONTINUE' )
247
+ if len (tokens ) and tokens [- 1 ].kind == " JUMP_BACK" :
248
+ tokens [- 1 ].kind = intern (" CONTINUE" )
226
249
227
250
elif op in self .opc .JABS_OPS :
228
251
pattr = repr (oparg )
@@ -240,17 +263,23 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
240
263
# CE - Hack for >= 2.5
241
264
# Now all values loaded via LOAD_CLOSURE are packed into
242
265
# a tuple before calling MAKE_CLOSURE.
243
- if (self .version >= (2 , 5 ) and op == self .opc .BUILD_TUPLE and
244
- self .code [self .prev [offset ]] == self .opc .LOAD_CLOSURE ):
266
+ if (
267
+ self .version >= (2 , 5 )
268
+ and op == self .opc .BUILD_TUPLE
269
+ and self .code [self .prev [offset ]] == self .opc .LOAD_CLOSURE
270
+ ):
245
271
continue
246
272
else :
247
- op_name = ' %s_%d' % (op_name , oparg )
273
+ op_name = " %s_%d" % (op_name , oparg )
248
274
customize [op_name ] = oparg
249
275
elif self .version > (2 , 0 ) and op == self .opc .CONTINUE_LOOP :
250
276
customize [op_name ] = 0
251
- elif op_name in """
277
+ elif (
278
+ op_name
279
+ in """
252
280
CONTINUE_LOOP EXEC_STMT LOAD_LISTCOMP LOAD_SETCOMP
253
- """ .split ():
281
+ """ .split ()
282
+ ):
254
283
customize [op_name ] = 0
255
284
elif op == self .opc .JUMP_ABSOLUTE :
256
285
# Further classify JUMP_ABSOLUTE into backward jumps
@@ -266,23 +295,24 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
266
295
# rule for that.
267
296
target = self .get_target (offset )
268
297
if target <= offset :
269
- op_name = 'JUMP_BACK'
270
- if (offset in self .stmts
271
- and self .code [offset + 3 ] not in (self .opc .END_FINALLY ,
272
- self .opc .POP_BLOCK )):
273
- if ((offset in self .linestarts and
274
- tokens [- 1 ].kind == 'JUMP_BACK' )
275
- or offset not in self .not_continue ):
276
- op_name = 'CONTINUE'
298
+ op_name = "JUMP_BACK"
299
+ if offset in self .stmts and self .code [offset + 3 ] not in (
300
+ self .opc .END_FINALLY ,
301
+ self .opc .POP_BLOCK ,
302
+ ):
303
+ if (
304
+ offset in self .linestarts and tokens [- 1 ].kind == "JUMP_BACK"
305
+ ) or offset not in self .not_continue :
306
+ op_name = "CONTINUE"
277
307
else :
278
308
# FIXME: this is a hack to catch stuff like:
279
309
# if x: continue
280
310
# the "continue" is not on a new line.
281
- if tokens [- 1 ].kind == ' JUMP_BACK' :
311
+ if tokens [- 1 ].kind == " JUMP_BACK" :
282
312
# We need 'intern' since we have
283
313
# already have processed the previous
284
314
# token.
285
- tokens [- 1 ].kind = intern (' CONTINUE' )
315
+ tokens [- 1 ].kind = intern (" CONTINUE" )
286
316
287
317
elif op == self .opc .LOAD_GLOBAL :
288
318
if offset in self .load_asserts :
@@ -316,6 +346,7 @@ def ingest(self, co, classname=None, code_objects={}, show_asm=None):
316
346
pass
317
347
318
348
if show_asm in ("both" , "after" ):
349
+ print ("\n # ---- after tokenization:" )
319
350
for t in tokens :
320
351
print (t .format (line_prefix = "" ))
321
352
print ()
0 commit comments