Skip to content

Commit 7fee243

Browse files
committed
.
1 parent af8e829 commit 7fee243

File tree

3 files changed

+101
-97
lines changed

3 files changed

+101
-97
lines changed

src/library_exceptions.js

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
var LibraryExceptions = {
88
$uncaughtExceptionCount: '0',
9-
$exceptionLast: '0',
10-
$exceptionCaught: ' []',
119

1210
// This class is the exception metadata which is prepended to each thrown object (in WASM memory).
1311
// It is allocated in one block among with a thrown object in __cxa_allocate_exception and freed
@@ -111,30 +109,6 @@ var LibraryExceptions = {
111109
return type;
112110
},
113111

114-
// We're done with a catch. Now, we can run the destructor if there is one
115-
// and free the exception. Note that if the dynCall on the destructor fails
116-
// due to calling apply on undefined, that means that the destructor is
117-
// an invalid index into the FUNCTION_TABLE, so something has gone wrong.
118-
__cxa_end_catch__deps: ['$exceptionCaught', '$exceptionLast', '__cxa_decrement_exception_refcount',
119-
'$CatchInfo'],
120-
__cxa_end_catch__sig: 'v',
121-
__cxa_end_catch: function() {
122-
// Clear state flag.
123-
_setThrew(0);
124-
#if ASSERTIONS
125-
assert(exceptionCaught.length > 0);
126-
#endif
127-
// Call destructor if one is registered then clear it.
128-
var catchInfo = exceptionCaught.pop();
129-
130-
#if EXCEPTION_DEBUG
131-
err('cxa_end_catch popped ' + [catchInfo, exceptionLast, 'stack', exceptionCaught]);
132-
#endif
133-
___cxa_decrement_exception_refcount(catchInfo.get_base_ptr());
134-
catchInfo.free();
135-
exceptionLast = 0; // XXX in decRef?
136-
},
137-
138112
__cxa_get_exception_ptr__deps: ['$CatchInfo'],
139113
__cxa_get_exception_ptr: function(ptr) {
140114
#if EXCEPTION_DEBUG
@@ -179,57 +153,6 @@ var LibraryExceptions = {
179153
___cxa_rethrow();
180154
},
181155

182-
// Finds a suitable catch clause for when an exception is thrown.
183-
// In normal compilers, this functionality is handled by the C++
184-
// 'personality' routine. This is passed a fairly complex structure
185-
// relating to the context of the exception and makes judgements
186-
// about how to handle it. Some of it is about matching a suitable
187-
// catch clause, and some of it is about unwinding. We already handle
188-
// unwinding using 'if' blocks around each function, so the remaining
189-
// functionality boils down to picking a suitable 'catch' block.
190-
// We'll do that here, instead, to keep things simpler.
191-
__cxa_find_matching_catch__deps: ['$exceptionLast', '$ExceptionInfo', '$CatchInfo', '__resumeException', '__cxa_can_catch'],
192-
__cxa_find_matching_catch: function() {
193-
var thrown = exceptionLast;
194-
if (!thrown) {
195-
// just pass through the null ptr
196-
{{{ makeStructuralReturn([0, 0]) }}};
197-
}
198-
var info = new ExceptionInfo(thrown);
199-
var thrownType = info.get_type();
200-
var catchInfo = new CatchInfo();
201-
catchInfo.set_base_ptr(thrown);
202-
catchInfo.set_adjusted_ptr(thrown);
203-
if (!thrownType) {
204-
// just pass through the thrown ptr
205-
{{{ makeStructuralReturn(['catchInfo.ptr', 0]) }}};
206-
}
207-
var typeArray = Array.prototype.slice.call(arguments);
208-
209-
// can_catch receives a **, add indirection
210-
#if EXCEPTION_DEBUG
211-
out("can_catch on " + [thrown]);
212-
#endif
213-
// The different catch blocks are denoted by different types.
214-
// Due to inheritance, those types may not precisely match the
215-
// type of the thrown object. Find one which matches, and
216-
// return the type of the catch block which should be called.
217-
for (var i = 0; i < typeArray.length; i++) {
218-
var caughtType = typeArray[i];
219-
if (caughtType === 0 || caughtType === thrownType) {
220-
// Catch all clause matched or exactly the same type is caught
221-
break;
222-
}
223-
if ({{{ exportedAsmFunc('___cxa_can_catch') }}}(caughtType, thrownType, catchInfo.get_adjusted_ptr_addr())) {
224-
#if EXCEPTION_DEBUG
225-
out(" can_catch found " + [catchInfo.get_adjusted_ptr(), caughtType]);
226-
#endif
227-
{{{ makeStructuralReturn(['catchInfo.ptr', 'caughtType']) }}};
228-
}
229-
}
230-
{{{ makeStructuralReturn(['catchInfo.ptr', 'thrownType']) }}};
231-
},
232-
233156
__resumeException__deps: ['$exceptionLast', '$CatchInfo'],
234157
__resumeException: function(catchInfoPtr) {
235158
var catchInfo = new CatchInfo(catchInfoPtr);

system/lib/libcxxabi/src/cxa_exception_emscripten.cpp

Lines changed: 101 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
#include <cassert>
12
#include <cstring>
23
#include <cstdio>
4+
#include <vector>
35

46
#include "cxxabi.h"
5-
7+
#include "private_typeinfo.h"
68
#include "cxa_exception.h"
79
#include "include/atomic_support.h"
810

11+
extern "C" void setThrew(uintptr_t threw, int value);
12+
extern "C" void setTempRet0(uint32_t value);
13+
914
namespace __cxxabiv1 {
1015

1116
extern "C" {
@@ -67,46 +72,126 @@ struct __catch_info {
6772
void* adjustedPtr;
6873
};
6974

70-
static __cxa_exception* get_exception_info(__catch_info* info) {
71-
return (__cxa_exception*)info->basePtr;
75+
static __cxa_exception* get_cxa_exception(__catch_info* info) {
76+
return cxa_exception_from_thrown_object(info->basePtr);
77+
}
78+
79+
static int is_pointer_type(std::type_info* type) {
80+
return !!dynamic_cast<__pointer_type_info*>(type);
7281
}
7382

7483
// Get pointer which is expected to be received by catch clause in C++ code. It may be adjusted
7584
// when the pointer is casted to some of the exception object base classes (e.g. when virtual
7685
// inheritance is used). When a pointer is thrown this method should return the thrown pointer
7786
// itself.
78-
static void* get_thrown_object(__catch_info* info) {
79-
bool isPointer = ___cxa_is_pointer_type(get_exception_info(info)->exceptionType);
87+
static void* get_exception_ptr(__catch_info* info) {
88+
bool isPointer = is_pointer_type(get_cxa_exception(info)->exceptionType);
8089
if (isPointer) {
81-
return *this.basePtr;
90+
return info->basePtr;
8291
}
83-
void* adjusted = get_adjusted_ptr(info);
84-
if (adjusted) {
85-
return adjusted;
92+
if (info->adjustedPtr) {
93+
return &info->adjustedPtr;
8694
}
87-
return info.basePtr;
95+
return &info->basePtr;
8896
}
8997

9098
static int uncaughtExceptionCount;
9199
static std::vector<__catch_info*> exceptionCaught;
92100

93-
void* __cxa_begin_catch(void* unwind_arg) _NOEXCEPT
101+
void* __cxa_begin_catch(void* unwind_arg) _NOEXCEPT {
94102
__catch_info* info = (__catch_info*)unwind_arg;
95-
__cxa_exception* ex = get_exception_info(info);
96-
if (!ex->caught()) {
103+
__cxa_exception* ex = get_cxa_exception(info);
104+
if (!ex->caught) {
97105
ex->caught = true;
98106
uncaughtExceptionCount--;
99107
}
100-
info->rethrown = false;
108+
ex->rethrown = false;
101109
exceptionCaught.push_back(info);
102110
#if 0
103111
err('cxa_begin_catch ' + [ptr, 'stack', exceptionCaught]);
104112
#endif
105113
__cxa_increment_exception_refcount(info->basePtr);
106-
return get_thrown_object(info);
114+
return get_exception_ptr(info);
107115
}
108-
#endif
109116

117+
static void* exceptionLast;
118+
119+
// We're done with a catch. Now, we can run the destructor if there is one
120+
// and free the exception. Note that if the dynCall on the destructor fails
121+
// due to calling apply on undefined, that means that the destructor is
122+
// an invalid index into the FUNCTION_TABLE, so something has gone wrong.
123+
void __cxa_end_catch() {
124+
// Clear state flag.
125+
setThrew(0, 0);
126+
assert(exceptionCaught.size() > 0);
127+
// Call destructor if one is registered then clear it.
128+
__catch_info* catchInfo = exceptionCaught.back();
129+
exceptionCaught.pop_back();
130+
131+
//err('cxa_end_catch popped ' + [catchInfo, exceptionLast, 'stack', exceptionCaught]);
132+
__cxa_decrement_exception_refcount(catchInfo->basePtr);
133+
::free(catchInfo);
134+
exceptionLast = 0; // XXX in decRef?
110135
}
111136

137+
int __cxa_can_catch(std::type_info* catchType, std::type_info* excpType, void **thrown);
138+
139+
// Finds a suitable catch clause for when an exception is thrown.
140+
// In normal compilers, this functionality is handled by the C++
141+
// 'personality' routine. This is passed a fairly complex structure
142+
// relating to the context of the exception and makes judgements
143+
// about how to handle it. Some of it is about matching a suitable
144+
// catch clause, and some of it is about unwinding. We already handle
145+
// unwinding using 'if' blocks around each function, so the remaining
146+
// functionality boils down to picking a suitable 'catch' block.
147+
// We'll do that here, instead, to keep things simpler.
148+
void* __cxa_find_matching_catch_v(int count, ...) {
149+
void* thrown = exceptionLast;
150+
if (!thrown) {
151+
// just pass through the null ptr
152+
setTempRet0(0);
153+
return 0;
154+
}
155+
__cxa_exception* info = cxa_exception_from_thrown_object(thrown);
156+
std::type_info* thrownType = info->exceptionType;
157+
__catch_info CatchInfo{thrown, 0}
158+
if (!thrownType) {
159+
// just pass through the thrown ptr
160+
setTempRet0(0);
161+
return catchInfo.basePtr;
162+
}
163+
164+
// can_catch receives a **, add indirection
165+
//out("can_catch on " + [thrown]);
166+
void* exceptionThrown = 0;
167+
// The different catch blocks are denoted by different types.
168+
// Due to inheritance, those types may not precisely match the
169+
// type of the thrown object. Find one which matches, and
170+
// return the type of the catch block which should be called.
171+
va_list ap;
172+
va_start(ap, count);
173+
for (int i = 0; i < count; i++) {
174+
std::type_info* caughtType = va_arg(va_list ap, std::type_info*);
175+
if (caughtType === 0 || caughtType === thrownType) {
176+
// Catch all clause matched or exactly the same type is caught
177+
break;
178+
}
179+
if (__cxa_can_catch(caughtType, thrownType, &exceptionThrown) {
180+
if (thrown !== exceptionThrown) {
181+
catchInfo.set_adjusted_ptr(exceptionThrown);
182+
}
183+
//out(" can_catch found " + [adjusted, caughtType]);
184+
setTempRet0(caughtType);
185+
return makeStructuralReturn(catchInfo.basePtr);
186+
}
187+
}
188+
va_end(ap);
189+
setTempRet0(thrownType);
190+
return catchInfo.basePtr;
191+
},
192+
193+
#endif // __USING_EMSCRIPTEN_EXCEPTIONS__
194+
195+
} // extern "C"
196+
112197
} // abi

system/lib/libcxxabi/src/private_typeinfo.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,10 +1350,6 @@ int __cxa_can_catch(__shim_type_info* catchType, __shim_type_info* excpType, voi
13501350
return ret;
13511351
}
13521352

1353-
int __cxa_is_pointer_type(__shim_type_info* type) {
1354-
return !!dynamic_cast<__pointer_type_info*>(type);
1355-
}
1356-
13571353
}
13581354
#endif // !__USING_WASM_EXCEPTIONS__
13591355

0 commit comments

Comments
 (0)