Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

handle simple parameters

  • Loading branch information...
commit f9d42f181f2c70ef5229eacbfdd6aafbe4d7ac97 1 parent 934632a
@alex authored
Showing with 27 additions and 7 deletions.
  1. +9 −7 decompile.py
  2. +18 −0 test_decompile.py
View
16 decompile.py
@@ -52,6 +52,8 @@ def parse_bytecode(code):
elif op in opcode.hasjrel:
# Make it absolute
arg = i + oparg
+ elif op in opcode.haslocal:
+ arg = code.co_varnames[oparg]
else:
raise NotImplementedError
instructions.append(Instruction(
@@ -91,7 +93,7 @@ def get_basic_block(self, idx):
def handle_simple_op(self, instr):
pass
- handle_LOAD_CONST = handle_LOAD_GLOBAL = handle_RETURN_VALUE = handle_POP_TOP = handle_simple_op
+ handle_LOAD_CONST = handle_LOAD_FAST = handle_LOAD_GLOBAL = handle_RETURN_VALUE = handle_POP_TOP = handle_simple_op
def handle_POP_JUMP_IF_FALSE(self, instr):
instr.true_block = self.get_basic_block(instr.new_idx + 1)
@@ -139,7 +141,6 @@ def indent(self):
finally:
self.indent_level -= 1
-
def evaluate(self):
while self.basic_blocks:
basic_block = self.basic_blocks.pop()
@@ -151,11 +152,9 @@ def handle_basic_block(self, basic_block):
handler = getattr(self, "handle_%s" % instr.opname)
handler(instr)
- def handle_LOAD_CONST(self, instr):
- self.buf.append(Literal(instr.arg))
-
- def handle_LOAD_GLOBAL(self, instr):
+ def handle_literal(self, instr):
self.buf.append(Literal(instr.arg))
+ handle_LOAD_CONST = handle_LOAD_FAST = handle_LOAD_GLOBAL = handle_literal
def handle_RETURN_VALUE(self, instr):
[obj] = self.get_and_clear_buf(1)
@@ -182,5 +181,8 @@ def decompile(function):
instructions = parse_bytecode(function.__code__)
start_bblock = BasicBlockFinder(instructions).find_basic_blocks()
body = Interpreter(start_bblock).evaluate()
- header = "def %s():\n" % function.__name__
+ header = "def %(name)s(%(args)s):\n" % {
+ "name": function.__name__,
+ "args": ", ".join(function.__code__.co_varnames[:function.__code__.co_argcount])
+ }
return header + body
View
18 test_decompile.py
@@ -53,6 +53,15 @@ def f():
return 2
""")
+ def test_simple_parameters(self):
+ def f(a):
+ return a
+
+ self.assert_decompiles(f, """
+ def f(a):
+ return a
+ """)
+
class TestBytecodeParser(object):
def assert_bytecode(self, func, expected):
instructions = parse_bytecode(func.__code__)
@@ -116,4 +125,13 @@ def f():
("POP_TOP",),
("LOAD_CONST", 1),
("RETURN_VALUE",)
+ ])
+
+ def test_parameter_name(self):
+ def f(a):
+ return a
+
+ self.assert_bytecode(f, [
+ ("LOAD_FAST", "a"),
+ ("RETURN_VALUE",)
])
Please sign in to comment.
Something went wrong with that request. Please try again.