Skip to content

Commit ac41bcf

Browse files
committed
refactorings inspired by #4
1 parent d09d8ca commit ac41bcf

File tree

1 file changed

+50
-47
lines changed

1 file changed

+50
-47
lines changed

src/ldc/eh/win32.d

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,25 @@ import core.sys.windows.windows;
1313
import core.exception : onOutOfMemoryError, OutOfMemoryError;
1414
import core.stdc.stdlib : malloc, free;
1515
import core.stdc.string : memcpy;
16+
import rt.util.container.common : xmalloc;
1617

1718
// pointers are image relative for Win64 versions
1819
version(Win64)
1920
alias ImgPtr(T) = uint; // offset into image
2021
else
21-
alias ImgPtr(T) = T;
22+
alias ImgPtr(T) = T*;
2223

2324
alias PMFN = ImgPtr!(void function(void*));
2425

25-
struct TypeDescriptor(int N)
26+
struct TypeDescriptor
2627
{
2728
version(_RTTI)
2829
const void * pVFTable; // Field overloaded by RTTI
2930
else
3031
uint hash; // Hash value computed from type's decorated name
3132

3233
void * spare; // reserved, possible for RTTI
33-
char[N+1] name; // variable size, zero terminated
34+
char[1] name; // variable size, zero terminated
3435
}
3536

3637
struct PMD
@@ -43,7 +44,7 @@ struct PMD
4344
struct CatchableType
4445
{
4546
uint properties; // Catchable Type properties (Bit field)
46-
ImgPtr!(TypeDescriptor!1*) pType; // Pointer to TypeDescriptor
47+
ImgPtr!TypeDescriptor pType; // Pointer to TypeDescriptor
4748
PMD thisDisplacement; // Pointer to instance of catch type within thrown object.
4849
int sizeOrOffset; // Size of simple-type object or offset into buffer of 'this' pointer for catch object
4950
PMFN copyFunction; // Copy constructor or CC-closure
@@ -58,15 +59,15 @@ enum CT_IsStdBadAlloc = 0x00000010; // type is a a std::bad_alloc
5859
struct CatchableTypeArray
5960
{
6061
int nCatchableTypes;
61-
ImgPtr!(CatchableType*)[2] arrayOfCatchableTypes;
62+
ImgPtr!CatchableType[1] arrayOfCatchableTypes; // variable size
6263
}
6364

6465
struct _ThrowInfo
6566
{
6667
uint attributes; // Throw Info attributes (Bit field)
6768
PMFN pmfnUnwind; // Destructor to call when exception has been handled or aborted.
6869
PMFN pForwardCompat; // pointer to Forward compatibility frame handler
69-
ImgPtr!(CatchableTypeArray*) pCatchableTypeArray; // pointer to CatchableTypeArray
70+
ImgPtr!CatchableTypeArray pCatchableTypeArray; // pointer to CatchableTypeArray
7071
}
7172

7273
struct ExceptionRecord
@@ -131,60 +132,64 @@ extern(C) void _d_throw_exception(Object e)
131132
import rt.util.container.hashtab;
132133
import core.sync.mutex;
133134

134-
__gshared HashTab!(TypeInfo_Class, _ThrowInfo) throwInfoHashtab;
135-
__gshared HashTab!(TypeInfo_Class, CatchableType) catchableHashtab;
135+
__gshared HashTab!(TypeInfo_Class, ImgPtr!_ThrowInfo) throwInfoHashtab;
136+
__gshared HashTab!(TypeInfo_Class, ImgPtr!CatchableType) catchableHashtab;
136137
__gshared Mutex throwInfoMutex;
137138

138139
// create and cache throwinfo for ti
139-
_ThrowInfo* getThrowInfo(TypeInfo_Class ti)
140+
ImgPtr!_ThrowInfo getThrowInfo(TypeInfo_Class ti)
140141
{
141142
throwInfoMutex.lock();
142143
if (auto p = ti in throwInfoHashtab)
143144
{
144145
throwInfoMutex.unlock();
145-
return p;
146+
return *p;
146147
}
147148

148149
size_t classes = 0;
149150
for (TypeInfo_Class tic = ti; tic; tic = tic.base)
150151
classes++;
151152

152-
size_t sz = int.sizeof + classes * ImgPtr!(CatchableType*).sizeof;
153-
auto cta = cast(CatchableTypeArray*) malloc(sz);
154-
if (!cta)
155-
onOutOfMemoryError();
153+
size_t sz = int.sizeof + classes * ImgPtr!(CatchableType).sizeof;
154+
auto cta = cast(CatchableTypeArray*) xmalloc(sz);
156155
cta.nCatchableTypes = classes;
157156

158157
size_t c = 0;
159-
for (TypeInfo_Class tic = ti; tic; tic = tic.base)
160-
cta.arrayOfCatchableTypes.ptr[c++] = getCatchableType(tic);
158+
for (TypeInfo_Class tic = ti; tic; tic = tic.base, c++)
159+
cta.arrayOfCatchableTypes.ptr[c] = getCatchableType(tic);
161160

162-
_ThrowInfo tinf = { 0, null, null, cta };
161+
auto tinf = cast(_ThrowInfo*) xmalloc(_ThrowInfo.sizeof);
162+
*tinf = _ThrowInfo(0, null, null, cta);
163163
throwInfoHashtab[ti] = tinf;
164-
auto pti = ti in throwInfoHashtab;
165164
throwInfoMutex.unlock();
166-
return pti;
165+
return tinf;
167166
}
168167

169168
CatchableType* getCatchableType(TypeInfo_Class ti)
170169
{
171170
if (auto p = ti in catchableHashtab)
172-
return p;
171+
return *p;
172+
173+
// generate catch types for both D (fully.qualified.name)
174+
// and C++ (D::name mangled to .PAVname@D@@)
175+
size_t p = ti.name.length;
176+
for ( ; p > 0 && ti.name[p-1] != '.'; p--) {}
177+
string name = ti.name[p .. $];
173178

174-
size_t sz = TypeDescriptor!1.sizeof + ti.name.length;
175-
auto td = cast(TypeDescriptor!1*) malloc(sz);
176-
if (!td)
177-
onOutOfMemoryError();
179+
size_t szd = TypeDescriptor.sizeof + ti.name.length;
180+
auto tdd = cast(TypeDescriptor*) xmalloc(szd);
178181

179-
td.hash = 0;
180-
td.spare = null;
181-
td.name.ptr[0] = 'D';
182-
memcpy(td.name.ptr + 1, ti.name.ptr, ti.name.length);
183-
td.name.ptr[ti.name.length + 1] = 0;
182+
tdd.hash = 0;
183+
tdd.spare = null;
184+
tdd.name.ptr[0] = 'D';
185+
memcpy(tdd.name.ptr + 1, ti.name.ptr, ti.name.length);
186+
tdd.name.ptr[ti.name.length + 1] = 0;
187+
188+
auto ct = cast(CatchableType*) xmalloc(2 * CatchableType.sizeof);
189+
*ct = CatchableType(CT_IsSimpleType, tdd, PMD(0, -1, 0), 4, null);
184190

185-
CatchableType ct = { CT_IsSimpleType, td, { 0, -1, 0 }, 4, null };
186191
catchableHashtab[ti] = ct;
187-
return ti in catchableHashtab;
192+
return ct;
188193
}
189194

190195
///////////////////////////////////////////////////////////////
@@ -281,19 +286,18 @@ nothrow:
281286

282287
void swap(ref ExceptionStack other)
283288
{
284-
auto olength = other._length; other._length = _length; _length = olength;
285-
auto op = other._p; other._p = _p; _p = op;
286-
auto ocap = other._cap; other._cap = _cap; _cap = ocap;
289+
static void swapField(T)(ref T a, ref T b) { T o = b; b = a; a = o; }
290+
swapField(_length, other._length);
291+
swapField(_p, other._p);
292+
swapField(_cap, other._cap);
287293
}
288294

289295
private:
290296
void grow()
291297
{
292298
// alloc from GC? add array as a GC range?
293299
immutable ncap = _cap ? 2 * _cap : 64;
294-
auto p = cast(Throwable*)malloc(ncap * Throwable.sizeof);
295-
if (p is null)
296-
onOutOfMemoryError();
300+
auto p = cast(Throwable*)xmalloc(ncap * Throwable.sizeof);
297301
p[0 .. _length] = _p[0 .. _length];
298302
free(_p);
299303
_p = p;
@@ -483,7 +487,6 @@ extern(C) int* __processing_throw() nothrow;
483487

484488
extern(C) void* _d_eh_swapContext(FiberContext* newContext) nothrow
485489
{
486-
import rt.util.container.common : xmalloc;
487490
import core.stdc.string : memset;
488491
if (!fiberContext)
489492
{
@@ -514,16 +517,16 @@ extern(C) void* _d_eh_swapContext(FiberContext* newContext) nothrow
514517
fiberContext = newContext;
515518
return old;
516519
}
517-
518-
static ~this()
519-
{
520+
521+
static ~this()
522+
{
520523
import core.stdc.stdlib : free;
521-
if (fiberContext)
522-
{
523-
destroy(*fiberContext);
524-
free(fiberContext);
525-
}
526-
}
524+
if (fiberContext)
525+
{
526+
destroy(*fiberContext);
527+
free(fiberContext);
528+
}
529+
}
527530

528531
///////////////////////////////////////////////////////////////
529532
void msvc_eh_init()

0 commit comments

Comments
 (0)