Newer Older

Dead code in Python-generated bytecode

So I've made a couple of changes to Papaya (yeah, it's called Papaya now):

So, due to my use of BytecodeAssembler, I get free stack size calculations, but I get another feature which is somewhat annoying: dead-code prevention.

Why is this annoying? Because the Python compiler generates dead code all the time.

What this means is, if you decompile any non-trivial (and some quite-trivial) .pyc files created by Python, and then try to recompile then, then it will fail with an "AssertionError: Unknown stack size at this location" message.

For example, take the following, very simple .py file:

    while True:
if True:
continue
break

This is disassembled into the following:

    SETUP_LOOP 
label0:
LOAD_NAME True
JUMP_IF_FALSE label3
POP_TOP
LOAD_NAME True
JUMP_IF_FALSE label1
POP_TOP
JUMP_ABSOLUTE label0
JUMP_FORWARD label2
label1:
POP_TOP
label2:
BREAK_LOOP
JUMP_ABSOLUTE label0
label3:
POP_TOP
POP_BLOCK
LOAD_CONST None
RETURN_VALUE

Note the double JUMP. This is generated any time you have a continue statement, despite the fact that the second jump cannot ever be run. Also unecessary is the JUMP_ABSOLUTE after BREAK_LOOP.

Both of these cause an error in BytecodeAssembler because it has no context from which to determine the stack size at that point. Of course, that doesn't really matter since the code will never be run.

I'm currently stumped as to the best way to solve this issue, and I'm tired and don't want to think about it any more. :(

blog comments powered by Disqus