Skip to content

dictionary literals are not decompiled correctly #40

@mristin

Description

@mristin

Hi,
I encountered that dictionary literals can not be decompiled and result in an exception:

>>> import meta.decompiler
>>> f = lambda: {"x": 4}
>>> meta.decompiler.decompile_func(f)

results in a traceback:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/marko/workspace/pqryopen/icontract/venv3/lib/python3.5/site-packages/meta/decompiler/__init__.py", line 37, in decompile_func
    ast_node = make_function(code, defaults=[], lineno=code.co_firstlineno)
  File "/home/marko/workspace/pqryopen/icontract/venv3/lib/python3.5/site-packages/meta/decompiler/instructions.py", line 137, in make_function
    stmnts = instructions.stmnt()
  File "/home/marko/workspace/pqryopen/icontract/venv3/lib/python3.5/site-packages/meta/decompiler/instructions.py", line 310, in stmnt
    self.visit(instr)
  File "/home/marko/workspace/pqryopen/icontract/venv3/lib/python3.5/site-packages/meta/decompiler/instructions.py", line 324, in visit
    method(instr)
  File "/home/marko/workspace/pqryopen/icontract/venv3/lib/python3.5/site-packages/meta/decompiler/simple_instructions.py", line 495, in BUILD_MAP
    new_instr = self.ilst.pop(0)
IndexError: pop from empty list

When I look at meta/decompiler/simple_instructions.py, it seems to me that you expect intructions:

    def BUILD_MAP(self, instr):

        nitems = instr.oparg
        keys = []
        values = []
        for i in range(nitems):
            map_instrs = []
            while 1:
                new_instr = self.ilst.pop(0)

                if new_instr.opname == 'STORE_MAP':
                    break

                map_instrs.append(new_instr)

            items = self.decompile_block(map_instrs).stmnt()
            assert len(items) == 2

            values.append(items[0])
            keys.append(items[1])


        list_ = _ast.Dict(keys=keys, values=values, lineno=instr.lineno, col_offset=0)
        self.push_ast_item(list_)

However, the python 3 byte code looks like:

>>> import dis
>>> f = lambda: {"x": 4}
>>> dis.dis(f)
  1           0 LOAD_CONST               1 ('x')
              3 LOAD_CONST               2 (4)
              6 BUILD_MAP                1
              9 RETURN_VALUE

I tried to read the code, but I was a bit confused where you set self.ilst and what it represents? There seems to be no constructor for the class SimpleInstructions, right?

I would be very grateful if you could guide me a bit how to fix this problem!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions