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))

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to