@@ -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
@@ -142,96 +143,77 @@ extern(C) string _d_toString(Object o)
142143import rt.util.container.hashtab;
143144import core.sync.mutex ;
144145
145- __gshared HashTab! (TypeInfo_Class , _ThrowInfo) throwInfoHashtab;
146- __gshared HashTab! (TypeInfo_Class , CatchableType) catchableHashtab;
146+ __gshared HashTab! (TypeInfo_Class , ImgPtr ! _ThrowInfo) throwInfoHashtab;
147+ __gshared HashTab! (TypeInfo_Class , ImgPtr ! CatchableType) catchableHashtab;
147148__gshared Mutex throwInfoMutex;
148149
149150// create and cache throwinfo for ti
150- _ThrowInfo* getThrowInfo (TypeInfo_Class ti)
151+ ImgPtr ! _ThrowInfo getThrowInfo (TypeInfo_Class ti)
151152{
152153 throwInfoMutex.lock();
153154 if (auto p = ti in throwInfoHashtab)
154155 {
155156 throwInfoMutex.unlock();
156- return p;
157+ return * p;
157158 }
158159
159- bool isError = false ;
160- bool isException = false ;
161160 size_t classes = 0 ;
162161 for (TypeInfo_Class tic = ti; tic; tic = tic.base)
163- {
164- classes++ ;
165- if (tic == typeid (Exception ))
166- isException = true ;
167- if (tic == typeid (Error))
168- isError = true ;
169- }
170- if (isError || isException)
171- classes += 2 ;
162+ classes += 2 ; // D and C++
172163
173- size_t sz = int .sizeof + classes * ImgPtr! (CatchableType* ).sizeof;
174- auto cta = cast (CatchableTypeArray* ) malloc(sz);
175- if (! cta)
176- onOutOfMemoryError();
164+ size_t sz = int .sizeof + classes * ImgPtr! (CatchableType).sizeof;
165+ auto cta = cast (CatchableTypeArray* ) xmalloc(sz);
177166 cta.nCatchableTypes = classes;
178167
179168 size_t c = 0 ;
180- for (TypeInfo_Class tic = ti; tic; tic = tic.base)
181- cta.arrayOfCatchableTypes.ptr[c++ ] = getCatchableType(tic);
182- if (isError || isException)
183- cta.arrayOfCatchableTypes.ptr[c++ ] = ctCxxDThrowable;
184- if (isException)
185- cta.arrayOfCatchableTypes.ptr[c++ ] = ctCxxDException;
186- if (isError)
187- cta.arrayOfCatchableTypes.ptr[c++ ] = ctCxxDError;
188-
189- _ThrowInfo tinf = { 0 , null , null , cta };
169+ for (TypeInfo_Class tic = ti; tic; tic = tic.base, c += 2 )
170+ {
171+ cta.arrayOfCatchableTypes.ptr[c] = getCatchableType(tic);
172+ cta.arrayOfCatchableTypes.ptr[c + 1 ] = cta.arrayOfCatchableTypes.ptr[c] + 1 ;
173+ }
174+
175+ auto tinf = cast (_ThrowInfo* ) xmalloc(_ThrowInfo.sizeof);
176+ * tinf = _ThrowInfo(0 , null , null , cta);
190177 throwInfoHashtab[ti] = tinf;
191- auto pti = ti in throwInfoHashtab;
192178 throwInfoMutex.unlock();
193- return pti ;
179+ return tinf ;
194180}
195-
181+
182+ // returns pointer to array of 2 elements, one for D and one for C++
196183CatchableType* getCatchableType (TypeInfo_Class ti)
197184{
198185 if (auto p = ti in catchableHashtab)
199- return p;
186+ return * p;
187+
188+ // generate catch types for both D (fully.qualified.name)
189+ // and C++ (D::name mangled to .PAVname@D@@)
190+ size_t p = ti.name.length;
191+ for ( ; p > 0 && ti.name[p- 1 ] != ' .' ; p-- ) {}
192+ string name = ti.name[p .. $];
193+
194+ size_t szd = (TypeDescriptor.sizeof + ti.name.length + 3 ) & ~ 3 ;
195+ size_t szcpp = TypeDescriptor.sizeof + name.length + 8 ;
196+ auto tdd = cast (TypeDescriptor* ) xmalloc(szd + szcpp);
197+
198+ tdd.hash = 0 ;
199+ tdd.spare = null ;
200+ tdd.name.ptr[0 ] = ' D' ;
201+ memcpy(tdd.name.ptr + 1 , ti.name.ptr, ti.name.length);
202+ tdd.name.ptr[ti.name.length + 1 ] = 0 ;
203+
204+ auto tdcpp = cast (TypeDescriptor* ) (cast (char * )tdd + szd);
205+ tdcpp.hash = 0 ;
206+ tdcpp.spare = null ;
207+ memcpy(tdcpp.name.ptr, " .PAV" .ptr, 4 );
208+ memcpy(tdcpp.name.ptr + 4 , name.ptr, name.length);
209+ memcpy(tdcpp.name.ptr + 4 + name.length, " @D@@" .ptr, 5 );
210+
211+ auto ct = cast (CatchableType* ) xmalloc(2 * CatchableType.sizeof);
212+ ct[0 ] = CatchableType(CT_IsSimpleType, tdd, PMD (0 , - 1 , 0 ), 4 , null );
213+ ct[1 ] = CatchableType(CT_IsSimpleType, tdcpp, PMD (0 , - 1 , 0 ), 4 , null );
200214
201- size_t sz = TypeDescriptor! 1. sizeof + ti.name.length;
202- auto td = cast (TypeDescriptor! 1 * ) malloc(sz);
203- if (! td)
204- onOutOfMemoryError();
205-
206- td.hash = 0 ;
207- td.spare = null ;
208- td.name.ptr[0 ] = ' D' ;
209- memcpy(td.name.ptr + 1 , ti.name.ptr, ti.name.length);
210- td.name.ptr[ti.name.length + 1 ] = 0 ;
211-
212- CatchableType ct = { CT_IsSimpleType, td, { 0 , - 1 , 0 }, 4 , null };
213215 catchableHashtab[ti] = ct;
214- return ti in catchableHashtab;
215- }
216-
217- CatchableType* createCxxCatchableType (string cxxMangledName)
218- {
219- size_t sz = TypeDescriptor! 1. sizeof + cxxMangledName.length;
220- auto td = cast (TypeDescriptor! 1 * ) malloc(sz);
221- if (! td)
222- onOutOfMemoryError();
223-
224- td.hash = 0 ;
225- td.spare = null ;
226- memcpy(td.name.ptr, cxxMangledName.ptr, cxxMangledName.length);
227- td.name.ptr[cxxMangledName.length + 1 ] = 0 ;
228-
229- CatchableType* pct = cast (CatchableType* ) malloc(CatchableType.sizeof);
230- if (! pct)
231- onOutOfMemoryError();
232- CatchableType ct = { CT_IsSimpleType, td, { 0 , - 1 , 0 }, 4 , null };
233- * pct = ct;
234- return pct;
216+ return ct;
235217}
236218
237219// /////////////////////////////////////////////////////////////
@@ -338,9 +320,7 @@ private:
338320 {
339321 // alloc from GC? add array as a GC range?
340322 immutable ncap = _cap ? 2 * _cap : 64 ;
341- auto p = cast (Throwable* )malloc(ncap * Throwable.sizeof);
342- if (p is null )
343- onOutOfMemoryError();
323+ auto p = cast (Throwable* )xmalloc(ncap * Throwable.sizeof);
344324 p[0 .. _length] = _p[0 .. _length];
345325 free(_p);
346326 _p = p;
@@ -530,7 +510,6 @@ extern(C) int* __processing_throw() nothrow;
530510
531511extern (C ) void * _d_eh_swapContext(FiberContext* newContext) nothrow
532512{
533- import rt.util.container.common : xmalloc;
534513 import core.stdc.string : memset;
535514 if (! fiberContext)
536515 {
@@ -577,11 +556,6 @@ void msvc_eh_init()
577556{
578557 throwInfoMutex = new Mutex ;
579558
580- // predefine CatchableTypes for C++ interop
581- ctCxxDThrowable = createCxxCatchableType(" .PAVException@D@@" );
582- ctCxxDException = createCxxCatchableType(" .PAVException@D@@" );
583- ctCxxDError = createCxxCatchableType(" .PAVException@D@@" );
584-
585559 // preallocate type descriptors likely to be needed
586560 getThrowInfo(typeid (Exception ));
587561 // better not have to allocate when this is thrown:
0 commit comments