@@ -2,31 +2,16 @@ module RuntimeGeneratedFunctions
22
33using 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
4227function 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
4631end
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
6056end
6157
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
7268function generated_callfunc end
7369
7470function generated_callfunc_body (argnames, moduletag, id, __args)
138134 RuntimeGeneratedFunctions.init(mod)
139135
140136Use this at top level to set up your module `mod` before using
141- `@ RuntimeGeneratedFunction`.
137+ `RuntimeGeneratedFunction(mod, ...) `.
142138"""
143139function init (mod)
144140 lock (_cache_lock) do
0 commit comments