672672 CompilationPolicyExtern = 1
673673end
674674
675+ const AL_N_INLINE = 29
676+ # mirrows arraylist_t
677+ mutable struct ArrayList
678+ len:: Csize_t
679+ max:: Csize_t
680+ items:: Ptr{Ptr{Cvoid}}
681+ _space:: NTuple{AL_N_INLINE, Ptr{Cvoid}}
682+
683+ function ArrayList ()
684+ list = new (0 , AL_N_INLINE, Ptr {Ptr{Cvoid}} (C_NULL ), ntuple (_-> Ptr {Cvoid} (C_NULL ), AL_N_INLINE))
685+ list. items = Base. pointer_from_objref (list) + fieldoffset (typeof (list), 4 )
686+
687+ finalizer (list) do list
688+ if list. items != Base. pointer_from_objref (list) + fieldoffset (typeof (list), 4 )
689+ Libc. free (list. items)
690+ end
691+ end
692+ return list
693+ end
694+ end
695+
696+
675697"""
676698 precompile(job::CompilerJob)
677699
@@ -787,16 +809,17 @@ function compile_method_instance(@nospecialize(job::CompilerJob))
787809 end
788810
789811 gv_to_value = Dict {String, Any} ()
790- num_gvars = Ref {Csize_t} (0 )
791- @ccall jl_get_llvm_gvs (native_code:: Ptr{Cvoid} , num_gvars:: Ptr{Csize_t} ,
792- C_NULL :: Ptr{Cvoid} ):: Nothing
793- gvs = Vector {Ptr{LLVM.API.LLVMOpaqueValue}} (undef, num_gvars[])
794- @ccall jl_get_llvm_gvs (native_code:: Ptr{Cvoid} , num_gvars:: Ptr{Csize_t} ,
795- gvs:: Ptr{LLVM.API.LLVMOpaqueValue} ):: Nothing
796812
797813 if VERSION >= v " 1.13.0-DEV.623"
798814 # Since Julia 1.13, the caller is responsible for initializing global variables that
799815 # point to global values or bindings with their address in memory.
816+ num_gvars = Ref {Csize_t} (0 )
817+ @ccall jl_get_llvm_gvs (native_code:: Ptr{Cvoid} , num_gvars:: Ptr{Csize_t} ,
818+ C_NULL :: Ptr{Cvoid} ):: Nothing
819+ gvs = Vector {Ptr{LLVM.API.LLVMOpaqueValue}} (undef, num_gvars[])
820+ @ccall jl_get_llvm_gvs (native_code:: Ptr{Cvoid} , num_gvars:: Ptr{Csize_t} ,
821+ gvs:: Ptr{LLVM.API.LLVMOpaqueValue} ):: Nothing
822+
800823 inits = Vector {Ptr{Cvoid}} (undef, num_gvars[])
801824 @ccall jl_get_llvm_gv_inits (native_code:: Ptr{Cvoid} , num_gvars:: Ptr{Csize_t} ,
802825 inits:: Ptr{Cvoid} ):: Nothing
@@ -807,15 +830,50 @@ function compile_method_instance(@nospecialize(job::CompilerJob))
807830 initializer! (gv, val)
808831
809832 # TODO : jl_binding_t?
833+ @show LLVM. name (gv), val
810834 gv_to_value[LLVM. name (gv)] = Base. unsafe_pointer_to_objref (val)
811835 end
812836 else
813- for gv_ref in gvs
814- gv = GlobalVariable (gv_ref)
815- val = reinterpret (Ptr{Cvoid}, initializer (gv))
816- # TODO : jl_binding_t?
817- gv_to_value[LLVM. name (gv)] = Base. unsafe_pointer_to_objref (val)
837+ # Prior to this version of Julia we only had access to the values that the global variables
838+ # were initialized with, so we have to match them up manually.
839+ # get the global values
840+ if VERSION >= v " 1.12.0-DEV.1703"
841+ num_gvars = Ref {Csize_t} (0 )
842+ @ccall jl_get_llvm_gvs (native_code:: Ptr{Cvoid} , num_gvars:: Ptr{Csize_t} ,
843+ C_NULL :: Ptr{Cvoid} ):: Nothing
844+ gvalues = Vector {Ptr{Cvoid}} (undef, num_gvars[])
845+ @ccall jl_get_llvm_gvs (native_code:: Ptr{Cvoid} , num_gvars:: Ptr{Csize_t} ,
846+ gvalues:: Ptr{Cvoid} ):: Nothing
847+ else
848+ # Sigh on older version of Julia we have to use `arraylist_t` which doesn't have a Julia API.
849+ gvars = ArrayList ()
850+ GC. @preserve gvars begin
851+ p_gvars = Base. pointer_from_objref (gvars)
852+ @ccall jl_get_llvm_gvs (native_code:: Ptr{Cvoid} , p_gvars:: Ptr{Cvoid} ):: Nothing
853+ gvalues = Vector {Ptr{Cvoid}} (undef, gvars. len)
854+ for i in 1 : gvars. len
855+ gvalues[i] = unsafe_load (gvars. items, i)
856+ end
857+ end
858+ end
859+ gvalues = Set (gvalues)
860+ for gv in globals (llvm_mod)
861+ init = LLVM. initializer (gv)
862+ if init === nothing
863+ continue
864+ end
865+ if init isa LLVM. ConstantExpr && opcode (init) == LLVM. API. LLVMIntToPtr
866+ init = operands (init)[1 ]
867+ end
868+ if ! (init isa LLVM. ConstantInt)
869+ continue
870+ end
871+ ptr = reinterpret (Ptr{Cvoid}, convert (UInt, init))
872+ if ptr in gvalues
873+ gv_to_value[LLVM. name (gv)] = Base. unsafe_pointer_to_objref (ptr)
874+ end
818875 end
876+ @assert length (gv_to_value) == length (gvalues)
819877 end
820878
821879 if VERSION >= v " 1.13.0-DEV.1120"
0 commit comments