Skip to content

Instantly share code, notes, and snippets.

@ammaraskar
Created October 13, 2021 19:29
Show Gist options
  • Save ammaraskar/6d81ca75f379c9e929089ab44c0d8702 to your computer and use it in GitHub Desktop.
Save ammaraskar/6d81ca75f379c9e929089ab44c0d8702 to your computer and use it in GitHub Desktop.
@activate_goto
def f():
    x = 0
    print('Hello World')
    x += 1
    if x > 10:
        goto_8
    goto_2

    return x

$ python goto.py
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
11
from bytecode import Bytecode, Instr, Label
def activate_goto(f):
bytecode = Bytecode.from_code(f.__code__)
# Map line numbers to a label to the start of that line.
line_mapping = {}
for i, instr in enumerate(bytecode):
if not isinstance(instr, Instr):
continue
line_number = instr.lineno - bytecode.first_lineno - 1
if line_number not in line_mapping:
label = Label()
bytecode.insert(i, label)
line_mapping[line_number] = label
for i, instr in enumerate(bytecode):
if not isinstance(instr, Instr) or instr.name != 'LOAD_GLOBAL':
continue
if not instr.arg.startswith("goto"):
continue
target_line = int(instr.arg.replace("goto_", ""))
target_label = line_mapping[target_line]
instr.set('JUMP_ABSOLUTE', target_label)
# Set the next instruction (POP_TOP) to be a no-op
bytecode[i + 1].set('NOP')
new_code = bytecode.to_code()
f.__code__ = new_code
return f
@activate_goto
def f():
x = 0
print('Hello World')
x += 1
if x > 10:
goto_8
goto_2
return x
if __name__ == '__main__':
print(f())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment