LONG CALLBACK sehFilterFunction(EXCEPTION_POINTERS* exceptionPointers,Exception*& outRuntimeException) { // Detect a WAVM runtime exception and just pull the the Exception pointer out for the handler. if(exceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_WAVM_RUNTIME) { outRuntimeException = reinterpret_cast<Exception*>(exceptionPointers->ExceptionRecord->ExceptionInformation[0]); } else { // Interpret the cause of the exception. Exception::Cause cause; switch(exceptionPointers->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: cause = Exception::Cause::AccessViolation; break; case EXCEPTION_STACK_OVERFLOW: cause = Exception::Cause::StackOverflow; break; case EXCEPTION_INT_DIVIDE_BY_ZERO: cause = Exception::Cause::IntegerDivideByZeroOrIntegerOverflow; break; case EXCEPTION_INT_OVERFLOW: cause = Exception::Cause::IntegerDivideByZeroOrIntegerOverflow; break; default: cause = Exception::Cause::Unknown; break; } // Unwind the stack frames from the context of the exception. auto executionContext = unwindStack(*exceptionPointers->ContextRecord); // Describe the exception's call stack. outRuntimeException = new Exception {cause,describeExecutionContext(executionContext)}; } return EXCEPTION_EXECUTE_HANDLER; }
void causeException(Exception::Cause cause) { auto callStack = describeExecutionContext(RuntimePlatform::captureExecutionContext()); RuntimePlatform::raiseException(new Exception {cause,callStack}); }