@@ -284,31 +284,17 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
284284
285285 """
286286 labels = findlabels (code )
287- extended_arg = 0
288287 starts_line = None
289288 free = None
290- # enumerate() is not an option, since we sometimes process
291- # multiple elements on a single pass through the loop
292- n = len (code )
293- i = 0
294- while i < n :
295- op = code [i ]
296- offset = i
289+ for offset , op , arg in _unpack_opargs (code ):
297290 if linestarts is not None :
298- starts_line = linestarts .get (i , None )
291+ starts_line = linestarts .get (offset , None )
299292 if starts_line is not None :
300293 starts_line += line_offset
301- is_jump_target = i in labels
302- i = i + 1
303- arg = None
294+ is_jump_target = offset in labels
304295 argval = None
305296 argrepr = ''
306- if op >= HAVE_ARGUMENT :
307- arg = code [i ] + code [i + 1 ]* 256 + extended_arg
308- extended_arg = 0
309- i = i + 2
310- if op == EXTENDED_ARG :
311- extended_arg = arg * 65536
297+ if arg is not None :
312298 # Set argval to the dereferenced value of the argument when
313299 # availabe, and argrepr to the string representation of argval.
314300 # _disassemble_bytes needs the string repr of the
@@ -319,7 +305,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
319305 elif op in hasname :
320306 argval , argrepr = _get_name_info (arg , names )
321307 elif op in hasjrel :
322- argval = i + arg
308+ argval = offset + 3 + arg
323309 argrepr = "to " + repr (argval )
324310 elif op in haslocal :
325311 argval , argrepr = _get_name_info (arg , varnames )
@@ -329,7 +315,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None,
329315 elif op in hasfree :
330316 argval , argrepr = _get_name_info (arg , cells )
331317 elif op in hasnargs :
332- argrepr = "%d positional, %d keyword pair" % (code [ i - 2 ], code [ i - 1 ] )
318+ argrepr = "%d positional, %d keyword pair" % (arg % 256 , arg // 256 )
333319 yield Instruction (opname [op ], op ,
334320 arg , argval , argrepr ,
335321 offset , starts_line , is_jump_target )
@@ -365,26 +351,37 @@ def _disassemble_str(source, *, file=None):
365351
366352disco = disassemble # XXX For backwards compatibility
367353
368- def findlabels (code ):
369- """Detect all offsets in a byte code which are jump targets.
370-
371- Return the list of offsets.
372-
373- """
374- labels = []
354+ def _unpack_opargs (code ):
375355 # enumerate() is not an option, since we sometimes process
376356 # multiple elements on a single pass through the loop
357+ extended_arg = 0
377358 n = len (code )
378359 i = 0
379360 while i < n :
380361 op = code [i ]
362+ offset = i
381363 i = i + 1
364+ arg = None
382365 if op >= HAVE_ARGUMENT :
383- arg = code [i ] + code [i + 1 ]* 256
366+ arg = code [i ] + code [i + 1 ]* 256 + extended_arg
367+ extended_arg = 0
384368 i = i + 2
369+ if op == EXTENDED_ARG :
370+ extended_arg = arg * 65536
371+ yield (offset , op , arg )
372+
373+ def findlabels (code ):
374+ """Detect all offsets in a byte code which are jump targets.
375+
376+ Return the list of offsets.
377+
378+ """
379+ labels = []
380+ for offset , op , arg in _unpack_opargs (code ):
381+ if arg is not None :
385382 label = - 1
386383 if op in hasjrel :
387- label = i + arg
384+ label = offset + 3 + arg
388385 elif op in hasjabs :
389386 label = arg
390387 if label >= 0 :
0 commit comments