From 82338661b3154df1f6d93d16db2dae10da3b6904 Mon Sep 17 00:00:00 2001 From: David Isinta Nyakawa <83705759+davidisinta@users.noreply.github.com> Date: Wed, 2 Apr 2025 01:28:08 -0400 Subject: [PATCH] Fix Issue 10523 - Enabled BigInt to work in CTFE (#10725) made biguint core ctfe valid by removing free keyword at compile time --- std/internal/math/biguintcore.d | 83 +++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/std/internal/math/biguintcore.d b/std/internal/math/biguintcore.d index 9c794b60d..b2c2b890e 100644 --- a/std/internal/math/biguintcore.d +++ b/std/internal/math/biguintcore.d @@ -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