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; }
Runtime::ExecutionContext captureExecutionContext() { // Capture the current processor state. CONTEXT context; RtlCaptureContext(&context); // Unwind the stack. auto result = unwindStack(context); // Remove the top stack frame so the first entry is the caller of this function. result.stackFrames.erase(result.stackFrames.begin()); return result; }
Function::Function(Module& pModule, llvm::Function& function, const ArgInfo& argInfo, TemplateBuilder* pTemplateBuilder) : module_(pModule), function_(function), entryBuilder_(pModule.getLLVMContext()), builder_(pModule.getLLVMContext()), createdEntryBlock_(false), useEntryBuilder_(false), argInfo_(argInfo), templateBuilder_(pTemplateBuilder), #if LOCIC_LLVM_VERSION < 307 debugInfo_(nullptr), #endif exceptionInfo_(nullptr), returnValuePtr_(nullptr), templateArgs_(nullptr), unwindState_(nullptr) { assert(function.isDeclaration()); assert(argInfo_.numArguments() == function_.getFunctionType()->getNumParams()); // Add a bottom level unwind stack. unwindStackStack_.push(UnwindStack()); // Add bottom level action for this function. unwindStack().push_back(UnwindAction::FunctionMarker()); const auto startBB = createBasicBlock(""); builder_.SetInsertPoint(startBB); argValues_.reserve(function_.arg_size()); for (auto arg = function_.arg_begin(); arg != function_.arg_end(); ++arg) { argValues_.push_back(arg); } std::vector<llvm_abi::Type*> argABITypes; argABITypes.reserve(argInfo.argumentTypes().size()); std::vector<llvm::Type*> argLLVMTypes; argLLVMTypes.reserve(argInfo.argumentTypes().size()); for (const auto& typePair : argInfo.argumentTypes()) { argABITypes.push_back(typePair.first); argLLVMTypes.push_back(typePair.second); } SetUseEntryBuilder useEntryBuilder(*this); // Decode arguments according to ABI. decodeABIValues(argValues_, argABITypes, argLLVMTypes); }
void ExpressionCompiler<TScalar>::evaluateExpression( const ExpressionImplementationPtr& expressionPtr, const MatrixID<const TScalar>& parameterID, const MatrixID<TScalar>& resultID ) { // Save current stack state std::vector<StackEntry> stackEntries; stackEntries.swap(_stackEntries); // Descend into expression expressionPtr->evaluate(parameterID, resultID, *this); // Restore current stack state and store any stack-allocated matrix // indices back in stackEntries stackEntries.swap(_stackEntries); // Deallocate stack-allocated matrices unwindStack(stackEntries); }
void Function::pushUnwindStack(size_t position) { // Position needs to include top level function action. assert(position >= 1); unwindStackStack_.push(UnwindStack(unwindStack().begin(), unwindStack().begin() + position)); }