Stream: helpdesk (published)

Topic: Getting code lowered with only the function type


view this post on Zulip Mason Protter (Mar 05 2021 at 22:21):

So I know that I can get the lowered code for a method with code_lowered(f, Tuple{...}), but that requires an instance of the function. What if I only have the type? Usually, you can proceed by just doing F.instance, but that won't work for a closure.

view this post on Zulip Mason Protter (Mar 05 2021 at 22:25):

To be clear, how could this generated function body get the proper code_lowered for this closure?

julia> cl = let x = 1
           y -> x + y
       end
#4 (generic function with 1 method)

julia> @generated function foo(f, x)
           # need the code_lowered for `f(::typeof(x))` here
       end
foo (generic function with 1 method)

given that I can't do

julia> typeof(cl).instance
ERROR: UndefRefError: access to undefined reference

view this post on Zulip Takafumi Arakaki (tkf) (Mar 05 2021 at 22:29):

It looks like you can do Base.uncompressed_ir(Base.which(Tuple{typeof(identity),Int})) after 1.6.

view this post on Zulip Mason Protter (Mar 05 2021 at 22:51):

There's gotta be a way that works with all julia versions though, right? Since cassette.jl and IRTools.jl worth through generated functions and worked on 1.0

view this post on Zulip Takafumi Arakaki (tkf) (Mar 05 2021 at 22:55):

Yeah, I was just too lazy to cook it up. I know you can use Base.uncompressed_ast for backward compatibility. Not sure what's the backward-compatible way to emulate which(::Type), though.

view this post on Zulip Takafumi Arakaki (tkf) (Mar 05 2021 at 22:57):

since which is a public API, it'd make sense to put it in Compat.jl

view this post on Zulip Mason Protter (Mar 05 2021 at 23:07):

Ah I see

view this post on Zulip Takafumi Arakaki (tkf) (Mar 05 2021 at 23:16):

It looks like you can just copy & paste the last few lines of which:

julia> function getmethod(tt)
           m = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), tt, typemax(UInt))
           if m === nothing
               error("no unique matching method found for the specified argument types")
           end
           return m.func::Method
       end
getmethod (generic function with 1 method)

julia> getmethod(Tuple{typeof(identity),Int})
identity(x) in Base at operators.jl:511

view this post on Zulip Takafumi Arakaki (tkf) (Mar 05 2021 at 23:16):

(works in 1.0 and 1.5)

view this post on Zulip Mason Protter (Mar 05 2021 at 23:17):

beautiful, thank you!


Last updated: Oct 02 2023 at 04:34 UTC