var LibraryExceptions = {
#if !WASM_EXCEPTIONS
$uncaughtExceptionCount: '0',
$exceptionLast: '0',
$exceptionCaught: ' []',
$ExceptionInfo: class {
constructor(excPtr) {
this.excPtr = excPtr;
this.ptr = excPtr - {{{ C_STRUCTS.__cxa_exception.__size__ }}};
}
set_type(type) {
{{{ makeSetValue('this.ptr', C_STRUCTS.__cxa_exception.exceptionType, 'type', '*') }}};
}
get_type() {
return {{{ makeGetValue('this.ptr', C_STRUCTS.__cxa_exception.exceptionType, '*') }}};
}
set_destructor(destructor) {
{{{ makeSetValue('this.ptr', C_STRUCTS.__cxa_exception.exceptionDestructor, 'destructor', '*') }}};
}
get_destructor() {
return {{{ makeGetValue('this.ptr', C_STRUCTS.__cxa_exception.exceptionDestructor, '*') }}};
}
set_caught(caught) {
caught = caught ? 1 : 0;
{{{ makeSetValue('this.ptr', C_STRUCTS.__cxa_exception.caught, 'caught', 'i8') }}};
}
get_caught() {
return {{{ makeGetValue('this.ptr', C_STRUCTS.__cxa_exception.caught, 'i8') }}} != 0;
}
set_rethrown(rethrown) {
rethrown = rethrown ? 1 : 0;
{{{ makeSetValue('this.ptr', C_STRUCTS.__cxa_exception.rethrown, 'rethrown', 'i8') }}};
}
get_rethrown() {
return {{{ makeGetValue('this.ptr', C_STRUCTS.__cxa_exception.rethrown, 'i8') }}} != 0;
}
init(type, destructor) {
#if EXCEPTION_DEBUG
dbg('ExceptionInfo init: ' + [type, destructor]);
#endif
this.set_adjusted_ptr(0);
this.set_type(type);
this.set_destructor(destructor);
}
set_adjusted_ptr(adjustedPtr) {
{{{ makeSetValue('this.ptr', C_STRUCTS.__cxa_exception.adjustedPtr, 'adjustedPtr', '*') }}};
}
get_adjusted_ptr() {
return {{{ makeGetValue('this.ptr', C_STRUCTS.__cxa_exception.adjustedPtr, '*') }}};
}
},
__cxa_throw__deps: ['$ExceptionInfo', '$exceptionLast', '$uncaughtExceptionCount'],
__cxa_throw: (ptr, type, destructor) => {
#if EXCEPTION_DEBUG
dbg('__cxa_throw: ' + [ptrToString(ptr), type, ptrToString(destructor)]);
#endif
var info = new ExceptionInfo(ptr);
info.init(type, destructor);
{{{ storeException('exceptionLast', 'ptr') }}}
uncaughtExceptionCount++;
{{{ makeThrow('exceptionLast') }}}
},
__cxa_rethrow__deps: ['$exceptionCaught', '$exceptionLast', '$uncaughtExceptionCount'],
__cxa_rethrow: () => {
var info = exceptionCaught.pop();
if (!info) {
abort('no exception to throw');
}
var ptr = info.excPtr;
if (!info.get_rethrown()) {
exceptionCaught.push(info);
info.set_rethrown(true);
info.set_caught(false);
uncaughtExceptionCount++;
}
#if EXCEPTION_DEBUG
dbg('__cxa_rethrow, popped ' +
[ptrToString(ptr), exceptionLast, 'stack', exceptionCaught]);
#endif
{{{ storeException('exceptionLast', 'ptr') }}}
{{{ makeThrow('exceptionLast') }}}
},
llvm_eh_typeid_for: (type) => type,
__cxa_begin_catch__deps: ['$exceptionCaught', '__cxa_increment_exception_refcount',
'__cxa_get_exception_ptr',
'$uncaughtExceptionCount'],
__cxa_begin_catch: (ptr) => {
var info = new ExceptionInfo(ptr);
if (!info.get_caught()) {
info.set_caught(true);
uncaughtExceptionCount--;
}
info.set_rethrown(false);
exceptionCaught.push(info);
#if EXCEPTION_DEBUG
dbg('__cxa_begin_catch ' + [ptrToString(ptr), 'stack', exceptionCaught]);
#endif
___cxa_increment_exception_refcount(ptr);
return ___cxa_get_exception_ptr(ptr);
},
__cxa_end_catch__deps: ['$exceptionCaught', '$exceptionLast', '__cxa_decrement_exception_refcount', 'setThrew'],
__cxa_end_catch: () => {
_setThrew(0, 0);
#if ASSERTIONS
assert(exceptionCaught.length > 0);
#endif
var info = exceptionCaught.pop();
#if EXCEPTION_DEBUG
dbg('__cxa_end_catch popped ' + [info, exceptionLast, 'stack', exceptionCaught]);
#endif
___cxa_decrement_exception_refcount(info.excPtr);
exceptionLast = 0;
},
__cxa_uncaught_exceptions__deps: ['$uncaughtExceptionCount'],
__cxa_uncaught_exceptions: () => uncaughtExceptionCount,
__cxa_call_unexpected: (exception) => abort('Unexpected exception thrown, this is not properly supported - aborting'),
__cxa_current_primary_exception__deps: ['$exceptionCaught', '__cxa_increment_exception_refcount'],
__cxa_current_primary_exception: () => {
if (!exceptionCaught.length) {
return 0;
}
var info = exceptionCaught[exceptionCaught.length - 1];
___cxa_increment_exception_refcount(info.excPtr);
return info.excPtr;
},
__cxa_current_exception_type() {
if (!exceptionCaught.length) {
return 0;
}
var info = exceptionCaught[exceptionCaught.length - 1];
return info.get_type();
},
__cxa_rethrow_primary_exception__deps: ['$ExceptionInfo', '$exceptionCaught', '__cxa_rethrow'],
__cxa_rethrow_primary_exception: (ptr) => {
if (!ptr) return;
var info = new ExceptionInfo(ptr);
exceptionCaught.push(info);
info.set_rethrown(true);
___cxa_rethrow();
},
$findMatchingCatch__deps: ['$exceptionLast', '$ExceptionInfo', '__cxa_can_catch', '$setTempRet0'],
$findMatchingCatch: (args) => {
var thrown =
#if EXCEPTION_STACK_TRACES
exceptionLast?.excPtr;
#else
exceptionLast;
#endif
if (!thrown) {
setTempRet0(0);
return 0;
}
var info = new ExceptionInfo(thrown);
info.set_adjusted_ptr(thrown);
var thrownType = info.get_type();
if (!thrownType) {
setTempRet0(0);
return thrown;
}
#if EXCEPTION_DEBUG
dbg("findMatchingCatch on " + ptrToString(thrown));
#endif
for (var caughtType of args) {
if (caughtType === 0 || caughtType === thrownType) {
break;
}
var adjusted_ptr_addr = info.ptr + {{{ C_STRUCTS.__cxa_exception.adjustedPtr }}};
if (___cxa_can_catch(caughtType, thrownType, adjusted_ptr_addr)) {
#if EXCEPTION_DEBUG
dbg(" findMatchingCatch found " + [ptrToString(info.get_adjusted_ptr()), caughtType]);
#endif
setTempRet0(caughtType);
return thrown;
}
}
setTempRet0(thrownType);
return thrown;
},
__resumeException__deps: ['$exceptionLast'],
__resumeException: (ptr) => {
#if EXCEPTION_DEBUG
dbg("__resumeException " + [ptrToString(ptr), exceptionLast]);
#endif
if (!exceptionLast) {
{{{ storeException('exceptionLast', 'ptr') }}}
}
{{{ makeThrow('exceptionLast') }}}
},
#endif
#if WASM_EXCEPTIONS || !DISABLE_EXCEPTION_CATCHING
$getExceptionMessageCommon__deps: ['__get_exception_message', 'free', '$stackSave', '$stackRestore', '$stackAlloc'],
$getExceptionMessageCommon: (ptr) => {
var sp = stackSave();
var type_addr_addr = stackAlloc({{{ POINTER_SIZE }}});
var message_addr_addr = stackAlloc({{{ POINTER_SIZE }}});
___get_exception_message(ptr, type_addr_addr, message_addr_addr);
var type_addr = {{{ makeGetValue('type_addr_addr', 0, '*') }}};
var message_addr = {{{ makeGetValue('message_addr_addr', 0, '*') }}};
var type = UTF8ToString(type_addr);
_free(type_addr);
var message;
if (message_addr) {
message = UTF8ToString(message_addr);
_free(message_addr);
}
stackRestore(sp);
return [type, message];
},
#endif
#if WASM_EXCEPTIONS
$getCppExceptionTag__deps: ['__cpp_exception'],
$getCppExceptionTag: () => ___cpp_exception,
#if EXCEPTION_STACK_TRACES
__throw_exception_with_stack_trace__deps: ['$getCppExceptionTag', '$getExceptionMessage'],
__throw_exception_with_stack_trace: (ex) => {
var e = new WebAssembly.Exception(getCppExceptionTag(), [ex], {traceStack: true});
e.message = getExceptionMessage(e);
throw e;
},
#endif
$getCppExceptionThrownObjectFromWebAssemblyException__deps: ['$getCppExceptionTag', '__thrown_object_from_unwind_exception'],
$getCppExceptionThrownObjectFromWebAssemblyException: (ex) => {
var unwind_header = ex.getArg(getCppExceptionTag(), 0);
return ___thrown_object_from_unwind_exception(unwind_header);
},
$incrementExceptionRefcount__deps: ['__cxa_increment_exception_refcount', '$getCppExceptionThrownObjectFromWebAssemblyException'],
$incrementExceptionRefcount: (ex) => {
var ptr = getCppExceptionThrownObjectFromWebAssemblyException(ex);
___cxa_increment_exception_refcount(ptr);
},
$decrementExceptionRefcount__deps: ['__cxa_decrement_exception_refcount', '$getCppExceptionThrownObjectFromWebAssemblyException'],
$decrementExceptionRefcount: (ex) => {
var ptr = getCppExceptionThrownObjectFromWebAssemblyException(ex);
___cxa_decrement_exception_refcount(ptr);
},
$getExceptionMessage__deps: ['$getCppExceptionThrownObjectFromWebAssemblyException', '$getExceptionMessageCommon'],
$getExceptionMessage: (ex) => {
var ptr = getCppExceptionThrownObjectFromWebAssemblyException(ex);
return getExceptionMessageCommon(ptr);
},
#elif !DISABLE_EXCEPTION_CATCHING
$incrementExceptionRefcount__deps: ['__cxa_increment_exception_refcount'],
$incrementExceptionRefcount: (ptr) => ___cxa_increment_exception_refcount(ptr),
$decrementExceptionRefcount__deps: ['__cxa_decrement_exception_refcount'],
$decrementExceptionRefcount: (ptr) => ___cxa_decrement_exception_refcount(ptr),
$getExceptionMessage__deps: ['$getExceptionMessageCommon'],
$getExceptionMessage: (ptr) => getExceptionMessageCommon(ptr),
#endif
};
#if !WASM_EXCEPTIONS
addCxaCatch = (n) => {
const args = [];
let sig = 'p';
for (let i = 0; i < n - 2; i++) {
args.push(`arg${i}`);
sig += 'p';
}
const argString = args.join(',');
LibraryManager.library[`__cxa_find_matching_catch_${n}__sig`] = sig;
LibraryManager.library[`__cxa_find_matching_catch_${n}__deps`] = ['$findMatchingCatch'];
LibraryManager.library[`__cxa_find_matching_catch_${n}`] = eval(`(${args}) => findMatchingCatch([${argString}])`);
};
for (let i = 2; i < 5; i++) {
addCxaCatch(i)
}
#endif
addToLibrary(LibraryExceptions);