Skip to content

Commit 4e5de90

Browse files
committed
Revert "Use normal RuntimeGeneratedFunction constructor rather than macro"
This reverts commit ff1fd50. As discussed in #21, it's error prone for the user to control the module used for the RGF cache. So it's easiest to keep the constructor macro.
1 parent cee1c8a commit 4e5de90

File tree

3 files changed

+42
-38
lines changed

3 files changed

+42
-38
lines changed

src/RuntimeGeneratedFunctions.jl

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,31 @@ module RuntimeGeneratedFunctions
22

33
using ExprTools, Serialization, SHA
44

5-
export RuntimeGeneratedFunction, @RuntimeGeneratedFunction
5+
export @RuntimeGeneratedFunction
66

77

88
"""
9-
RuntimeGeneratedFunction(module, function_expression)
9+
RuntimeGeneratedFunction
1010
11-
Construct a function from `function_expression` in the scope of `module` which
12-
can be called immediately without world age problems. Somewhat like using
13-
`eval(function_expression)` and then calling the resulting function. The
14-
differences are:
11+
This type should be constructed via the macro @RuntimeGeneratedFunction.
12+
"""
13+
struct RuntimeGeneratedFunction{argnames,moduletag,id} <: Function
14+
body::Expr
15+
function RuntimeGeneratedFunction(moduletag, ex)
16+
def = splitdef(ex)
17+
args, body = normalize_args(def[:args]), def[:body]
18+
id = expr_to_id(body)
19+
cached_body = _cache_body(moduletag, id, body)
20+
new{Tuple(args),moduletag,id}(cached_body)
21+
end
22+
end
23+
24+
"""
25+
@RuntimeGeneratedFunction(function_expression)
26+
27+
Construct a function from `function_expression` which can be called immediately
28+
without world age problems. Somewhat like using `eval(function_expression)` and
29+
then calling the resulting function. The differences are:
1530
1631
* The result can be called immediately (immune to world age errors)
1732
* The result is not a named generic function, and doesn't participate in
@@ -26,32 +41,21 @@ RuntimeGeneratedFunctions.init(@__MODULE__) # Required at module top-level
2641
2742
function foo()
2843
expression = :((x,y)->x+y+1) # May be generated dynamically
29-
f = RuntimeGeneratedFunction(@__MODULE__, expression)
44+
f = @RuntimeGeneratedFunction(expression)
3045
f(1,2) # May be called immediately
3146
end
3247
```
3348
"""
34-
struct RuntimeGeneratedFunction{argnames,moduletag,id} <: Function
35-
body::Expr
36-
function RuntimeGeneratedFunction(mod::Module, ex)
37-
if !isdefined(mod, _tagname)
49+
macro RuntimeGeneratedFunction(ex)
50+
quote
51+
if !($(esc(:(@isdefined($_tagname)))))
3852
error("""You must use `RuntimeGeneratedFunctions.init(@__MODULE__)` at module
3953
top level before using runtime generated functions""")
4054
end
41-
moduletag = getfield(mod, _tagname)
42-
def = splitdef(ex)
43-
args, body = normalize_args(def[:args]), def[:body]
44-
id = expr_to_id(body)
45-
cached_body = _cache_body(moduletag, id, body)
46-
new{Tuple(args),moduletag,id}(cached_body)
47-
end
48-
end
49-
50-
51-
macro RuntimeGeneratedFunction(ex)
52-
Base.depwarn("`@RuntimeGeneratedFunction(ex)` is deprecated, use `RuntimeGeneratedFunction(@__MODULE__, ex)` instead.", :RuntimeGeneratedFunction)
53-
quote
54-
RuntimeGeneratedFunction(@__MODULE__, $(esc(ex)))
55+
RuntimeGeneratedFunction(
56+
$(esc(_tagname)),
57+
$(esc(ex))
58+
)
5559
end
5660
end
5761

@@ -64,7 +68,7 @@ end
6468
(f::RuntimeGeneratedFunction)(args::Vararg{Any,N}) where N = generated_callfunc(f, args...)
6569

6670
# We'll generate a method of this function in every module which wants to use
67-
# RuntimeGeneratedFunction
71+
# @RuntimeGeneratedFunction
6872
function generated_callfunc end
6973

7074
function generated_callfunc_body(argnames, moduletag, id, __args)
@@ -134,7 +138,7 @@ end
134138
RuntimeGeneratedFunctions.init(mod)
135139
136140
Use this at top level to set up your module `mod` before using
137-
`RuntimeGeneratedFunction(mod, ...)`.
141+
`@RuntimeGeneratedFunction`.
138142
"""
139143
function init(mod)
140144
lock(_cache_lock) do

test/precomp/RGFPrecompTest.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ module RGFPrecompTest
22
using RuntimeGeneratedFunctions
33
RuntimeGeneratedFunctions.init(@__MODULE__)
44

5-
f = RuntimeGeneratedFunction(@__MODULE__, :((x,y)->x+y))
5+
f = @RuntimeGeneratedFunction(:((x,y)->x+y))
66
end

test/runtests.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ ex3 = :(function (_du::T,_u::Vector{E},_p::P,_t::Any) where {T<:Vector,E,P}
2727
nothing
2828
end)
2929

30-
f1 = RuntimeGeneratedFunction(@__MODULE__, ex1)
31-
f2 = RuntimeGeneratedFunction(@__MODULE__, ex2)
32-
f3 = RuntimeGeneratedFunction(@__MODULE__, ex3)
30+
f1 = @RuntimeGeneratedFunction(ex1)
31+
f2 = @RuntimeGeneratedFunction(ex2)
32+
f3 = @RuntimeGeneratedFunction(ex3)
3333

3434
@test f1 isa Function
3535

@@ -62,7 +62,7 @@ function no_worldage()
6262
@inbounds _du[2] = _u[2]
6363
nothing
6464
end)
65-
f1 = RuntimeGeneratedFunction(@__MODULE__, ex)
65+
f1 = @RuntimeGeneratedFunction(ex)
6666
du = rand(2)
6767
u = rand(2)
6868
p = nothing
@@ -72,7 +72,7 @@ end
7272
@test no_worldage() === nothing
7373

7474
# Test show()
75-
@test sprint(show, RuntimeGeneratedFunction(@__MODULE__, Base.remove_linenums!(:((x,y)->x+y+1)))) ==
75+
@test sprint(show, @RuntimeGeneratedFunction(Base.remove_linenums!(:((x,y)->x+y+1)))) ==
7676
"""
7777
RuntimeGeneratedFunction(#=in $(@__MODULE__)=#, :((x, y)->begin
7878
x + y + 1
@@ -86,9 +86,9 @@ using RGFPrecompTest
8686

8787
# Test that RuntimeGeneratedFunction with identical body expressions (but
8888
# allocated separately) don't clobber each other when one is GC'd.
89-
f_gc = RuntimeGeneratedFunction(@__MODULE__, Base.remove_linenums!(:((x,y)->x+y+100001)))
89+
f_gc = @RuntimeGeneratedFunction(Base.remove_linenums!(:((x,y)->x+y+100001)))
9090
let
91-
RuntimeGeneratedFunction(@__MODULE__, Base.remove_linenums!(:((x,y)->x+y+100001)))
91+
@RuntimeGeneratedFunction(Base.remove_linenums!(:((x,y)->x+y+100001)))
9292
end
9393
GC.gc()
9494
@test f_gc(1,-1) == 100001
@@ -100,7 +100,7 @@ for k=1:4
100100
t = Threads.@spawn begin
101101
r = Bool[]
102102
for i=1:100
103-
f = RuntimeGeneratedFunction(@__MODULE__, Base.remove_linenums!(:((x,y)->x+y+$i*$k)))
103+
f = @RuntimeGeneratedFunction(Base.remove_linenums!(:((x,y)->x+y+$i*$k)))
104104
x = 1; y = 2;
105105
push!(r, f(x,y) == x + y + i*k)
106106
end
@@ -119,13 +119,13 @@ module GlobalsTest
119119
RuntimeGeneratedFunctions.init(@__MODULE__)
120120

121121
y = 40
122-
f = RuntimeGeneratedFunction(@__MODULE__, :(x->x+y))
122+
f = @RuntimeGeneratedFunction(:(x->x+y))
123123
end
124124

125125
@test GlobalsTest.f(2) == 42
126126

127127
@test_throws ErrorException @eval(module NotInitTest
128128
using RuntimeGeneratedFunctions
129129
# RuntimeGeneratedFunctions.init(@__MODULE__) # <-- missing
130-
f = RuntimeGeneratedFunction(@__MODULE__, :(x->x+y))
130+
f = @RuntimeGeneratedFunction(:(x->x+y))
131131
end)

0 commit comments

Comments
 (0)