forked from ldc-developers/druntime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gnu.d
78 lines (62 loc) · 2.33 KB
/
gnu.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* This module implements ...
*/
module ldc.eh.cpp.gnu;
modmap (C++) "unwind-cxx.h";
import ldc.eh.common;
import ldc.eh.libunwind;
import (C++) __cxxabiv1._;
import (C++) __cxxabiv1.__cxa_exception;
import (C++) _Unwind_Exception : _cpp__Unwind_Exception = _Unwind_Exception;
import (C++) std.type_info;
class CppHandler : ForeignHandler
{
__cxa_exception *_cpp_exception;
_Unwind_Context_Ptr context;
this(_cpp__Unwind_Exception *e, _Unwind_Context_Ptr context)
{
this._cpp_exception = __get_exception_header_from_ue(e);
this.context = context;
}
void *getException()
{
return &_cpp_exception.unwindHeader;
}
type_info *getCatchTypeInfo(void* address, ubyte encoding)
{
size_t catchTypeInfoWrapAddr;
get_encoded_value(cast(ubyte*) address, catchTypeInfoWrapAddr, encoding, context);
auto a = cast(__cpp_type_info_ptr)cast(Object)cast(void*)catchTypeInfoWrapAddr;
return a ? cast(type_info*)a.p : null;
}
bool doCatch(void* address, ubyte encoding)
{
void *__thr_obj = __get_object_from_ue(&_cpp_exception.unwindHeader);
// Pointer types need to adjust the actual pointer, not the pointer to pointer that is the exception object.
// This also has the effect of passing pointer types "by value" through the __cxa_begin_catch return value.
if (_cpp_exception.exceptionType.__is_pointer_p())
__thr_obj = *cast(void **) __thr_obj;
auto catchTypeInfo = getCatchTypeInfo(address, encoding);
if (catchTypeInfo && catchTypeInfo.__do_catch(_cpp_exception.exceptionType, & __thr_obj, 1))
{
_cpp_exception.adjustedPtr = __thr_obj; // NOTE: __cxa_begin_catch returns adjustedPtr, which in C++ EH is set by __gxx_personality_v0 if the search phase is successful
return true;
}
return false;
}
}
class CppHandlerFactory : ForeignHandlerFactory
{
bool doHandleExceptionClass(ulong exception_class) shared
{
return __is_gxx_exception_class(exception_class);
}
ForeignHandler create(_Unwind_Context_Ptr context, _Unwind_Exception* exception_info) shared
{
return new CppHandler(cast(_cpp__Unwind_Exception*) exception_info, context);
}
}
shared static this()
{
foreignHandlerFactories ~= new CppHandlerFactory;
}