Fix Issue 10523 - Enabled BigInt to work in CTFE (#10725)

made biguint core ctfe valid by removing free keyword at compile time
This commit is contained in:
David Isinta Nyakawa 2025-04-02 01:28:08 -04:00 committed by GitHub
parent a86eaca27b
commit 82338661b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -940,7 +940,11 @@ public:
uint [] wasteful = new BigDigit[x.data.length];
wasteful[] = x.data[];
immutable rem = multibyteDivAssign(wasteful, y, 0);
() @trusted { GC.free(wasteful.ptr); } ();
if (!__ctfe)
{
//use free only at runtime
() @trusted { GC.free(wasteful.ptr); } ();
}
return rem;
}
}
@ -1279,6 +1283,13 @@ pure @safe unittest
assert(s == 5);
}
pure @safe unittest
{ //evaluate mod at compile time
enum BigUint r = BigUint([5]);
enum BigUint t = BigUint([7]);
enum BigUint s = BigUint.mod(r, t);
static assert(s == 5);
}
@safe pure unittest
{
@ -1725,7 +1736,11 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
mulKaratsuba(result[half .. $], y, x[half .. $], scratchbuff);
BigDigit c = addAssignSimple(result[half .. half + y.length], partial);
if (c) multibyteIncrementAssign!('+')(result[half + y.length..$], c);
() @trusted { GC.free(scratchbuff.ptr); } ();
if (!__ctfe)
{
//use free only at runtime
() @trusted { GC.free(scratchbuff.ptr); } ();
}
}
else
{
@ -1784,7 +1799,11 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
addAssignSimple(result[done .. done + y.length + chunksize], partial);
done += chunksize;
}
() @trusted { GC.free(scratchbuff.ptr); } ();
if (!__ctfe)
{
//use free only at runtime
() @trusted { GC.free(scratchbuff.ptr); } ();
}
}
}
else
@ -1792,7 +1811,11 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
// Balanced. Use Karatsuba directly.
BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
mulKaratsuba(result, x, y, scratchbuff);
() @trusted { GC.free(scratchbuff.ptr); } ();
if (!__ctfe)
{
//use free only at runtime
() @trusted { GC.free(scratchbuff.ptr); } ();
}
}
}
@ -1828,24 +1851,28 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
*/
void squareInternal(BigDigit[] result, const BigDigit[] x) pure nothrow @safe
{
import core.memory : GC;
// Squaring is potentially half a multiply, plus add the squares of
// the diagonal elements.
assert(result.length == 2*x.length,
"result needs to have twice the capacity of x");
if (x.length <= KARATSUBASQUARELIMIT)
{
if (x.length == 1)
{
result[1] = multibyteMul(result[0 .. 1], x, x[0], 0);
return;
}
return squareSimple(result, x);
}
// The nice thing about squaring is that it always stays balanced
BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
squareKaratsuba(result, x, scratchbuff);
() @trusted { GC.free(scratchbuff.ptr); } ();
import core.memory : GC;
// Squaring is potentially half a multiply, plus add the squares of
// the diagonal elements.
assert(result.length == 2*x.length,
"result needs to have twice the capacity of x");
if (x.length <= KARATSUBASQUARELIMIT)
{
if (x.length == 1)
{
result[1] = multibyteMul(result[0 .. 1], x, x[0], 0);
return;
}
return squareSimple(result, x);
}
// The nice thing about squaring is that it always stays balanced
BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
squareKaratsuba(result, x, scratchbuff);
if (!__ctfe)
{
//use free only at runtime
() @trusted { GC.free(scratchbuff.ptr); } ();
}
}
@ -1897,7 +1924,11 @@ void divModInternal(BigDigit [] quotient, BigDigit[] remainder, const BigDigit [
if (s == 0) remainder[] = un[0 .. vn.length];
else multibyteShr(remainder, un[0 .. vn.length+1], s);
}
() @trusted { GC.free(un.ptr); GC.free(vn.ptr); } ();
if (!__ctfe)
{
//use free only at runtime
() @trusted { GC.free(un.ptr); GC.free(vn.ptr); } ();
}
}
pure @safe unittest
@ -2842,7 +2873,11 @@ pure nothrow @safe
m -= v.length;
}
recursiveDivMod(quotient[0 .. m], u[0 .. m + v.length], v, scratch);
() @trusted { GC.free(scratch.ptr); } ();
if (!__ctfe)
{
//use free only at runtime
() @trusted { GC.free(scratch.ptr); } ();
}
}
@system unittest