@@ -2,29 +2,15 @@ module RuntimeGeneratedFunctions
2
2
3
3
using ExprTools, Serialization, SHA
4
4
5
- export @RuntimeGeneratedFunction
5
+ export RuntimeGeneratedFunction, @RuntimeGeneratedFunction
6
6
7
7
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
-
24
8
"""
25
9
@RuntimeGeneratedFunction(function_expression)
26
10
@RuntimeGeneratedFunction(context_module, function_expression)
27
11
12
+ RuntimeGeneratedFunction(cache_module, context_module, function_expression)
13
+
28
14
Construct a function from `function_expression` which can be called immediately
29
15
without world age problems. Somewhat like using `eval(function_expression)` and
30
16
then calling the resulting function. The differences are:
@@ -40,6 +26,11 @@ If provided, `context_module` is module in which symbols within
40
26
`function_expression` will be looked up. By default this is module in which
41
27
`@RuntimeGeneratedFunction` is expanded.
42
28
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
+
43
34
# Examples
44
35
```
45
36
RuntimeGeneratedFunctions.init(@__MODULE__) # Required at module top-level
@@ -51,28 +42,46 @@ function foo()
51
42
end
52
43
```
53
44
"""
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
59
54
end
60
55
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)
69
59
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 """ )
71
61
end
72
- RuntimeGeneratedFunction (cache_module.$ _tagname, context_module.$ _tagname, $ code)
73
62
end
74
63
end
75
64
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
+
76
85
function Base. show (io:: IO , :: MIME"text/plain" , f:: RuntimeGeneratedFunction{argnames, cache_tag, context_tag, id} ) where {argnames,cache_tag,context_tag,id}
77
86
cache_mod = parentmodule (cache_tag)
78
87
context_mod = parentmodule (context_tag)
0 commit comments