Skip to content

Instantly share code, notes, and snippets.

@zahlman
Created June 26, 2022 04:39
Show Gist options
  • Select an option

  • Save zahlman/18a4492018ebf43dbc33ecd2c322650d to your computer and use it in GitHub Desktop.

Select an option

Save zahlman/18a4492018ebf43dbc33ecd2c322650d to your computer and use it in GitHub Desktop.
Initial prototype: hack recursive functions to look themselves up in the function's pre-bound consts, instead of doing a global namespace lookup
import dis
def filter_code(func, replacement):
name = func.__name__
code = func.__code__.co_code
begin, do_fix = None, None
for i in dis.get_instructions(func):
if begin is not None: # every time except the first
end = i.offset
yield replacement if do_fix else code[begin:end]
begin, do_fix = i.offset, (i.opname == 'LOAD_GLOBAL' and i.argval == name)
# handle the last
yield replacement if do_fix else code[begin:]
def rewrite(func):
consts = func.__code__.co_consts + (func,)
load_opcode = bytes([dis.opmap['LOAD_CONST'], len(consts) - 1])
fixed_code = b''.join(filter_code(func, load_opcode))
func.__code__ = func.__code__.replace(co_consts=consts, co_code=fixed_code)
return func # for decorator usage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment