diff --git a/src/compile.cpp b/src/compile.cpp index aba84fc611..9df75d6330 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -75,23 +75,21 @@ resolveTarget(MyThread* t, void* stack, object method) if (method and methodVirtual(t, method)) { unsigned parameterFootprint = methodParameterFootprint(t, method); - if (reinterpret_cast(stack)[parameterFootprint]) { - object class_ = objectClass - (t, reinterpret_cast(stack)[parameterFootprint]); + object class_ = objectClass + (t, reinterpret_cast(stack)[parameterFootprint]); - if (classVmFlags(t, class_) & BootstrapFlag) { - PROTECT(t, method); - PROTECT(t, class_); + if (classVmFlags(t, class_) & BootstrapFlag) { + PROTECT(t, method); + PROTECT(t, class_); - resolveClass(t, className(t, class_)); - if (UNLIKELY(t->exception)) return 0; - } + resolveClass(t, className(t, class_)); + if (UNLIKELY(t->exception)) return 0; + } - if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) { - return findInterfaceMethod(t, method, class_); - } else { - return findMethod(t, method, class_); - } + if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) { + return findInterfaceMethod(t, method, class_); + } else { + return findMethod(t, method, class_); } } @@ -2512,7 +2510,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) c->indirectCall (c->constant (reinterpret_cast(findInterfaceMethodFromInstance)), - frame->trace(target, true), + frame->trace(0, false), 3, c->thread(), frame->append(target), c->stack(frame->stack, instance)); @@ -3999,7 +3997,7 @@ class SegFaultHandler: public System::SignalHandler { public: SegFaultHandler(): m(0) { } - virtual bool handleSignal(void* ip, void* base, void* stack) { + virtual void handleSignal(void* ip, void* base, void* stack) { MyThread* t = static_cast(m->localThread->get()); object node = findTraceNode(t, ip); if (node) { @@ -4008,8 +4006,6 @@ class SegFaultHandler: public System::SignalHandler { t->stack = stack; t->exception = makeNullPointerException(t); unwind(t); - } else { - return false; } } diff --git a/src/posix.cpp b/src/posix.cpp index 4873cf2b25..d4ec599d6b 100644 --- a/src/posix.cpp +++ b/src/posix.cpp @@ -64,19 +64,17 @@ handleSignal(int signal, siginfo_t* info, void* context) greg_t* registers = static_cast(context)->uc_mcontext.gregs; - bool handled = segFaultHandler->handleSignal + segFaultHandler->handleSignal (reinterpret_cast(registers[IpRegister]), reinterpret_cast(registers[BaseRegister]), reinterpret_cast(registers[StackRegister])); - if (not handled) { - if (oldSegFaultHandler.sa_flags & SA_SIGINFO) { - oldSegFaultHandler.sa_sigaction(signal, info, context); - } else if (oldSegFaultHandler.sa_handler) { - oldSegFaultHandler.sa_handler(signal); - } else { - abort(); - } + if (oldSegFaultHandler.sa_flags & SA_SIGINFO) { + oldSegFaultHandler.sa_sigaction(signal, info, context); + } else if (oldSegFaultHandler.sa_handler) { + oldSegFaultHandler.sa_handler(signal); + } else { + abort(); } } } @@ -532,6 +530,7 @@ class MySystem: public System { return sigaction(SIGSEGV, &sa, &oldSegFaultHandler); } else if (segFaultHandler) { + segFaultHandler = 0; return sigaction(SIGSEGV, &oldSegFaultHandler, 0); } else { return 1; diff --git a/src/system.h b/src/system.h index f03d20d86a..cf13134b13 100644 --- a/src/system.h +++ b/src/system.h @@ -84,7 +84,7 @@ class System: public Allocator { public: virtual ~SignalHandler() { } - virtual bool handleSignal(void* ip, void* base, void* stack) = 0; + virtual void handleSignal(void* ip, void* base, void* stack) = 0; }; virtual ~System() { } diff --git a/src/windows.cpp b/src/windows.cpp index 59c819eb87..edafa31d54 100644 --- a/src/windows.cpp +++ b/src/windows.cpp @@ -13,6 +13,21 @@ using namespace vm; namespace { +System::SignalHandler* segFaultHandler = 0; +LPTOP_LEVEL_EXCEPTION_FILTER oldSegFaultHandler = 0; + +LONG CALLBACK +handleException(LPEXCEPTION_POINTERS e) +{ + if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { + segFaultHandler->handleSignal + (reinterpret_cast(e->ContextRecord->Eip), + reinterpret_cast(e->ContextRecord->Ebp), + reinterpret_cast(e->ContextRecord->Esp)); + } + return EXCEPTION_CONTINUE_SEARCH; +} + class MutexResource { public: MutexResource(System* s, HANDLE m): s(s), m(m) { @@ -500,6 +515,21 @@ class MySystem: public System { return 0; } + virtual Status handleSegFault(SignalHandler* handler) { + if (handler) { + segFaultHandler = handler; + + oldSegFaultHandler = SetUnhandledExceptionFilter(handleException); + return 0; + } else if (segFaultHandler) { + segFaultHandler = 0; + SetUnhandledExceptionFilter(oldSegFaultHandler); + return 0; + } else { + return 1; + } + } + virtual uint64_t call(void* function, uintptr_t* arguments, uint8_t* types, unsigned count, unsigned size, unsigned returnType) {