Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Commit

Permalink
LDC: Add core.exception TLS workaround for Windows druntime DLL
Browse files Browse the repository at this point in the history
This works around the single remaining Phobos DLL linking error (somehow
only required for debug Phobos), by replacing direct access to a little
TLS buffer with a non-inlineable call to an accessor function (exported
by druntime DLL and imported by other DLLs/executables instantiating the
`staticError` template), on Windows in general.

We cannot restrict this to `version(Shared)`, because that is set when
compiling druntime, but what matters are `staticError` instantiations in
other code.
  • Loading branch information
kinke committed Apr 30, 2021
1 parent bc9e711 commit f23246f
Showing 1 changed file with 17 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/core/exception.d
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,16 @@ extern (C)
// TLS storage shared for all errors, chaining might create circular reference
private align(2 * size_t.sizeof) void[128] _store;

version (LDC) version (Windows)
{
version = LDC_Windows;

// cannot access TLS globals directly across DLL boundaries, e.g.,
// when instantiating `staticError` below in another DLL
pragma(inline, false) // could be safely inlined in the binary containing druntime only
private ref void[128] getStore() { return _store; }
}

// only Errors for now as those are rarely chained
private T staticError(T, Args...)(auto ref Args args)
if (is(T : Error))
Expand All @@ -640,8 +650,13 @@ private T staticError(T, Args...)(auto ref Args args)
static assert(__traits(classInstanceSize, T) <= _store.length,
T.stringof ~ " is too large for staticError()");

_store[0 .. __traits(classInstanceSize, T)] = typeid(T).initializer[];
return cast(T) _store.ptr;
version (LDC_Windows)
auto store = &getStore();
else
auto store = &_store;

(*store)[0 .. __traits(classInstanceSize, T)] = typeid(T).initializer[];
return cast(T) store.ptr;
}
auto res = (cast(T function() @trusted pure nothrow @nogc) &get)();
res.__ctor(args);
Expand Down

0 comments on commit f23246f

Please sign in to comment.