diff --git a/libraries/chain/include/eosio/chain/webassembly/wavm.hpp b/libraries/chain/include/eosio/chain/webassembly/wavm.hpp index f619e318b3f..23df2f04e08 100644 --- a/libraries/chain/include/eosio/chain/webassembly/wavm.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/wavm.hpp @@ -312,7 +312,12 @@ struct intrinsic_invoker_impl, std::tuple> { template static native_to_wasm_t invoke(Translated... translated) { - return convert_native_to_wasm(the_running_instance_context, Method(the_running_instance_context, translated...)); + try { + return convert_native_to_wasm(the_running_instance_context, Method(the_running_instance_context, translated...)); + } + catch(...) { + Platform::immediately_exit(std::current_exception()); + } } template @@ -331,7 +336,12 @@ struct intrinsic_invoker_impl, std::tuple template static void invoke(Translated... translated) { - Method(the_running_instance_context, translated...); + try { + Method(the_running_instance_context, translated...); + } + catch(...) { + Platform::immediately_exit(std::current_exception()); + } } template diff --git a/libraries/chain/webassembly/wavm.cpp b/libraries/chain/webassembly/wavm.cpp index e614398c74e..febd2ec8b07 100644 --- a/libraries/chain/webassembly/wavm.cpp +++ b/libraries/chain/webassembly/wavm.cpp @@ -131,7 +131,7 @@ void wavm_runtime::immediately_exit_currently_running_module() { #ifdef _WIN32 throw wasm_exit(); #else - Platform::immediately_exit(); + Platform::immediately_exit(nullptr); #endif } diff --git a/libraries/wasm-jit/Include/Platform/Platform.h b/libraries/wasm-jit/Include/Platform/Platform.h index 8d8769d4834..edaeef071d8 100644 --- a/libraries/wasm-jit/Include/Platform/Platform.h +++ b/libraries/wasm-jit/Include/Platform/Platform.h @@ -134,7 +134,7 @@ namespace Platform Uptr& outTrapOperand, const std::function& thunk ); - PLATFORM_API void immediately_exit(); + PLATFORM_API [[noreturn]] void immediately_exit(std::exception_ptr except); // // Threading diff --git a/libraries/wasm-jit/Source/Platform/POSIX.cpp b/libraries/wasm-jit/Source/Platform/POSIX.cpp index 4305381b39f..b6810e97480 100644 --- a/libraries/wasm-jit/Source/Platform/POSIX.cpp +++ b/libraries/wasm-jit/Source/Platform/POSIX.cpp @@ -176,6 +176,7 @@ namespace Platform THREAD_LOCAL Uptr* signalOperand = nullptr; THREAD_LOCAL bool isReentrantSignal = false; THREAD_LOCAL bool isCatchingSignals = false; + thread_local std::exception_ptr thrown_exception; void signalHandler(int signalNumber,siginfo_t* signalInfo,void*) { @@ -252,6 +253,7 @@ namespace Platform jmp_buf oldSignalReturnEnv; memcpy(&oldSignalReturnEnv,&signalReturnEnv,sizeof(jmp_buf)); const bool oldIsCatchingSignals = isCatchingSignals; + thrown_exception = nullptr; // Use setjmp to allow signals to jump back to this point. bool isReturningFromSignalHandler = sigsetjmp(signalReturnEnv,1); @@ -273,10 +275,14 @@ namespace Platform signalCallStack = nullptr; signalOperand = nullptr; + if(thrown_exception) + std::rethrow_exception(thrown_exception); + return signalType; } - void immediately_exit() { + void immediately_exit(std::exception_ptr except) { + thrown_exception = except; siglongjmp(signalReturnEnv,1); } diff --git a/libraries/wasm-jit/Source/Platform/Windows.cpp b/libraries/wasm-jit/Source/Platform/Windows.cpp index bc3c30fc46a..2c34c613b64 100644 --- a/libraries/wasm-jit/Source/Platform/Windows.cpp +++ b/libraries/wasm-jit/Source/Platform/Windows.cpp @@ -359,6 +359,10 @@ namespace Platform { errorUnless(SetEvent(reinterpret_cast(event))); } + + void immediately_exit(std::exception_ptr except) { + std::rethrow_exception(except); + } } #endif diff --git a/libraries/wasm-jit/Source/Runtime/LLVMJIT.cpp b/libraries/wasm-jit/Source/Runtime/LLVMJIT.cpp index ba5354c5d22..98fbe2fac9e 100644 --- a/libraries/wasm-jit/Source/Runtime/LLVMJIT.cpp +++ b/libraries/wasm-jit/Source/Runtime/LLVMJIT.cpp @@ -112,15 +112,9 @@ namespace LLVMJIT void registerEHFrames(U8* addr, U64 loadAddr,uintptr_t numBytes) override { - llvm::RTDyldMemoryManager::registerEHFrames(addr,loadAddr,numBytes); - hasRegisteredEHFrames = true; - ehFramesAddr = addr; - ehFramesLoadAddr = loadAddr; - ehFramesNumBytes = numBytes; } void deregisterEHFrames(U8* addr, U64 loadAddr,uintptr_t numBytes) override { - llvm::RTDyldMemoryManager::deregisterEHFrames(addr,loadAddr,numBytes); } virtual bool needsToReserveAllocationSpace() override { return true; } diff --git a/libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp b/libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp index a8d1fe80c71..9e38eeebea0 100644 --- a/libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp +++ b/libraries/wasm-jit/Source/Runtime/WAVMIntrinsics.cpp @@ -8,6 +8,16 @@ namespace Runtime { + static void causeIntrensicException(Exception::Cause cause) { + try { + Platform::immediately_exit(std::make_exception_ptr(Exception{cause, std::vector()})); + } + catch (...) { + Platform::immediately_exit(std::current_exception()); + } + __builtin_unreachable(); + } + template Float quietNaN(Float value) { @@ -104,11 +114,11 @@ namespace Runtime { if(sourceValue != sourceValue) { - causeException(Exception::Cause::invalidFloatOperation); + causeIntrensicException(Exception::Cause::invalidFloatOperation); } else if(sourceValue >= maxValue || (isMinInclusive ? sourceValue <= minValue : sourceValue < minValue)) { - causeException(Exception::Cause::integerDivideByZeroOrIntegerOverflow); + causeIntrensicException(Exception::Cause::integerDivideByZeroOrIntegerOverflow); } return (Dest)sourceValue; } @@ -125,45 +135,51 @@ namespace Runtime DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,divideByZeroOrIntegerOverflowTrap,divideByZeroOrIntegerOverflowTrap,none) { - causeException(Exception::Cause::integerDivideByZeroOrIntegerOverflow); + causeIntrensicException(Exception::Cause::integerDivideByZeroOrIntegerOverflow); } DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,unreachableTrap,unreachableTrap,none) { - causeException(Exception::Cause::reachedUnreachable); + causeIntrensicException(Exception::Cause::reachedUnreachable); } DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,accessViolationTrap,accessViolationTrap,none) { - causeException(Exception::Cause::accessViolation); + causeIntrensicException(Exception::Cause::accessViolation); } DEFINE_INTRINSIC_FUNCTION3(wavmIntrinsics,indirectCallSignatureMismatch,indirectCallSignatureMismatch,none,i32,index,i64,expectedSignatureBits,i64,tableBits) { - TableInstance* table = reinterpret_cast(tableBits); - void* elementValue = table->baseAddress[index].value; - const FunctionType* actualSignature = table->baseAddress[index].type; - const FunctionType* expectedSignature = reinterpret_cast((Uptr)expectedSignatureBits); - std::string ipDescription = ""; - LLVMJIT::describeInstructionPointer(reinterpret_cast(elementValue),ipDescription); - Log::printf(Log::Category::debug,"call_indirect signature mismatch: expected %s at index %u but got %s (%s)\n", - asString(expectedSignature).c_str(), - index, - actualSignature ? asString(actualSignature).c_str() : "nullptr", - ipDescription.c_str() - ); - causeException(elementValue == nullptr ? Exception::Cause::undefinedTableElement : Exception::Cause::indirectCallSignatureMismatch); + try { + TableInstance* table = reinterpret_cast(tableBits); + void* elementValue = table->baseAddress[index].value; + const FunctionType* actualSignature = table->baseAddress[index].type; + const FunctionType* expectedSignature = reinterpret_cast((Uptr)expectedSignatureBits); + std::string ipDescription = ""; + LLVMJIT::describeInstructionPointer(reinterpret_cast(elementValue),ipDescription); + Log::printf(Log::Category::debug,"call_indirect signature mismatch: expected %s at index %u but got %s (%s)\n", + asString(expectedSignature).c_str(), + index, + actualSignature ? asString(actualSignature).c_str() : "nullptr", + ipDescription.c_str() + ); + causeIntrensicException(elementValue == nullptr ? Exception::Cause::undefinedTableElement : Exception::Cause::indirectCallSignatureMismatch); + } + catch (...) { + Platform::immediately_exit(std::current_exception()); + } } DEFINE_INTRINSIC_FUNCTION0(wavmIntrinsics,indirectCallIndexOutOfBounds,indirectCallIndexOutOfBounds,none) { - causeException(Exception::Cause::undefinedTableElement); + causeIntrensicException(Exception::Cause::undefinedTableElement); } DEFINE_INTRINSIC_FUNCTION2(wavmIntrinsics,_growMemory,growMemory,i32,i32,deltaPages,i64,memoryBits) { MemoryInstance* memory = reinterpret_cast(memoryBits); - WAVM_ASSERT_THROW(memory); + if(!memory) + causeIntrensicException(Exception::Cause::outOfMemory); const Iptr numPreviousMemoryPages = growMemory(memory,(Uptr)deltaPages); if(numPreviousMemoryPages + (Uptr)deltaPages > IR::maxMemoryPages) { return -1; } else { return (I32)numPreviousMemoryPages; } @@ -172,7 +188,8 @@ namespace Runtime DEFINE_INTRINSIC_FUNCTION1(wavmIntrinsics,_currentMemory,currentMemory,i32,i64,memoryBits) { MemoryInstance* memory = reinterpret_cast(memoryBits); - WAVM_ASSERT_THROW(memory); + if(!memory) + causeIntrensicException(Exception::Cause::outOfMemory); Uptr numMemoryPages = getMemoryNumPages(memory); if(numMemoryPages > UINT32_MAX) { numMemoryPages = UINT32_MAX; } return (U32)numMemoryPages;