@@ -2,16 +2,31 @@ module RuntimeGeneratedFunctions
22
33using 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
2742function 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
3146end
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
5660end
5761
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
6872function generated_callfunc end
6973
7074function generated_callfunc_body (argnames, moduletag, id, __args)
134138 RuntimeGeneratedFunctions.init(mod)
135139
136140Use this at top level to set up your module `mod` before using
137- `RuntimeGeneratedFunction(mod, ...) `.
141+ `@ RuntimeGeneratedFunction`.
138142"""
139143function init (mod)
140144 lock (_cache_lock) do
0 commit comments