Skip to content

Commit 99d6f33

Browse files
authored
Merge pull request #39 from open-watt/druntime_scrub
More druntime scrubbing
2 parents f4ec849 + 7082478 commit 99d6f33

File tree

4 files changed

+133
-43
lines changed

4 files changed

+133
-43
lines changed

src/urt/internal/lifetime.d

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
module urt.internal.lifetime;
2+
3+
import urt.lifetime : forward;
4+
5+
/+
6+
emplaceRef is a package function for druntime internal use. It works like
7+
emplace, but takes its argument by ref (as opposed to "by pointer").
8+
This makes it easier to use, easier to be safe, and faster in a non-inline
9+
build.
10+
Furthermore, emplaceRef optionally takes a type parameter, which specifies
11+
the type we want to build. This helps to build qualified objects on mutable
12+
buffer, without breaking the type system with unsafe casts.
13+
+/
14+
void emplaceRef(T, UT, Args...)(ref UT chunk, auto ref Args args)
15+
{
16+
static if (args.length == 0)
17+
{
18+
static assert(is(typeof({static T i;})),
19+
"Cannot emplace a " ~ T.stringof ~ " because " ~ T.stringof ~
20+
".this() is annotated with @disable.");
21+
static if (is(T == class)) static assert(!__traits(isAbstractClass, T),
22+
T.stringof ~ " is abstract and it can't be emplaced");
23+
emplaceInitializer(chunk);
24+
}
25+
else static if (
26+
!is(T == struct) && Args.length == 1 /* primitives, enums, arrays */
27+
||
28+
Args.length == 1 && is(typeof({T t = forward!(args[0]);})) /* conversions */
29+
||
30+
is(typeof(T(forward!args))) /* general constructors */)
31+
{
32+
static struct S
33+
{
34+
T payload;
35+
this()(auto ref Args args)
36+
{
37+
static if (__traits(compiles, payload = forward!args))
38+
payload = forward!args;
39+
else
40+
payload = T(forward!args);
41+
}
42+
}
43+
if (__ctfe)
44+
{
45+
static if (__traits(compiles, chunk = T(forward!args)))
46+
chunk = T(forward!args);
47+
else static if (args.length == 1 && __traits(compiles, chunk = forward!(args[0])))
48+
chunk = forward!(args[0]);
49+
else assert(0, "CTFE emplace doesn't support "
50+
~ T.stringof ~ " from " ~ Args.stringof);
51+
}
52+
else
53+
{
54+
S* p = () @trusted { return cast(S*) &chunk; }();
55+
static if (UT.sizeof > 0)
56+
emplaceInitializer(*p);
57+
p.__ctor(forward!args);
58+
}
59+
}
60+
else static if (is(typeof(chunk.__ctor(forward!args))))
61+
{
62+
// This catches the rare case of local types that keep a frame pointer
63+
emplaceInitializer(chunk);
64+
chunk.__ctor(forward!args);
65+
}
66+
else
67+
{
68+
//We can't emplace. Try to diagnose a disabled postblit.
69+
static assert(!(Args.length == 1 && is(Args[0] : T)),
70+
"Cannot emplace a " ~ T.stringof ~ " because " ~ T.stringof ~
71+
".this(this) is annotated with @disable.");
72+
73+
//We can't emplace.
74+
static assert(false,
75+
T.stringof ~ " cannot be emplaced from " ~ Args[].stringof ~ ".");
76+
}
77+
}
78+
79+
// ditto
80+
static import urt.traits;
81+
void emplaceRef(UT, Args...)(ref UT chunk, auto ref Args args)
82+
if (is(UT == urt.traits.Unqual!UT))
83+
{
84+
emplaceRef!(UT, UT)(chunk, forward!args);
85+
}
86+
87+
/+
88+
Emplaces T.init.
89+
In contrast to `emplaceRef(chunk)`, there are no checks for disabled default
90+
constructors etc.
91+
+/
92+
void emplaceInitializer(T)(scope ref T chunk) nothrow pure @trusted
93+
if (!is(T == const) && !is(T == immutable) && !is(T == inout))
94+
{
95+
import core.internal.traits : hasElaborateAssign;
96+
97+
static if (__traits(isZeroInit, T))
98+
{
99+
import urt.mem : memset;
100+
memset(cast(void*) &chunk, 0, T.sizeof);
101+
}
102+
else static if (__traits(isScalar, T) ||
103+
T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; }))
104+
{
105+
chunk = T.init;
106+
}
107+
else static if (__traits(isStaticArray, T))
108+
{
109+
// For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one.
110+
foreach (i; 0 .. T.length)
111+
{
112+
emplaceInitializer(chunk[i]);
113+
}
114+
}
115+
else
116+
{
117+
import urt.mem : memcpy;
118+
const initializer = __traits(initSymbol, T);
119+
memcpy(cast(void*)&chunk, initializer.ptr, initializer.length);
120+
}
121+
}

src/urt/lifetime.d

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module urt.lifetime;
22

3+
import urt.internal.lifetime : emplaceRef; // TODO: DESTROY THIS!
34

45
T* emplace(T)(T* chunk) @safe pure
56
{
@@ -78,12 +79,6 @@ T* emplace(T, Args...)(void[] chunk, auto ref Args args)
7879
return cast(T*) chunk.ptr;
7980
}
8081

81-
82-
// HACK: we should port this to our lib...
83-
static import core.internal.lifetime;
84-
alias emplaceRef = core.internal.lifetime.emplaceRef;
85-
86-
8782
/+
8883
void copyEmplace(S, T)(ref S source, ref T target) @system
8984
if (is(immutable S == immutable T))
@@ -269,7 +264,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source) @
269264

270265
static if (hasElaborateAssign!T || !isAssignable!T)
271266
{
272-
import core.stdc.string : memcpy;
267+
import urt.mem : memcpy;
273268
() @trusted { memcpy(&target, &source, T.sizeof); }();
274269
}
275270
else
@@ -327,20 +322,11 @@ void moveEmplace(T)(ref T source, ref T target) @system @nogc
327322

328323

329324

330-
//debug = PRINTF;
331-
332-
debug(PRINTF)
333-
{
334-
import core.stdc.stdio;
335-
}
336-
337325
/// Implementation of `_d_delstruct` and `_d_delstructTrace`
338326
template _d_delstructImpl(T)
339327
{
340328
private void _d_delstructImpure(ref T p)
341329
{
342-
debug(PRINTF) printf("_d_delstruct(%p)\n", p);
343-
344330
destroy(*p);
345331
p = null;
346332
}
@@ -478,27 +464,11 @@ T _d_newclassT(T)() @trusted
478464
attr |= BlkAttr.NO_SCAN;
479465
480466
p = GC.malloc(init.length, attr, typeid(T));
481-
debug(PRINTF) printf(" p = %p\n", p);
482-
}
483-
484-
debug(PRINTF)
485-
{
486-
printf("p = %p\n", p);
487-
printf("init.ptr = %p, len = %llu\n", init.ptr, cast(ulong)init.length);
488-
printf("vptr = %p\n", *cast(void**) init);
489-
printf("vtbl[0] = %p\n", (*cast(void***) init)[0]);
490-
printf("vtbl[1] = %p\n", (*cast(void***) init)[1]);
491-
printf("init[0] = %x\n", (cast(uint*) init)[0]);
492-
printf("init[1] = %x\n", (cast(uint*) init)[1]);
493-
printf("init[2] = %x\n", (cast(uint*) init)[2]);
494-
printf("init[3] = %x\n", (cast(uint*) init)[3]);
495-
printf("init[4] = %x\n", (cast(uint*) init)[4]);
496467
}
497468
498469
// initialize it
499470
p[0 .. init.length] = init[];
500471
501-
debug(PRINTF) printf("initialization done\n");
502472
return cast(T) p;
503473
}
504474

src/urt/math.d

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
module urt.math;
22

33
import urt.intrinsic;
4-
import core.stdc.stdio; // For writeDebugf
54

65
// for arch where using FPU for int<->float conversions is preferred
76
//version = PreferFPUIntConv;

src/urt/mem/package.d

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ extern(C)
1111
nothrow @nogc:
1212
void* alloca(size_t size);
1313

14-
void* memcpy(void* dest, const void* src, size_t n);
15-
void* memmove(void* dest, const void* src, size_t n);
16-
void* memset(void* s, int c, size_t n);
17-
void* memzero(void* s, size_t n) => memset(s, 0, n);
14+
void* memcpy(void* dest, const void* src, size_t n) pure;
15+
void* memmove(void* dest, const void* src, size_t n) pure;
16+
void* memset(void* s, int c, size_t n) pure;
17+
void* memzero(void* s, size_t n) pure => memset(s, 0, n);
1818

19-
size_t strlen(const char* s);
20-
int strcmp(const char* s1, const char* s2);
21-
char* strcpy(char* dest, const char* src);
19+
size_t strlen(const char* s) pure;
20+
int strcmp(const char* s1, const char* s2) pure;
21+
char* strcpy(char* dest, const char* src) pure;
2222
char* strcat(char* dest, const char* src);
2323

24-
size_t wcslen(const wchar_t* s);
25-
// wchar_t* wcscpy(wchar_t* dest, const wchar_t* src);
24+
size_t wcslen(const wchar_t* s) pure;
25+
// wchar_t* wcscpy(wchar_t* dest, const wchar_t* src) pure;
2626
// wchar_t* wcscat(wchar_t* dest, const wchar_t* src);
27-
// wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t n);
27+
// wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t n) pure;
2828
// wchar_t* wcsncat(wchar_t* dest, const wchar_t* src, size_t n);
2929
}

0 commit comments

Comments
 (0)