@@ -13,24 +13,25 @@ import core.sys.windows.windows;
1313import core.exception : onOutOfMemoryError, OutOfMemoryError;
1414import core.stdc.stdlib : malloc, free;
1515import core.stdc.string : memcpy;
16+ import rt.util.container.common : xmalloc;
1617
1718// pointers are image relative for Win64 versions
1819version (Win64 )
1920 alias ImgPtr (T) = uint ; // offset into image
2021else
21- alias ImgPtr (T) = T;
22+ alias ImgPtr (T) = T* ;
2223
2324alias 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
3637struct PMD
@@ -43,7 +44,7 @@ struct PMD
4344struct 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
5859struct CatchableTypeArray
5960{
6061 int nCatchableTypes;
61- ImgPtr! ( CatchableType* )[ 2 ] arrayOfCatchableTypes;
62+ ImgPtr! CatchableType[ 1 ] arrayOfCatchableTypes; // variable size
6263}
6364
6465struct _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
7273struct ExceptionRecord
@@ -131,60 +132,64 @@ extern(C) void _d_throw_exception(Object e)
131132import rt.util.container.hashtab;
132133import 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
169168CatchableType* 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
289295private :
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
484488extern (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// /////////////////////////////////////////////////////////////
529532void msvc_eh_init ()
0 commit comments