@@ -2,29 +2,15 @@ module RuntimeGeneratedFunctions
22
33using ExprTools, Serialization, SHA
44
5- export @RuntimeGeneratedFunction
5+ export RuntimeGeneratedFunction, @RuntimeGeneratedFunction
66
77
8- """
9- RuntimeGeneratedFunction
10-
11- This type should be constructed via the macro @RuntimeGeneratedFunction.
12- """
13- struct RuntimeGeneratedFunction{argnames, cache_tag, context_tag, id} <: Function
14- body:: Expr
15- function RuntimeGeneratedFunction (cache_tag, context_tag, 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 (cache_tag, id, body)
20- new {Tuple(args), cache_tag, context_tag, id} (cached_body)
21- end
22- end
23-
248"""
259 @RuntimeGeneratedFunction(function_expression)
2610 @RuntimeGeneratedFunction(context_module, function_expression)
2711
12+ RuntimeGeneratedFunction(cache_module, context_module, function_expression)
13+
2814Construct a function from `function_expression` which can be called immediately
2915without world age problems. Somewhat like using `eval(function_expression)` and
3016then calling the resulting function. The differences are:
@@ -40,6 +26,11 @@ If provided, `context_module` is module in which symbols within
4026`function_expression` will be looked up. By default this is module in which
4127`@RuntimeGeneratedFunction` is expanded.
4228
29+ `cache_module` is the module where the expression `code` will be cached. If
30+ `RuntimeGeneratedFunction` is used during precompilation, this must be a module
31+ which is currently being precompiled. Normally this would be set to
32+ `@__MODULE__` using one of the macro constructors.
33+
4334# Examples
4435```
4536RuntimeGeneratedFunctions.init(@__MODULE__) # Required at module top-level
@@ -51,28 +42,46 @@ function foo()
5142end
5243```
5344"""
54- macro RuntimeGeneratedFunction (code)
55- _RGF_constructor_code (:(@__MODULE__ ), esc (code))
56- end
57- macro RuntimeGeneratedFunction (context_module, code)
58- _RGF_constructor_code (esc (context_module), esc (code))
45+ struct RuntimeGeneratedFunction{argnames, cache_tag, context_tag, id} <: Function
46+ body:: Expr
47+ function RuntimeGeneratedFunction (cache_tag, context_tag, ex)
48+ def = splitdef (ex)
49+ args, body = normalize_args (def[:args ]), def[:body ]
50+ id = expr_to_id (body)
51+ cached_body = _cache_body (cache_tag, id, body)
52+ new {Tuple(args), cache_tag, context_tag, id} (cached_body)
53+ end
5954end
6055
61- function _RGF_constructor_code (context_module, code)
62- quote
63- code = $ code
64- cache_module = @__MODULE__
65- context_module = $ context_module
66- if #= =# ! isdefined (cache_module, $ (QuoteNode (_tagname))) ||
67- ! isdefined (context_module, $ (QuoteNode (_tagname)))
68- init_mods = unique ([context_module, cache_module])
56+ function _check_rgf_initialized (mods... )
57+ for mod in mods
58+ if ! isdefined (mod, _tagname)
6959 error (""" You must use `RuntimeGeneratedFunctions.init(@__MODULE__)` at module
70- top level before using runtime generated functions in $init_mods """ )
60+ top level before using runtime generated functions in $mod """ )
7161 end
72- RuntimeGeneratedFunction (cache_module.$ _tagname, context_module.$ _tagname, $ code)
7362 end
7463end
7564
65+ function RuntimeGeneratedFunction (cache_module:: Module , context_module:: Module , code)
66+ _check_rgf_initialized (cache_module, context_module)
67+ RuntimeGeneratedFunction (getfield (cache_module, _tagname),
68+ getfield (context_module, _tagname), code)
69+ end
70+
71+ macro RuntimeGeneratedFunction (code)
72+ quote
73+ RuntimeGeneratedFunction (@__MODULE__ , @__MODULE__ , $ (esc (code)))
74+ end
75+ end
76+ macro RuntimeGeneratedFunction (context_module, code)
77+ quote
78+ RuntimeGeneratedFunction (@__MODULE__ , $ (esc (context_module)), $ (esc (code)))
79+ end
80+ end
81+
82+ # Duplicate RuntimeGeneratedFunction docs onto @RuntimeGeneratedFunction
83+ @eval @doc $ (@doc RuntimeGeneratedFunction) var"@RuntimeGeneratedFunction"
84+
7685function Base. show (io:: IO , :: MIME"text/plain" , f:: RuntimeGeneratedFunction{argnames, cache_tag, context_tag, id} ) where {argnames,cache_tag,context_tag,id}
7786 cache_mod = parentmodule (cache_tag)
7887 context_mod = parentmodule (context_tag)
0 commit comments