Skip to content

Commit cee1c8a

Browse files
Merge pull request #20 from c42f/cjf/deprecate-macro-constructor
Use normal RuntimeGeneratedFunction constructor rather than macro
2 parents b1f9daa + ff1fd50 commit cee1c8a

File tree

3 files changed

+38
-42
lines changed

3 files changed

+38
-42
lines changed

src/RuntimeGeneratedFunctions.jl

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

33
using ExprTools, Serialization, SHA
44

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

77

88
"""
9-
RuntimeGeneratedFunction
9+
RuntimeGeneratedFunction(module, function_expression)
1010
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:
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:
3015
3116
* The result can be called immediately (immune to world age errors)
3217
* The result is not a named generic function, and doesn't participate in
@@ -41,21 +26,32 @@ RuntimeGeneratedFunctions.init(@__MODULE__) # Required at module top-level
4126
4227
function foo()
4328
expression = :((x,y)->x+y+1) # May be generated dynamically
44-
f = @RuntimeGeneratedFunction(expression)
29+
f = RuntimeGeneratedFunction(@__MODULE__, expression)
4530
f(1,2) # May be called immediately
4631
end
4732
```
4833
"""
49-
macro RuntimeGeneratedFunction(ex)
50-
quote
51-
if !($(esc(:(@isdefined($_tagname)))))
34+
struct RuntimeGeneratedFunction{argnames,moduletag,id} <: Function
35+
body::Expr
36+
function RuntimeGeneratedFunction(mod::Module, ex)
37+
if !isdefined(mod, _tagname)
5238
error("""You must use `RuntimeGeneratedFunctions.init(@__MODULE__)` at module
5339
top level before using runtime generated functions""")
5440
end
55-
RuntimeGeneratedFunction(
56-
$(esc(_tagname)),
57-
$(esc(ex))
58-
)
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)))
5955
end
6056
end
6157

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

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

7470
function generated_callfunc_body(argnames, moduletag, id, __args)
@@ -138,7 +134,7 @@ end
138134
RuntimeGeneratedFunctions.init(mod)
139135
140136
Use this at top level to set up your module `mod` before using
141-
`@RuntimeGeneratedFunction`.
137+
`RuntimeGeneratedFunction(mod, ...)`.
142138
"""
143139
function init(mod)
144140
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(:((x,y)->x+y))
5+
f = RuntimeGeneratedFunction(@__MODULE__, :((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(ex1)
31-
f2 = @RuntimeGeneratedFunction(ex2)
32-
f3 = @RuntimeGeneratedFunction(ex3)
30+
f1 = RuntimeGeneratedFunction(@__MODULE__, ex1)
31+
f2 = RuntimeGeneratedFunction(@__MODULE__, ex2)
32+
f3 = RuntimeGeneratedFunction(@__MODULE__, 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(ex)
65+
f1 = RuntimeGeneratedFunction(@__MODULE__, 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(Base.remove_linenums!(:((x,y)->x+y+1)))) ==
75+
@test sprint(show, RuntimeGeneratedFunction(@__MODULE__, 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(Base.remove_linenums!(:((x,y)->x+y+100001)))
89+
f_gc = RuntimeGeneratedFunction(@__MODULE__, Base.remove_linenums!(:((x,y)->x+y+100001)))
9090
let
91-
@RuntimeGeneratedFunction(Base.remove_linenums!(:((x,y)->x+y+100001)))
91+
RuntimeGeneratedFunction(@__MODULE__, 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(Base.remove_linenums!(:((x,y)->x+y+$i*$k)))
103+
f = RuntimeGeneratedFunction(@__MODULE__, 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(:(x->x+y))
122+
f = RuntimeGeneratedFunction(@__MODULE__, :(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(:(x->x+y))
130+
f = RuntimeGeneratedFunction(@__MODULE__, :(x->x+y))
131131
end)

0 commit comments

Comments
 (0)