Skip to content

Commit

Permalink
Use jl_reinit_foreign_type if available
Browse files Browse the repository at this point in the history
This prepares us for an upcoming change to serialization in Julia 1.10.
  • Loading branch information
fingolfin committed Nov 28, 2022
1 parent 5ea730c commit ad3e631
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## Version 0.9.2-DEV (released YYYY-MM-DD)

- Silence scary warning about missing compiler
- Prepare for an upcoming change to serialization in Julia 1.10

## Version 0.9.1 (released 2022-11-23)

- Added a longer example for using GAP.jl, based around the Rubik's cube
Expand Down
2 changes: 1 addition & 1 deletion pkg/JuliaInterface/example/function_perform.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module GapFunctionPerform

import GAP_jll: GapObj
import GAP: GapObj

function typed_func(a::GapObj, b::GapObj)
return a
Expand Down
27 changes: 26 additions & 1 deletion src/GAP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ GAP_jll.is_available() ||
error("""This platform or julia version is currently not supported by GAP:
$(Base.BinaryPlatforms.host_triplet())""")

# Julia >= 1.10 will at some point add support for (de)serializing foreign
# types (the types, not the instances, at least not yet). We want (and need)
# to use that if available, which also requires changes in GAP resp. GAP_jll.
# To determine whether to use it, we therefore check two conditions:
# (1) whether the Julia kernel exports `jl_reinit_foreign_type`, and
# (2) whether or not GAP_jll defines GapObj.
# See https://github.com/JuliaLang/julia/pull/44527
# and https://github.com/JuliaLang/julia/pull/47407
function use_jl_reinit_foreign_type()
if isdefined(GAP_jll, :GapObj)
# GAP_jll still provides GapObj => use the old system
return false
end
# otherwise try to use the new system
try
cglobal(:jl_reinit_foreign_type) != C_NULL
catch
false
end
end

include("setup.jl")

import Base: length, finalize
Expand Down Expand Up @@ -75,6 +96,10 @@ const real_JuliaInterface_path = Ref{String}()
JuliaInterface_path() = real_JuliaInterface_path[]

function initialize(argv::Vector{String})
if use_jl_reinit_foreign_type()
ccall((:GAP_InitJuliaMemoryInterface, libgap), Nothing, (Any, Ptr{Nothing}), @__MODULE__, C_NULL)
end

handle_signals = isdefined(Main, :__GAP_ARGS__) # a bit of a hack...
error_handler_func = handle_signals ? C_NULL : @cfunction(error_handlerwrap, Cvoid, ())

Expand Down Expand Up @@ -112,7 +137,7 @@ function initialize(argv::Vector{String})
## At this point, the GAP module has not been completely initialized, and
## hence is not yet available under the global binding "GAP"; but
## JuliaInterface needs to access it. To make that possible, we dlopen
## its kernel extension already here, and poke a point to this module
## its kernel extension already here, and poke a pointer to this module
## into the kernel extension's global variable `gap_module`
@debug "storing pointer to Julia module 'GAP' into JuliaInterface"
Libdl.dlopen(JuliaInterface_path())
Expand Down
20 changes: 20 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
if use_jl_reinit_foreign_type()
const GapObj = ccall((:GAP_DeclareGapObj, libgap),
Any,
(Symbol, Module, Any),
:GapObj, GAP, Any)

const SmallBag = ccall((:GAP_DeclareBag, libgap),
Any,
(Symbol, Module, Any, Cint),
:SmallBag, GAP, Any, 0)

const LargeBag = ccall((:GAP_DeclareBag, libgap),
Any,
(Symbol, Module, Any, Cint),
:LargeBag, GAP, Any, 1)

else

import GAP_jll: GapObj

end


"""
FFE
Expand Down
6 changes: 5 additions & 1 deletion test/adapter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,9 @@ end

ioc = IOContext(io, :module => nothing);
print(ioc, GAP.GapObj)
@test String(take!(io)) == "GAP_jll.GapObj"
if GAP.use_jl_reinit_foreign_type()
@test String(take!(io)) == "GAP.GapObj"
else
@test String(take!(io)) == "GAP_jll.GapObj"
end
end

0 comments on commit ad3e631

Please sign in to comment.