1
1
# This file provides an adaptor to match the API expected by the Julia runtime
2
2
# code in the binding Core._parse
3
3
4
- function _set_core_parse_hook (parser)
5
- # HACK! Fool the runtime into allowing us to set Core._parse, even during
6
- # incremental compilation. (Ideally we'd just arrange for Core._parse to be
7
- # set to the JuliaSyntax parser. But how do we signal that to the dumping
8
- # code outside of the initial creation of Core?)
9
- i = findfirst (== (:incremental ), fieldnames (Base. JLOptions))
10
- ptr = convert (Ptr{fieldtype (Base. JLOptions, i)},
11
- cglobal (:jl_options , Base. JLOptions) + fieldoffset (Base. JLOptions, i))
12
- incremental = unsafe_load (ptr)
13
- if incremental != 0
14
- unsafe_store! (ptr, 0 )
15
- end
4
+ if isdefined (Core, :set_parser )
5
+ const _set_core_parse_hook = Core. set_parser
6
+ else
7
+ function _set_core_parse_hook (parser)
8
+ # HACK! Fool the runtime into allowing us to set Core._parse, even during
9
+ # incremental compilation. (Ideally we'd just arrange for Core._parse to be
10
+ # set to the JuliaSyntax parser. But how do we signal that to the dumping
11
+ # code outside of the initial creation of Core?)
12
+ i = findfirst (== (:incremental ), fieldnames (Base. JLOptions))
13
+ ptr = convert (Ptr{fieldtype (Base. JLOptions, i)},
14
+ cglobal (:jl_options , Base. JLOptions) + fieldoffset (Base. JLOptions, i))
15
+ incremental = unsafe_load (ptr)
16
+ if incremental != 0
17
+ unsafe_store! (ptr, 0 )
18
+ end
16
19
17
- Base. eval (Core, :(_parse = $ parser))
20
+ Base. eval (Core, :(_parse = $ parser))
18
21
19
- if incremental != 0
20
- unsafe_store! (ptr, incremental)
22
+ if incremental != 0
23
+ unsafe_store! (ptr, incremental)
24
+ end
21
25
end
22
26
end
23
27
24
28
# Use caller's world age.
25
- const _caller_world = typemax (UInt)
26
- const _parser_world_age = Ref {UInt} (_caller_world )
29
+ const _latest_world = typemax (UInt)
30
+ const _parser_world_age = Ref {UInt} (_latest_world )
27
31
28
32
function core_parser_hook (code, filename, lineno, offset, options)
29
- # `hook` is always _core_parser_hook, but that's hidden from the compiler
30
- # via a Ref to prevent invalidation / recompilation when other packages are
31
- # loaded. This wouldn't seem like it should be necessary given the use of
32
- # invoke_in_world, but it is in Julia-1.7.3. I'm not sure exactly which
33
- # latency it's removing.
34
- hook = _core_parser_hook_ref[]
35
- if _parser_world_age[] != _caller_world
36
- Base. invoke_in_world (_parser_world_age[], hook,
33
+ # NB: We need an inference barrier of one type or another here to prevent
34
+ # invalidations. The invokes provide this currently.
35
+ if _parser_world_age[] != _latest_world
36
+ Base. invoke_in_world (_parser_world_age[], _core_parser_hook,
37
37
code, filename, lineno, offset, options)
38
38
else
39
- hook ( code, filename, lineno, offset, options)
39
+ Base . invokelatest (_core_parser_hook, code, filename, lineno, offset, options)
40
40
end
41
41
end
42
42
146
146
Base. Meta. ParseError (e:: JuliaSyntax.ParseError ) = e
147
147
148
148
const _default_parser = Core. _parse
149
- # NB: Never reassigned, but the compiler doesn't know this!
150
- const _core_parser_hook_ref = Ref {Function} (_core_parser_hook)
151
149
152
150
"""
153
151
enable_in_core!([enable=true; freeze_world_age, debug_filename])
@@ -165,7 +163,7 @@ Keyword arguments:
165
163
"""
166
164
function enable_in_core! (enable= true ; freeze_world_age = true ,
167
165
debug_filename = get (ENV , " JULIA_SYNTAX_DEBUG_FILE" , nothing ))
168
- _parser_world_age[] = freeze_world_age ? Base. get_world_counter () : _caller_world
166
+ _parser_world_age[] = freeze_world_age ? Base. get_world_counter () : _latest_world
169
167
if enable && ! isnothing (debug_filename)
170
168
_debug_log[] = open (debug_filename, " w" )
171
169
elseif ! enable && ! isnothing (_debug_log[])
0 commit comments