Skip to content

Commit 8233866

Browse files
authored
Fix Issue 10523 - Enabled BigInt to work in CTFE (#10725)
made biguint core ctfe valid by removing free keyword at compile time
1 parent a86eaca commit 8233866

File tree

1 file changed

+59
-24
lines changed

1 file changed

+59
-24
lines changed

std/internal/math/biguintcore.d

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,11 @@ public:
940940
uint [] wasteful = new BigDigit[x.data.length];
941941
wasteful[] = x.data[];
942942
immutable rem = multibyteDivAssign(wasteful, y, 0);
943-
() @trusted { GC.free(wasteful.ptr); } ();
943+
if (!__ctfe)
944+
{
945+
//use free only at runtime
946+
() @trusted { GC.free(wasteful.ptr); } ();
947+
}
944948
return rem;
945949
}
946950
}
@@ -1279,6 +1283,13 @@ pure @safe unittest
12791283
assert(s == 5);
12801284
}
12811285

1286+
pure @safe unittest
1287+
{ //evaluate mod at compile time
1288+
enum BigUint r = BigUint([5]);
1289+
enum BigUint t = BigUint([7]);
1290+
enum BigUint s = BigUint.mod(r, t);
1291+
static assert(s == 5);
1292+
}
12821293

12831294
@safe pure unittest
12841295
{
@@ -1725,7 +1736,11 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
17251736
mulKaratsuba(result[half .. $], y, x[half .. $], scratchbuff);
17261737
BigDigit c = addAssignSimple(result[half .. half + y.length], partial);
17271738
if (c) multibyteIncrementAssign!('+')(result[half + y.length..$], c);
1728-
() @trusted { GC.free(scratchbuff.ptr); } ();
1739+
if (!__ctfe)
1740+
{
1741+
//use free only at runtime
1742+
() @trusted { GC.free(scratchbuff.ptr); } ();
1743+
}
17291744
}
17301745
else
17311746
{
@@ -1784,15 +1799,23 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
17841799
addAssignSimple(result[done .. done + y.length + chunksize], partial);
17851800
done += chunksize;
17861801
}
1787-
() @trusted { GC.free(scratchbuff.ptr); } ();
1802+
if (!__ctfe)
1803+
{
1804+
//use free only at runtime
1805+
() @trusted { GC.free(scratchbuff.ptr); } ();
1806+
}
17881807
}
17891808
}
17901809
else
17911810
{
17921811
// Balanced. Use Karatsuba directly.
17931812
BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
17941813
mulKaratsuba(result, x, y, scratchbuff);
1795-
() @trusted { GC.free(scratchbuff.ptr); } ();
1814+
if (!__ctfe)
1815+
{
1816+
//use free only at runtime
1817+
() @trusted { GC.free(scratchbuff.ptr); } ();
1818+
}
17961819
}
17971820
}
17981821

@@ -1828,24 +1851,28 @@ void mulInternal(BigDigit[] result, const(BigDigit)[] x, const(BigDigit)[] y)
18281851
*/
18291852
void squareInternal(BigDigit[] result, const BigDigit[] x) pure nothrow @safe
18301853
{
1831-
import core.memory : GC;
1832-
// Squaring is potentially half a multiply, plus add the squares of
1833-
// the diagonal elements.
1834-
assert(result.length == 2*x.length,
1835-
"result needs to have twice the capacity of x");
1836-
if (x.length <= KARATSUBASQUARELIMIT)
1837-
{
1838-
if (x.length == 1)
1839-
{
1840-
result[1] = multibyteMul(result[0 .. 1], x, x[0], 0);
1841-
return;
1842-
}
1843-
return squareSimple(result, x);
1844-
}
1845-
// The nice thing about squaring is that it always stays balanced
1846-
BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
1847-
squareKaratsuba(result, x, scratchbuff);
1848-
() @trusted { GC.free(scratchbuff.ptr); } ();
1854+
import core.memory : GC;
1855+
// Squaring is potentially half a multiply, plus add the squares of
1856+
// the diagonal elements.
1857+
assert(result.length == 2*x.length,
1858+
"result needs to have twice the capacity of x");
1859+
if (x.length <= KARATSUBASQUARELIMIT)
1860+
{
1861+
if (x.length == 1)
1862+
{
1863+
result[1] = multibyteMul(result[0 .. 1], x, x[0], 0);
1864+
return;
1865+
}
1866+
return squareSimple(result, x);
1867+
}
1868+
// The nice thing about squaring is that it always stays balanced
1869+
BigDigit [] scratchbuff = new BigDigit[karatsubaRequiredBuffSize(x.length)];
1870+
squareKaratsuba(result, x, scratchbuff);
1871+
if (!__ctfe)
1872+
{
1873+
//use free only at runtime
1874+
() @trusted { GC.free(scratchbuff.ptr); } ();
1875+
}
18491876
}
18501877

18511878

@@ -1897,7 +1924,11 @@ void divModInternal(BigDigit [] quotient, BigDigit[] remainder, const BigDigit [
18971924
if (s == 0) remainder[] = un[0 .. vn.length];
18981925
else multibyteShr(remainder, un[0 .. vn.length+1], s);
18991926
}
1900-
() @trusted { GC.free(un.ptr); GC.free(vn.ptr); } ();
1927+
if (!__ctfe)
1928+
{
1929+
//use free only at runtime
1930+
() @trusted { GC.free(un.ptr); GC.free(vn.ptr); } ();
1931+
}
19011932
}
19021933

19031934
pure @safe unittest
@@ -2842,7 +2873,11 @@ pure nothrow @safe
28422873
m -= v.length;
28432874
}
28442875
recursiveDivMod(quotient[0 .. m], u[0 .. m + v.length], v, scratch);
2845-
() @trusted { GC.free(scratch.ptr); } ();
2876+
if (!__ctfe)
2877+
{
2878+
//use free only at runtime
2879+
() @trusted { GC.free(scratch.ptr); } ();
2880+
}
28462881
}
28472882

28482883
@system unittest

0 commit comments

Comments
 (0)