diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-05-08 20:44:54 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-05-08 20:44:54 (GMT) |
commit | 3e99fdeed5cff4eda913ea0082cdb94e59ce629d (patch) | |
tree | 6967ad7b7a9ce67e532dccaf65bb4bb107308e93 /Lib/dis.py | |
parent | ce41287e996351735ec1564bc1d701dd9057bdcf (diff) | |
parent | 02d9f5e5b2ee2662cb6776ebdafa2f3169452e41 (diff) | |
download | cpython-3e99fdeed5cff4eda913ea0082cdb94e59ce629d.zip cpython-3e99fdeed5cff4eda913ea0082cdb94e59ce629d.tar.gz cpython-3e99fdeed5cff4eda913ea0082cdb94e59ce629d.tar.bz2 |
Issue #26881: The modulefinder module now supports extended opcode arguments.
Diffstat (limited to 'Lib/dis.py')
-rw-r--r-- | Lib/dis.py | 55 |
1 files changed, 26 insertions, 29 deletions
@@ -284,31 +284,17 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None, """ labels = findlabels(code) - extended_arg = 0 starts_line = None free = None - # enumerate() is not an option, since we sometimes process - # multiple elements on a single pass through the loop - n = len(code) - i = 0 - while i < n: - op = code[i] - offset = i + for offset, op, arg in _unpack_opargs(code): if linestarts is not None: - starts_line = linestarts.get(i, None) + starts_line = linestarts.get(offset, None) if starts_line is not None: starts_line += line_offset - is_jump_target = i in labels - i = i+1 - arg = None + is_jump_target = offset in labels argval = None argrepr = '' - if op >= HAVE_ARGUMENT: - arg = code[i] + code[i+1]*256 + extended_arg - extended_arg = 0 - i = i+2 - if op == EXTENDED_ARG: - extended_arg = arg*65536 + if arg is not None: # Set argval to the dereferenced value of the argument when # availabe, and argrepr to the string representation of argval. # _disassemble_bytes needs the string repr of the @@ -319,7 +305,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None, elif op in hasname: argval, argrepr = _get_name_info(arg, names) elif op in hasjrel: - argval = i + arg + argval = offset + 3 + arg argrepr = "to " + repr(argval) elif op in haslocal: argval, argrepr = _get_name_info(arg, varnames) @@ -329,7 +315,7 @@ def _get_instructions_bytes(code, varnames=None, names=None, constants=None, elif op in hasfree: argval, argrepr = _get_name_info(arg, cells) elif op in hasnargs: - argrepr = "%d positional, %d keyword pair" % (code[i-2], code[i-1]) + argrepr = "%d positional, %d keyword pair" % (arg%256, arg//256) yield Instruction(opname[op], op, arg, argval, argrepr, offset, starts_line, is_jump_target) @@ -365,26 +351,37 @@ def _disassemble_str(source, *, file=None): disco = disassemble # XXX For backwards compatibility -def findlabels(code): - """Detect all offsets in a byte code which are jump targets. - - Return the list of offsets. - - """ - labels = [] +def _unpack_opargs(code): # enumerate() is not an option, since we sometimes process # multiple elements on a single pass through the loop + extended_arg = 0 n = len(code) i = 0 while i < n: op = code[i] + offset = i i = i+1 + arg = None if op >= HAVE_ARGUMENT: - arg = code[i] + code[i+1]*256 + arg = code[i] + code[i+1]*256 + extended_arg + extended_arg = 0 i = i+2 + if op == EXTENDED_ARG: + extended_arg = arg*65536 + yield (offset, op, arg) + +def findlabels(code): + """Detect all offsets in a byte code which are jump targets. + + Return the list of offsets. + + """ + labels = [] + for offset, op, arg in _unpack_opargs(code): + if arg is not None: label = -1 if op in hasjrel: - label = i+arg + label = offset + 3 + arg elif op in hasjabs: label = arg if label >= 0: |