| |
| |
| |
| |
| |
|
|
| var LibraryExceptions = { |
| #if !WASM_EXCEPTIONS |
| $uncaughtExceptionCount: '0', |
| #if !DISABLE_EXCEPTION_CATCHING |
| $exceptionLast: null, |
| #endif |
| $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', '$uncaughtExceptionCount', |
| #if !DISABLE_EXCEPTION_CATCHING |
| '$exceptionLast', |
| '__cxa_increment_exception_refcount', |
| #endif |
| #if EXCEPTION_STACK_TRACES |
| |
| |
| |
| '$getExceptionMessage', |
| |
| |
| |
| '$decrementExceptionRefcount', '$incrementExceptionRefcount', |
| #endif |
| ], |
| __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); |
| #if !DISABLE_EXCEPTION_CATCHING |
| ___cxa_increment_exception_refcount(ptr); |
| exceptionLast = new CppException(ptr); |
| #endif |
| uncaughtExceptionCount++; |
| {{{ makeThrow() }}} |
| }, |
|
|
| |
| |
| |
| __cxa_rethrow__deps: ['$exceptionCaught', '$uncaughtExceptionCount', |
| #if !DISABLE_EXCEPTION_CATCHING |
| '$exceptionLast', |
| '__cxa_increment_exception_refcount', |
| #endif |
| ], |
| __cxa_rethrow: () => { |
| if (!exceptionCaught.length) { |
| abort('no exception to throw'); |
| } |
| var info = exceptionCaught.at(-1); |
| var ptr = info.excPtr; |
| info.set_rethrown(true); |
| info.set_caught(false); |
| uncaughtExceptionCount++; |
| #if !DISABLE_EXCEPTION_CATCHING |
| ___cxa_increment_exception_refcount(ptr); |
| #if EXCEPTION_DEBUG |
| dbg('__cxa_rethrow: ' + |
| [ptrToString(ptr), exceptionLast, 'stack', exceptionCaught]); |
| #endif |
| exceptionLast = new CppException(ptr); |
| #endif |
| {{{ makeThrow() }}} |
| }, |
|
|
| llvm_eh_typeid_for: (type) => type, |
|
|
| __cxa_begin_catch__deps: ['$exceptionCaught', '__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 |
| return ___cxa_get_exception_ptr(ptr); |
| }, |
|
|
| |
| |
| |
| |
| __cxa_end_catch__deps: ['$exceptionCaught', '__cxa_decrement_exception_refcount', 'setThrew', |
| #if !DISABLE_EXCEPTION_CATCHING |
| '$exceptionLast', |
| #endif |
| ], |
| __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, 'stack', exceptionCaught]); |
| #endif |
| ___cxa_decrement_exception_refcount(info.excPtr); |
| #if !DISABLE_EXCEPTION_CATCHING |
| exceptionLast = null; |
| #endif |
| }, |
|
|
| __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', '$uncaughtExceptionCount', |
| #if !DISABLE_EXCEPTION_CATCHING |
| '$exceptionLast', |
| '__cxa_increment_exception_refcount', |
| #endif |
| ], |
| __cxa_rethrow_primary_exception: (ptr) => { |
| if (!ptr) return; |
| #if EXCEPTION_DEBUG |
| dbg('__cxa_rethrow_primary_exception: ' + ptrToString(ptr)); |
| #endif |
| var info = new ExceptionInfo(ptr); |
| info.set_rethrown(true); |
| info.set_caught(false); |
| uncaughtExceptionCount++; |
| #if !DISABLE_EXCEPTION_CATCHING |
| ___cxa_increment_exception_refcount(ptr); |
| exceptionLast = new CppException(ptr); |
| #endif |
| {{{ makeThrow('exceptionLast') }}} |
| }, |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #if !DISABLE_EXCEPTION_CATCHING |
| $findMatchingCatch__deps: ['$exceptionLast', '$ExceptionInfo', '__cxa_can_catch', '$setTempRet0'], |
| #endif |
| $findMatchingCatch: (args) => { |
| #if DISABLE_EXCEPTION_CATCHING |
| setTempRet0(0); |
| return 0; |
| #else |
| var thrown = exceptionLast?.excPtr; |
| 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; |
| #endif |
| }, |
|
|
| #if !DISABLE_EXCEPTION_CATCHING |
| __resumeException__deps: ['$exceptionLast'], |
| #endif |
| __resumeException: (ptr) => { |
| #if !DISABLE_EXCEPTION_CATCHING |
| #if EXCEPTION_DEBUG |
| dbg("__resumeException " + [ptrToString(ptr), exceptionLast]); |
| #endif |
| if (!exceptionLast) { |
| exceptionLast = new CppException(ptr); |
| } |
| #endif |
| {{{ makeThrow() }}} |
| }, |
|
|
| #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', |
| |
| |
| |
| '$decrementExceptionRefcount', '$incrementExceptionRefcount'], |
| __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); |
| }, |
|
|
| $incrementUncaughtExceptionCount__deps: ['__increment_uncaught_exception'], |
| $incrementUncaughtExceptionCount: '__increment_uncaught_exception', |
|
|
| $decrementUncaughtExceptionCount__deps: ['__decrement_uncaught_exception'], |
| $decrementUncaughtExceptionCount: '__decrement_uncaught_exception', |
|
|
| $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); |
| }, |
|
|
| #else |
| #if !DISABLE_EXCEPTION_THROWING |
| $incrementUncaughtExceptionCount__deps: ['$uncaughtExceptionCount'], |
| $incrementUncaughtExceptionCount: () => { |
| uncaughtExceptionCount++; |
| }, |
|
|
| $decrementUncaughtExceptionCount__deps: ['$uncaughtExceptionCount'], |
| $decrementUncaughtExceptionCount: () => { |
| uncaughtExceptionCount--; |
| }, |
| #endif |
|
|
| #if !DISABLE_EXCEPTION_CATCHING |
| $incrementExceptionRefcount__deps: ['__cxa_increment_exception_refcount'], |
| $incrementExceptionRefcount: (exn) => ___cxa_increment_exception_refcount(exn.excPtr), |
|
|
| $decrementExceptionRefcount__deps: ['__cxa_decrement_exception_refcount'], |
| $decrementExceptionRefcount: (exn) => ___cxa_decrement_exception_refcount(exn.excPtr), |
|
|
| $getExceptionMessage__deps: ['$getExceptionMessageCommon'], |
| $getExceptionMessage: (exn) => getExceptionMessageCommon(exn.excPtr), |
|
|
| #endif |
| #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); |
|
|