diff --git a/M2/Macaulay2/d/ffi.d b/M2/Macaulay2/d/ffi.d index 65be1e85765..5987cd3d215 100644 --- a/M2/Macaulay2/d/ffi.d +++ b/M2/Macaulay2/d/ffi.d @@ -216,7 +216,9 @@ ffiIntegerType(e:Expr):Expr := ( if length(a) == 2 then ( when a.0 is n:ZZcell do ( - if isZero(n.v) + if !isInt(n) + then WrongArgSmallInteger(1) + else if isZero(n.v) then toExpr(Ccode(voidPointer, "&ffi_type_pointer")) else when a.1 is signed:Boolean do ( @@ -260,10 +262,15 @@ ffiIntegerAddress(e:Expr):Expr := ( is x:ZZcell do ( when a.1 is y:ZZcell do ( - if isZero(y.v) then ( - z := copy(x.v); + if !isInt(y) + then WrongArgSmallInteger(2) + else if isZero(y.v) then ( + z := newZZmutable(); + set(z, x.v); ptr := getMem(pointerSize); - Ccode(void, "*(mpz_srcptr *)", ptr, " = ", z); + Ccode(void, "*(mpz_ptr *)", ptr, " = ", z); + Ccode(void, "GC_REGISTER_FINALIZER(", ptr, ", ", + "(GC_finalization_proc)mpz_clear, ", z, ", 0, 0)"); toExpr(ptr)) else when a.2 is signed:Boolean do ( @@ -320,7 +327,9 @@ ffiIntegerValue(e:Expr):Expr := ( is x:pointerCell do ( when a.1 is y:ZZcell do ( - if isZero(y.v) + if !isInt(y) + then WrongArgSmallInteger(2) + else if isZero(y.v) then toExpr(moveToZZ(Ccode(ZZmutable, "*(mpz_ptr*)", x.v))) else when a.2 is signed:Boolean do ( @@ -363,6 +372,7 @@ setupfun("ffiIntegerValue", ffiIntegerValue); ffiRealType(e:Expr):Expr := ( when e is n:ZZcell do ( + if !isInt(n) then return WrongArgSmallInteger(); bits := toInt(n); if bits == 0 then toExpr(Ccode(voidPointer, "&ffi_type_pointer")) else if bits == 32 then toExpr(Ccode(voidPointer, "&ffi_type_float")) @@ -383,11 +393,17 @@ ffiRealAddress(e:Expr):Expr := ( is x:RRcell do ( when a.1 is y:ZZcell do ( + if !isInt(y) then return WrongArgSmallInteger(); bits := toInt(y); if bits == 0 then ( - z := copy(x.v); + z := newRRmutable(precision(x.v)); + Ccode(void, "mpfr_set(", z, ", ", x.v, ", MPFR_RNDN)"); ptr := getMem(pointerSize); - Ccode(void, "*(mpfr_srcptr *)", ptr, " = ", z); + Ccode(void, "*(mpfr_ptr *)", ptr, " = ", z); + -- TODO: we get segfaults during garbage collection + -- if the following is uncommented + -- Ccode(void, "GC_REGISTER_FINALIZER(", ptr, ", ", + -- "(GC_finalization_proc)mpfr_clear, ", z, ", 0, 0)"); toExpr(ptr)) else if bits == 32 || bits == 64 then ( ptr := getMemAtomic(bits / 8); @@ -419,6 +435,7 @@ ffiRealValue(e:Expr):Expr := ( is x:pointerCell do ( when a.1 is y:ZZcell do ( + if !isInt(y) then return WrongArgSmallInteger(); bits := toInt(y); if bits == 0 then toExpr(moveToRR(Ccode(RRmutable, "*(mpfr_ptr*)", x.v))) diff --git a/M2/Macaulay2/d/gmp.d b/M2/Macaulay2/d/gmp.d index d84c77fd29e..c6513041d8f 100644 --- a/M2/Macaulay2/d/gmp.d +++ b/M2/Macaulay2/d/gmp.d @@ -203,7 +203,7 @@ clear(x:RRimutable) ::= Ccode( void, "mpfi_clear(", x, ")" ); clear(z:CCmutable):void := ( clear(z.re); clear(z.im); ); -export copy(z:ZZ):ZZ := ( +export moveToZZ(z:ZZmutable):ZZ := ( y := GCmalloc(ZZmutable); Ccode(void, " int s = z->_mp_size, ss = s>=0 ? s : -s; @@ -212,14 +212,13 @@ export copy(z:ZZ):ZZ := ( ",y,"->_mp_alloc = ss, ",y,"->_mp_size = s, ",y,"->_mp_d = p; "); Ccode(ZZ,y)); -export moveToZZ(z:ZZmutable):ZZ := copy(Ccode(ZZ, z)); export moveToZZandclear(z:ZZmutable):ZZ := ( w := moveToZZ(z); clear(z); w); -export copy(z:RR):RR := ( +export moveToRR(z:RRmutable):RR := ( y := GCmalloc(RRmutable); Ccode(void, " int limb_size = (",z,"->_mpfr_prec - 1) / GMP_NUMB_BITS + 1; @@ -232,7 +231,6 @@ export copy(z:RR):RR := ( "); Ccode(RR,y) ); -export moveToRR(z:RRmutable):RR := copy(Ccode(RR, z)); export moveToRRi(z:RRimutable):RRi := ( y := GCmalloc(RRimutable);