Hi, I'm wondering if there's a way to recompile the lowered AST back into a function and what additional information (other than the module it should be evaluate in) is necessary to do that what I've tried and would like to do is demonstrated with the code attached. The idea is that I would like to modify the code of a function/method before calling it (in this case, I am replacing it with the code from another function with the same signature). (In another word, the question is how to construct a function from code1 with ast2 and run it.)
It will also be nice if there's more documentation on this "lowered AST" since it seems to be very different form the one you get in a function definition. (e.g. what is the array in `code_lowered(+, (Float64, Float64))[1].args[2]` mean) A brief description of what I want to do. I'm writing a control system with dynamic logic. However, since the code might not be running on a single host, it is hard to use an existing interpreter to do what I want. Trying to avoid inventing yet another language, I hope to use a subset of an existing language and somehow transform it into a representation that can be run somewhere else and it seems that the inspection and meta programming feature in julia is very useful for this. It might be possible to just apply a macro to every function / method definition but it will be much harder to write. I would rather try to "trace" the excution and use the AST acquired at runtime. For that I would like to know more about the lowered AST and possibly how to execute a modified version in order to trace recursive / nested function calls. This might not be the best way to do it and I'm still in planning stage so any suggestions on the design is also welcome. Cheers, Yichao Yu
#
function get_code(func, args)
return which(func, Base.typesof(args...)).func.code
end
function recompile(func1, func2, args)
code1 = get_code(func1, args)
code2 = get_code(func2, args)
@assert code1.module == code2.module
eval_code1 = code1.module.eval(code1)
eval_res1 = eval_code1(args...)
@assert eval_res1 == func1(args...)
println("eval_code: $(eval_res1)")
eval_code2 = code2.module.eval(code2)
eval_res2 = eval_code2(args...)
@assert eval_res2 == func2(args...)
println("eval_code: $(eval_res2)")
ast1 = ccall(:jl_uncompress_ast, Any, (Any, Any), code1, code1.ast)
println("ast1: $ast1")
ast2 = ccall(:jl_uncompress_ast, Any, (Any, Any), code2, code2.ast)
println("ast2: $ast2")
code1.ast = ccall(:jl_compress_ast, Any, (Any, Any), code1, ast2)
println("new_code: $code1")
eval_new_code = code1.module.eval(code1)
eval_new_res = eval_new_code(args...)
@assert eval_new_res == func2(args...)
println("eval_new_code: $(eval_new_res)")
end
recompile(+, -, (1.2, 3.4))
signature.asc
Description: This is a digitally signed message part.
