From 8a8f79a45a15c3ba063add57e1d63eb7944d2287 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Tue, 13 Feb 2024 20:50:39 -0500 Subject: [PATCH 1/4] Check that "bits" args of ffi integer/real functions are ints --- M2/Macaulay2/d/ffi.d | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/M2/Macaulay2/d/ffi.d b/M2/Macaulay2/d/ffi.d index 65be1e85765..e83b21c5c4e 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,7 +262,9 @@ ffiIntegerAddress(e:Expr):Expr := ( is x:ZZcell do ( when a.1 is y:ZZcell do ( - if isZero(y.v) then ( + if !isInt(y) + then WrongArgSmallInteger(2) + else if isZero(y.v) then ( z := copy(x.v); ptr := getMem(pointerSize); Ccode(void, "*(mpz_srcptr *)", ptr, " = ", z); @@ -320,7 +324,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 +369,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,6 +390,7 @@ 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); @@ -419,6 +427,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))) From 56f525ddfe87d56b850917e12a2122597b15fa8f Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Tue, 13 Feb 2024 20:55:11 -0500 Subject: [PATCH 2/4] Restore previous behavior for allocating mpz_t's in ForeignFunctions Use GMP's own allocation functions rather than allocating memory using the garbage collector. This was causing crashes when calling GMP functions, especially with GMP < 6.2. Closes: #3128 --- M2/Macaulay2/d/ffi.d | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/M2/Macaulay2/d/ffi.d b/M2/Macaulay2/d/ffi.d index e83b21c5c4e..c16d89eeb0a 100644 --- a/M2/Macaulay2/d/ffi.d +++ b/M2/Macaulay2/d/ffi.d @@ -265,9 +265,12 @@ ffiIntegerAddress(e:Expr):Expr := ( if !isInt(y) then WrongArgSmallInteger(2) else if isZero(y.v) then ( - z := copy(x.v); + 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 ( From 9598c9d1a4ed2286d75a6da06e9a721db00d25fc Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Tue, 13 Feb 2024 21:08:32 -0500 Subject: [PATCH 3/4] Don't allocate mpfr_t memory using garbage collector --- M2/Macaulay2/d/ffi.d | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/M2/Macaulay2/d/ffi.d b/M2/Macaulay2/d/ffi.d index c16d89eeb0a..5987cd3d215 100644 --- a/M2/Macaulay2/d/ffi.d +++ b/M2/Macaulay2/d/ffi.d @@ -396,9 +396,14 @@ ffiRealAddress(e:Expr):Expr := ( 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); From d1a16988391d81a5a636639c6b8719e37e539dc1 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Tue, 13 Feb 2024 21:38:17 -0500 Subject: [PATCH 4/4] Remove now-unused copy(ZZ) and copy(RR) from gmp.d --- M2/Macaulay2/d/gmp.d | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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);