@@ -842,30 +842,32 @@ function report_text(text::AbstractString,
842
842
return JETToplevelResult (analyzer′, res, source; analyzer, jetconfigs... )
843
843
end
844
844
845
+ # we have to go on hacks; see `transform_abstract_global_symbols!` and `resolve_toplevel_symbols!`
845
846
function analyze_toplevel! (analyzer:: AbstractAnalyzer , src:: CodeInfo )
846
847
# construct toplevel `MethodInstance`
847
848
mi = ccall (:jl_new_method_instance_uninit , Ref{Core. MethodInstance}, ());
848
- mi. uninferred = src
849
849
mi. specTypes = Tuple{}
850
850
851
- transform_abstract_global_symbols! (analyzer, src)
852
- mi. def = get_toplevelmod (analyzer)
851
+ mi. def = mod = get_toplevelmod (analyzer)
852
+ src = transform_abstract_global_symbols! (analyzer, src)
853
+ src = resolve_toplevel_symbols! (mod, src)
854
+ mi. uninferred = src
853
855
854
856
result = InferenceResult (mi);
855
- # toplevel frame doesn 't need to be cached (and so it won't be optimized), nor should
856
- # go through JET's code generation error check
857
- frame = InferenceState (result, src, #= cached=# false , analyzer);
857
+ # toplevel frames don 't really need to be cached, but still better to be optimized
858
+ # in order to get reasonable `LocalUndefVarErrorReport` and `UncaughtExceptionReport`
859
+ frame = InferenceState (result, src, #= cached=# true , analyzer);
858
860
859
861
return analyze_frame! (analyzer, frame)
860
862
end
861
863
862
- # HACK this is an native hack to re-use `AbstractInterpreter`'s approximated slot types for
864
+ # HACK this is very naive hack to re-use `AbstractInterpreter`'s slot type approximation for
863
865
# assignments of abstract global variables, which are represented as toplevel symbols at this point;
864
- # the idea is just to transform them into slots from symbols and use their approximated type
865
- # on their assignment.
866
+ # the idea is just to transform them into slot from symbol and use their approximated type
867
+ # on their assignment (see `finish(::InferenceState, ::AbstractAnalyzer)`) .
866
868
# NOTE that `transform_abstract_global_symbols!` will produce really invalid code for
867
869
# actual interpretation or execution, but all the statements won't be interpreted anymore
868
- # by `ConcreteInterpreter` nor executed anyway since toplevel frames aren't cached
870
+ # by `ConcreteInterpreter` nor executed by the native compilation pipeline anyway
869
871
function transform_abstract_global_symbols! (analyzer:: AbstractAnalyzer , src:: CodeInfo )
870
872
nslots = length (src. slotnames)
871
873
abstrct_global_variables = Dict {Symbol,Int} ()
@@ -901,6 +903,41 @@ function transform_abstract_global_symbols!(analyzer::AbstractAnalyzer, src::Cod
901
903
end
902
904
903
905
set_global_slots! (analyzer, Dict (idx => slotname for (slotname, idx) in abstrct_global_variables))
906
+
907
+ return src
908
+ end
909
+
910
+ # resolve toplevel symbols (and other expressions like `:foreigncall`)
911
+ # so that the returned `CodeInfo` is eligible for abstractintepret and optimization
912
+ # TODO `jl_resolve_globals_in_ir` can throw, and we want to bypass it to `ToplevelErrorReport`
913
+ @static if VERSION ≥ v " 1.8.0-DEV.421"
914
+ function resolve_toplevel_symbols! (mod:: Module , src:: CodeInfo )
915
+ newsrc = copy (src)
916
+ @ccall jl_resolve_globals_in_ir (
917
+ #= jl_array_t *stmts=# newsrc. code:: Any ,
918
+ #= jl_module_t *m=# mod:: Any ,
919
+ #= jl_svec_t *sparam_vals=# svec ():: Any ,
920
+ #= int binding_effects=# 0 :: Int ):: Cvoid
921
+ return newsrc
922
+ end
923
+ else
924
+ # HACK before https://github.com/JuliaLang/julia/pull/42013, we need to go through
925
+ # the method definition pipeline to get the effect of `jl_resolve_globals_in_ir`
926
+ function resolve_toplevel_symbols! (mod:: Module , src:: CodeInfo )
927
+ sig = svec (
928
+ #= atypes=# svec (typeof (__toplevelf__)),
929
+ #= tvars=# svec (),
930
+ #= functionloc=# LineNumberNode (@__LINE__ , @__FILE__ ))
931
+ # branching on https://github.com/JuliaLang/julia/pull/41137
932
+ method = (@static if isdefined (Core. Compiler, :OverlayMethodTable )
933
+ ccall (:jl_method_def , Any, (Any, Ptr{Cvoid}, Any, Any), sig, C_NULL , src, mod)
934
+ else
935
+ ccall (:jl_method_def , Cvoid, (Any, Any, Any), sig, src, mod)
936
+ only (methods (__toplevelf__))
937
+ end ):: Method
938
+ return CC. uncompressed_ir (method)
939
+ end
940
+ function __toplevelf__ end
904
941
end
905
942
906
943
# TODO `analyze_builtin!` ?
0 commit comments