Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change the way we do Int64 conversion to/from GAP #357

Merged
merged 1 commit into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/GAPJulia/JuliaInterface/gap/convert.gd
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
#! <List>
#! <Item>
#! <C>Int64</C> to immediate integer when it fits,
#! otherwise to &Julia; object wrapper,
#! otherwise to a &GAP; large integer,
#! </Item>
#! <Item>
#! <C>GapFFE</C> to immediate FFE,
Expand Down
2 changes: 1 addition & 1 deletion pkg/GAPJulia/JuliaInterface/src/convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Obj gap_julia(jl_value_t * julia_obj)
if (INT_INTOBJ_MIN <= v && v <= INT_INTOBJ_MAX) {
return INTOBJ_INT(v);
}
return NewJuliaObj(julia_obj);
return ObjInt_Int8(v);
}
if (is_gapobj(julia_obj)) {
return (Obj)julia_obj;
Expand Down
8 changes: 0 additions & 8 deletions src/ccalls.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,6 @@ function NewPlist(length :: Int64)
return o
end

function MakeObjInt(x::BigInt)
o = ccall( :MakeObjInt,
Ptr{Cvoid},
(Ptr{UInt64},Cint),
x.d, x.size )
return RAW_GAP_TO_JULIA( o )
end

function NEW_MACFLOAT(x::Float64)
o = ccall( :NEW_MACFLOAT,
Any,
Expand Down
38 changes: 25 additions & 13 deletions src/julia_to_gap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,40 @@ of input data, by converting egal data to identical objects in GAP.
"""


## Default
## Default for actual GAP objects is to do nothing
julia_to_gap(x::GapObj) = x
julia_to_gap(x::FFE) = x
julia_to_gap(x::Bool) = x

## Integers: general case first deal with things that fit into immediate
## integers, then falls back to converting to BigInt and calling into the GAP
## kernel API.
## TODO: we could provide more efficient conversion for UInt64, Int128, UInt128
## which avoids the conversion to BigInt, if we wanted to.
function julia_to_gap(x::Integer)
# if it fits into a GAP immediate integer, convert x to Int64
if x in -1<<60:(1<<60-1)
return Int64(x)
end
# for the general case, fall back to BigInt
return julia_to_gap(BigInt(x))
end

## Integers
julia_to_gap(x::Int128) = MakeObjInt(BigInt(x)) # FIXME: inefficient hack
## Small integers types always fit into GAP immediate integers, and thus are
## represented by Int64 on the Julia side.
julia_to_gap(x::Int64) = x
julia_to_gap(x::Int32) = Int64(x)
julia_to_gap(x::Int16) = Int64(x)
julia_to_gap(x::Int8) = Int64(x)

## Unsigned Integers
julia_to_gap(x::UInt128) = MakeObjInt(BigInt(x)) # FIXME: inefficient hack
julia_to_gap(x::UInt64) = MakeObjInt(BigInt(x)) # FIXME: inefficient hack
julia_to_gap(x::UInt32) = Int64(x)
julia_to_gap(x::UInt16) = Int64(x)
julia_to_gap(x::UInt8) = Int64(x)

## BigInts
julia_to_gap(x::BigInt) = MakeObjInt(x)
julia_to_gap(x::UInt32) = Int64(x)
julia_to_gap(x::UInt16) = Int64(x)
julia_to_gap(x::UInt8) = Int64(x)

## BigInts are converted via a ccall
function julia_to_gap(x::BigInt)
o = ccall(:MakeObjInt, Ptr{Cvoid}, (Ptr{UInt64},Cint), x.d, x.size)
return RAW_GAP_TO_JULIA(o)
end

## Rationals
function julia_to_gap(x::Rational{T}) where T <: Integer
Expand Down
2 changes: 1 addition & 1 deletion test/basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ end
# passed and then extracted again
@test f( (1,2,3) )[1] == (1,2,3)

@test GAP.Globals.IdFunc(2^62) isa Int64
@test !(GAP.Globals.IdFunc(2^62) isa Int64)

x = GAP.Globals.Indeterminate(GAP.Globals.Rationals)
f = x^4+1
Expand Down
15 changes: 15 additions & 0 deletions test/conversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,21 @@ end
@test GAP.julia_to_gap(Int16(1)) == 1
@test GAP.julia_to_gap(Int8(1)) == 1

## Int64 corner cases
@test GAP.julia_to_gap(-2^60 ) === -2^60
@test GAP.julia_to_gap( 2^60-1) === 2^60 - 1

@test GAP.Globals.IsInt(GAP.julia_to_gap(-2^60-1))
@test GAP.Globals.IsInt(GAP.julia_to_gap( 2^60))

@test GAP.Globals.IsInt(GAP.julia_to_gap(-2^63-1))
@test GAP.Globals.IsInt(GAP.julia_to_gap(-2^63))
@test GAP.Globals.IsInt(GAP.julia_to_gap( 2^63-1))
@test GAP.Globals.IsInt(GAP.julia_to_gap( 2^63))

# see issue https://github.com/oscar-system/GAP.jl/issues/332
@test 2^60 * GAP.Globals.Factorial(20) == GAP.EvalString("2^60 * Factorial(20)")

## Unsigned integers
@test GAP.julia_to_gap(UInt128(1)) == 1
@test GAP.julia_to_gap(UInt64(1)) == 1
Expand Down