Skip to content

Instantly share code, notes, and snippets.

@femtomc
Created June 29, 2020 22:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save femtomc/18f3b8012ef6c861fccfca6dabe1a08a to your computer and use it in GitHub Desktop.
Save femtomc/18f3b8012ef6c861fccfca6dabe1a08a to your computer and use it in GitHub Desktop.
# Recursively wraps function calls with the below generated function call and inserts the context argument.
function remix!(ir, hooks = false)
pr = IRTools.Pipe(ir)
new = argument!(pr)
for (v, st) in pr
ex = st.expr
ex isa Expr && ex.head == :call && begin
if !(ex.args[1] isa GlobalRef && (ex.args[1].mod == Base || ex.args[1].mod == Core))
args = copy(ex.args)
ex = Expr(:call, :remix!, new, ex.args...)
pr[v] = ex
if hooks
insert!(pr, v, Expr(:call, :scrub!, new, args...))
insertafter!(pr, v, Expr(:call, :dub!, new, args...))
end
end
end
end
ir = IRTools.finish(pr)
# Swap.
ir_args = IRTools.arguments(ir)
insert!(ir_args, 2, ir_args[end])
pop!(ir_args)
argument!(ir)
insert!(ir_args, 3, ir_args[end])
ir = IRTools.renumber(ir)
ir
end
@generated function remix!(ctx::MixTable, fn::Function, args...)
T = Tuple{fn, args...}
m = IRTools.meta(T)
m isa Nothing && error("Error in remix!: could not derive lowered method body for $T.")
ir = IRTools.IR(m)
n_ir = remix!(ir)
updated = update!(m.code, n_ir)
pushfirst!(updated.slotnames, Symbol("#self#"))
return updated
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment