@@ -275,31 +275,17 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
275275
276276 """
277277 labels = findlabels (code )
278- extended_arg = 0
279278 starts_line = None
280279 free = None
281- # enumerate() is not an option, since we sometimes process
282- # multiple elements on a single pass through the loop
283- n = len (code )
284- i = 0
285- while i < n :
286- op = code [i ]
287- offset = i
280+ for offset , op , arg in _unpack_opargs (code ):
288281 if linestarts is not None :
289- starts_line = linestarts .get (i , None )
282+ starts_line = linestarts .get (offset , None )
290283 if starts_line is not None :
291284 starts_line += line_offset
292- is_jump_target = i in labels
293- i = i + 1
294- arg = None
285+ is_jump_target = offset in labels
295286 argval = None
296287 argrepr = ''
297- if op >= HAVE_ARGUMENT :
298- arg = code [i ] + code [i + 1 ]* 256 + extended_arg
299- extended_arg = 0
300- i = i + 2
301- if op == EXTENDED_ARG :
302- extended_arg = arg * 65536
288+ if arg is not None :
303289 # Set argval to the dereferenced value of the argument when
304290 # availabe, and argrepr to the string representation of argval.
305291 # _disassemble_bytes needs the string repr of the
@@ -310,7 +296,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
310296 elif op in hasname :
311297 argval , argrepr = _get_name_info (arg , names )
312298 elif op in hasjrel :
313- argval = i + arg
299+ argval = offset + 3 + arg
314300 argrepr = "to " + repr (argval )
315301 elif op in haslocal :
316302 argval , argrepr = _get_name_info (arg , varnames )
@@ -320,7 +306,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
320306 elif op in hasfree :
321307 argval , argrepr = _get_name_info (arg , cells )
322308 elif op in hasnargs :
323- argrepr = "%d positional, %d keyword pair" % (code [ i - 2 ], code [ i - 1 ] )
309+ argrepr = "%d positional, %d keyword pair" % (arg % 256 , arg // 256 )
324310 yield Instruction (opname [op ], op ,
325311 arg , argval , argrepr ,
326312 offset , starts_line , is_jump_target )
@@ -356,26 +342,37 @@ def _disassemble_str(source, *, file=None):
356342
357343disco = disassemble # XXX For backwards compatibility
358344
359- def findlabels (code ):
360- """Detect all offsets in a byte code which are jump targets.
361-
362- Return the list of offsets.
363-
364- """
365- labels = []
345+ def _unpack_opargs (code ):
366346 # enumerate() is not an option, since we sometimes process
367347 # multiple elements on a single pass through the loop
348+ extended_arg = 0
368349 n = len (code )
369350 i = 0
370351 while i < n :
371352 op = code [i ]
353+ offset = i
372354 i = i + 1
355+ arg = None
373356 if op >= HAVE_ARGUMENT :
374- arg = code [i ] + code [i + 1 ]* 256
357+ arg = code [i ] + code [i + 1 ]* 256 + extended_arg
358+ extended_arg = 0
375359 i = i + 2
360+ if op == EXTENDED_ARG :
361+ extended_arg = arg * 65536
362+ yield (offset , op , arg )
363+
364+ def findlabels (code ):
365+ """Detect all offsets in a byte code which are jump targets.
366+
367+ Return the list of offsets.
368+
369+ """
370+ labels = []
371+ for offset , op , arg in _unpack_opargs (code ):
372+ if arg is not None :
376373 label = - 1
377374 if op in hasjrel :
378- label = i + arg
375+ label = offset + 3 + arg
379376 elif op in hasjabs :
380377 label = arg
381378 if label >= 0 :
0 commit comments