summaryrefslogtreecommitdiff
path: root/libphobos/libdruntime/core
diff options
context:
space:
mode:
Diffstat (limited to 'libphobos/libdruntime/core')
-rw-r--r--libphobos/libdruntime/core/exception.d84
-rw-r--r--libphobos/libdruntime/core/int128.d156
-rw-r--r--libphobos/libdruntime/core/lifetime.d20
3 files changed, 152 insertions, 108 deletions
diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d
index a6928660773..81aa43b27d0 100644
--- a/libphobos/libdruntime/core/exception.d
+++ b/libphobos/libdruntime/core/exception.d
@@ -19,29 +19,6 @@ void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted
assert(0, "No appropriate switch clause found");
}
-version (D_BetterC)
-{
- // When compiling with -betterC we use template functions so if they are
- // used the bodies are copied into the user's program so there is no need
- // for the D runtime during linking.
-
- // In the future we might want to convert all functions in this module to
- // templates even for ordinary builds instead of providing them as an
- // extern(C) library.
-
- void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
- {
- assert(0, "Memory allocation failed");
- }
- alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;
-
- void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
- {
- assert(0, "Invalid memory operation");
- }
-}
-else:
-
/**
* Thrown on a range error.
*/
@@ -218,17 +195,17 @@ private void rangeMsgPut(ref char[] r, scope const(char)[] e) @nogc nothrow pure
*/
class AssertError : Error
{
- @safe pure nothrow this( string file, size_t line )
+ @safe pure nothrow @nogc this( string file, size_t line )
{
this(cast(Throwable)null, file, line);
}
- @safe pure nothrow this( Throwable next, string file = __FILE__, size_t line = __LINE__ )
+ @safe pure nothrow @nogc this( Throwable next, string file = __FILE__, size_t line = __LINE__ )
{
this( "Assertion failure", file, line, next);
}
- @safe pure nothrow this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
+ @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
{
super( msg, file, line, next );
}
@@ -692,26 +669,49 @@ extern (C) void onFinalizeError( TypeInfo info, Throwable e, string file = __FIL
throw staticError!FinalizeError(info, e, file, line);
}
-/**
- * A callback for out of memory errors in D. An $(LREF OutOfMemoryError) will be
- * thrown.
- *
- * Throws:
- * $(LREF OutOfMemoryError).
- */
-extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+version (D_BetterC)
{
- // NOTE: Since an out of memory condition exists, no allocation must occur
- // while generating this object.
- throw staticError!OutOfMemoryError();
-}
+ // When compiling with -betterC we use template functions so if they are
+ // used the bodies are copied into the user's program so there is no need
+ // for the D runtime during linking.
-extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
-{
- // suppress stacktrace until they are @nogc
- throw staticError!OutOfMemoryError(false);
+ // In the future we might want to convert all functions in this module to
+ // templates even for ordinary builds instead of providing them as an
+ // extern(C) library.
+
+ void onOutOfMemoryError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
+ {
+ assert(0, "Memory allocation failed");
+ }
+ alias onOutOfMemoryErrorNoGC = onOutOfMemoryError;
+
+ void onInvalidMemoryOperationError()(void* pretend_sideffect = null) @nogc nothrow pure @trusted
+ {
+ assert(0, "Invalid memory operation");
+ }
}
+else
+{
+ /**
+ * A callback for out of memory errors in D. An $(LREF OutOfMemoryError) will be
+ * thrown.
+ *
+ * Throws:
+ * $(LREF OutOfMemoryError).
+ */
+ extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc /* dmd @@@BUG11461@@@ */
+ {
+ // NOTE: Since an out of memory condition exists, no allocation must occur
+ // while generating this object.
+ throw staticError!OutOfMemoryError();
+ }
+ extern (C) void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc
+ {
+ // suppress stacktrace until they are @nogc
+ throw staticError!OutOfMemoryError(false);
+ }
+}
/**
* A callback for invalid memory operations in D. An
diff --git a/libphobos/libdruntime/core/int128.d b/libphobos/libdruntime/core/int128.d
index 2f628c03138..e4326fd54c3 100644
--- a/libphobos/libdruntime/core/int128.d
+++ b/libphobos/libdruntime/core/int128.d
@@ -18,15 +18,26 @@ alias I = long;
alias U = ulong;
enum Ubits = uint(U.sizeof * 8);
-align(16) struct Cent
+version (X86_64) private enum Cent_alignment = 16;
+else private enum Cent_alignment = (size_t.sizeof * 2);
+
+align(Cent_alignment) struct Cent
{
- U lo; // low 64 bits
- U hi; // high 64 bits
+ version (LittleEndian)
+ {
+ U lo; // low 64 bits
+ U hi; // high 64 bits
+ }
+ else
+ {
+ U hi; // high 64 bits
+ U lo; // low 64 bits
+ }
}
-enum One = Cent(1);
-enum Zero = Cent();
-enum MinusOne = neg(One);
+enum Cent One = { lo:1 };
+enum Cent Zero = { lo:0 };
+enum Cent MinusOne = neg(One);
/*****************************
* Test against 0
@@ -320,7 +331,8 @@ Cent ror(Cent c, uint n)
pure
Cent and(Cent c1, Cent c2)
{
- return Cent(c1.lo & c2.lo, c1.hi & c2.hi);
+ const Cent ret = { lo:c1.lo & c2.lo, hi:c1.hi & c2.hi };
+ return ret;
}
/****************************
@@ -334,7 +346,8 @@ Cent and(Cent c1, Cent c2)
pure
Cent or(Cent c1, Cent c2)
{
- return Cent(c1.lo | c2.lo, c1.hi | c2.hi);
+ const Cent ret = { lo:c1.lo | c2.lo, hi:c1.hi | c2.hi };
+ return ret;
}
/****************************
@@ -348,7 +361,8 @@ Cent or(Cent c1, Cent c2)
pure
Cent xor(Cent c1, Cent c2)
{
- return Cent(c1.lo ^ c2.lo, c1.hi ^ c2.hi);
+ const Cent ret = { lo:c1.lo ^ c2.lo, hi:c1.hi ^ c2.hi };
+ return ret;
}
/****************************
@@ -363,7 +377,8 @@ pure
Cent add(Cent c1, Cent c2)
{
U r = cast(U)(c1.lo + c2.lo);
- return Cent(r, cast(U)(c1.hi + c2.hi + (r < c1.lo)));
+ const Cent ret = { lo:r, hi:cast(U)(c1.hi + c2.hi + (r < c1.lo)) };
+ return ret;
}
/****************************
@@ -419,9 +434,9 @@ Cent mul(Cent c1, Cent c2)
const c1h1 = c1.hi >> mulshift;
r3 = c1h1 * c2l0 + (r3 & mulmask);
- return Cent((r0 & mulmask) + (r1 & mulmask) * (mulmask + 1),
- (r2 & mulmask) + (r3 & mulmask) * (mulmask + 1));
-
+ const Cent ret = { lo:(r0 & mulmask) + (r1 & mulmask) * (mulmask + 1),
+ hi:(r2 & mulmask) + (r3 & mulmask) * (mulmask + 1) };
+ return ret;
}
@@ -523,8 +538,10 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
if (c1.hi == 0 && c2.hi == 0)
{
// Single precision divide
- modulus = Cent(c1.lo % c2.lo);
- return Cent(c1.lo / c2.lo);
+ const Cent rem = { lo:c1.lo % c2.lo };
+ modulus = rem;
+ const Cent ret = { lo:c1.lo / c2.lo };
+ return ret;
}
if (c1.hi == 0)
{
@@ -539,10 +556,11 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
const q1 = (c1.hi < c2.lo) ? 0 : (c1.hi / c2.lo);
if (q1)
c1.hi = c1.hi % c2.lo;
- U rem;
- const q0 = udivmod128_64(c1, c2.lo, rem);
- modulus = Cent(rem);
- return Cent(q0, q1);
+ Cent rem;
+ const q0 = udivmod128_64(c1, c2.lo, rem.lo);
+ modulus = rem;
+ const Cent ret = { lo:q0, hi:q1 };
+ return ret;
}
// Full cent precision division.
@@ -560,10 +578,10 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
// Get quotient from divide unsigned operation.
U rem_ignored;
- const q1 = udivmod128_64(u1, v1, rem_ignored);
+ const Cent q1 = { lo:udivmod128_64(u1, v1, rem_ignored) };
// Undo normalization and division of c1 by 2.
- Cent quotient = shr(shl(Cent(q1), shift), 63);
+ Cent quotient = shr(shl(q1, shift), 63);
// Make quotient correct or too small by 1
if (tst(quotient))
@@ -770,44 +788,44 @@ version (unittest)
unittest
{
- const C0 = Zero;
- const C1 = One;
- const C2 = Cent(2);
- const C3 = Cent(3);
- const C5 = Cent(5);
- const C10 = Cent(10);
- const C20 = Cent(20);
- const C30 = Cent(30);
- const C100 = Cent(100);
-
- const Cm1 = neg(One);
- const Cm3 = neg(C3);
- const Cm10 = neg(C10);
-
- const C3_1 = Cent(1,3);
- const C3_2 = Cent(2,3);
- const C4_8 = Cent(8, 4);
- const C5_0 = Cent(0, 5);
- const C7_1 = Cent(1,7);
- const C7_9 = Cent(9,7);
- const C9_3 = Cent(3,9);
- const C10_0 = Cent(0,10);
- const C10_1 = Cent(1,10);
- const C10_3 = Cent(3,10);
- const C11_3 = Cent(3,11);
- const C20_0 = Cent(0,20);
- const C90_30 = Cent(30,90);
-
- const Cm10_0 = inc(com(C10_0)); // Cent(0, -10);
- const Cm10_1 = inc(com(C10_1)); // Cent(-1, -11);
- const Cm10_3 = inc(com(C10_3)); // Cent(-3, -11);
- const Cm20_0 = inc(com(C20_0)); // Cent(0, -20);
-
- enum Cs_3 = Cent(3, I.min);
-
- const Cbig_1 = Cent(0xa3ccac1832952398, 0xc3ac542864f652f8);
- const Cbig_2 = Cent(0x5267b85f8a42fc20, 0);
- const Cbig_3 = Cent(0xf0000000ffffffff, 0);
+ const Cent C0 = Zero;
+ const Cent C1 = One;
+ const Cent C2 = { lo:2 };
+ const Cent C3 = { lo:3 };
+ const Cent C5 = { lo:5 };
+ const Cent C10 = { lo:10 };
+ const Cent C20 = { lo:20 };
+ const Cent C30 = { lo:30 };
+ const Cent C100 = { lo:100 };
+
+ const Cent Cm1 = neg(One);
+ const Cent Cm3 = neg(C3);
+ const Cent Cm10 = neg(C10);
+
+ const Cent C3_1 = { lo:1, hi:3 };
+ const Cent C3_2 = { lo:2, hi:3 };
+ const Cent C4_8 = { lo:8, hi:4 };
+ const Cent C5_0 = { lo:0, hi:5 };
+ const Cent C7_1 = { lo:1, hi:7 };
+ const Cent C7_9 = { lo:9, hi:7 };
+ const Cent C9_3 = { lo:3, hi:9 };
+ const Cent C10_0 = { lo:0, hi:10 };
+ const Cent C10_1 = { lo:1, hi:10 };
+ const Cent C10_3 = { lo:3, hi:10 };
+ const Cent C11_3 = { lo:3, hi:11 };
+ const Cent C20_0 = { lo:0, hi:20 };
+ const Cent C90_30 = { lo:30, hi:90 };
+
+ const Cent Cm10_0 = inc(com(C10_0)); // Cent(lo=0, hi=-10);
+ const Cent Cm10_1 = inc(com(C10_1)); // Cent(lo=-1, hi=-11);
+ const Cent Cm10_3 = inc(com(C10_3)); // Cent(lo=-3, hi=-11);
+ const Cent Cm20_0 = inc(com(C20_0)); // Cent(lo=0, hi=-20);
+
+ enum Cent Cs_3 = { lo:3, hi:I.min };
+
+ const Cent Cbig_1 = { lo:0xa3ccac1832952398, hi:0xc3ac542864f652f8 };
+ const Cent Cbig_2 = { lo:0x5267b85f8a42fc20, hi:0 };
+ const Cent Cbig_3 = { lo:0xf0000000ffffffff, hi:0 };
/************************/
@@ -893,12 +911,20 @@ unittest
assert(div(mul(C90_30, C2), C2) == C90_30);
assert(div(mul(C90_30, C2), C90_30) == C2);
- assert(divmod(Cbig_1, Cbig_2, modulus) == Cent(0x4496aa309d4d4a2f, U.max));
- assert(modulus == Cent(0xd83203d0fdc799b8, U.max));
- assert(udivmod(Cbig_1, Cbig_2, modulus) == Cent(0x5fe0e9bace2bedad, 2));
- assert(modulus == Cent(0x2c923125a68721f8, 0));
- assert(div(Cbig_1, Cbig_3) == Cent(0xbfa6c02b5aff8b86, U.max));
- assert(udiv(Cbig_1, Cbig_3) == Cent(0xd0b7d13b48cb350f, 0));
+ const Cent Cb1divb2 = { lo:0x4496aa309d4d4a2f, hi:U.max };
+ const Cent Cb1modb2 = { lo:0xd83203d0fdc799b8, hi:U.max };
+ assert(divmod(Cbig_1, Cbig_2, modulus) == Cb1divb2);
+ assert(modulus == Cb1modb2);
+
+ const Cent Cb1udivb2 = { lo:0x5fe0e9bace2bedad, hi:2 };
+ const Cent Cb1umodb2 = { lo:0x2c923125a68721f8, hi:0 };
+ assert(udivmod(Cbig_1, Cbig_2, modulus) == Cb1udivb2);
+ assert(modulus == Cb1umodb2);
+
+ const Cent Cb1divb3 = { lo:0xbfa6c02b5aff8b86, hi:U.max };
+ const Cent Cb1udivb3 = { lo:0xd0b7d13b48cb350f, hi:0 };
+ assert(div(Cbig_1, Cbig_3) == Cb1divb3);
+ assert(udiv(Cbig_1, Cbig_3) == Cb1udivb3);
assert(mul(Cm10, C1) == Cm10);
assert(mul(C1, Cm10) == Cm10);
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index 3a7c8e02b8a..47fed9dc514 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -1273,7 +1273,9 @@ void copyEmplace(S, T)(ref S source, ref T target) @system
}
else static if (__traits(hasCopyConstructor, T))
{
- emplace(cast(Unqual!(T)*) &target); // blit T.init
+ // https://issues.dlang.org/show_bug.cgi?id=22766
+ import core.internal.lifetime : emplaceInitializer;
+ emplaceInitializer(*(cast(Unqual!T*)&target));
static if (__traits(isNested, T))
{
// copy context pointer
@@ -1373,6 +1375,22 @@ void copyEmplace(S, T)(ref S source, ref T target) @system
static assert(!__traits(compiles, copyEmplace(ss, t)));
}
+// https://issues.dlang.org/show_bug.cgi?id=22766
+@system pure nothrow @nogc unittest
+{
+ static struct S
+ {
+ @disable this();
+ this(int) @safe pure nothrow @nogc{}
+ this(ref const(S) other) @safe pure nothrow @nogc {}
+ }
+
+ S s1 = S(1);
+ S s2 = void;
+ copyEmplace(s1, s2);
+ assert(s2 == S(1));
+}
+
version (DigitalMars) version (X86) version (Posix) version = DMD_X86_Posix;
// don't violate immutability for reference types