Fix SEH and USING: errors on windows nt

release
U-3ADF\Administrator 2007-09-25 10:37:45 +02:00
parent 4b7bc7ef6d
commit 544c2370cf
5 changed files with 55 additions and 45 deletions

View File

@ -1,7 +1,8 @@
USING: alien alien.c-types arrays assocs combinators continuations
destructors io io.backend io.nonblocking io.windows libc
kernel math namespaces sequences threads tuples.lib windows
windows.errors windows.kernel32 prettyprint ;
windows.errors windows.kernel32 prettyprint strings splitting
io.files windows.winsock ;
IN: io.windows.nt.backend
: unicode-prefix ( -- seq )

View File

@ -23,40 +23,53 @@ DEFINE_PRIMITIVE(cd)
SetCurrentDirectory(unbox_u16_string());
}
long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch)
long exception_handler(PEXCEPTION_POINTERS pe)
{
CONTEXT *c = (CONTEXT*)ctx;
void *esp = NULL;
PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord;
CONTEXT *c = (CONTEXT*)pe->ContextRecord;
void *signal_callstack_top = NULL;
if(in_code_heap_p(c->Eip))
esp = (void*)c->Esp;
printf("ExceptionCode = 0x%08x\n", rec->ExceptionCode);
printf("AccessViolationCode = 0x%08x\n", EXCEPTION_ACCESS_VIOLATION);
printf("DivideByZeroCode1 = 0x%08x\n", EXCEPTION_FLT_DIVIDE_BY_ZERO);
printf("DivideByZeroCode2 = 0x%08x\n", EXCEPTION_INT_DIVIDE_BY_ZERO);
printf("addr=0x%08x\n", rec->ExceptionInformation[1]);
printf("eax=0x%08x\n", c->Eax);
printf("eax=0x%08x\n", c->Ebx);
printf("eip=0x%08x\n", c->Eip);
printf("esp=0x%08x\n", c->Esp);
signal_callstack_top = (void*)c->Esp;
printf("calculated esp: 0x%08x\n", esp);
if(rec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
memory_protection_error(rec->ExceptionInformation[1], esp);
else if(rec->ExceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO
|| rec->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
general_error(ERROR_DIVIDE_BY_ZERO,F,F,esp);
if(e->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
{
signal_fault_addr = e->ExceptionInformation[1];
c->Eip = (CELL)memory_signal_handler_impl;
}
else if(e->ExceptionCode == EXCEPTION_FLT_DIVIDE_BY_ZERO
|| e->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
{
signal_number = ERROR_DIVIDE_BY_ZERO;
c->Eip = (CELL)divide_by_zero_signal_handler_impl;
}
else
signal_error(11,esp);
return -1; /* unreachable */
{
signal_number = 11;
c->Eip = (CELL)misc_signal_handler_impl;
}
return EXCEPTION_CONTINUE_EXECUTION;
}
void c_to_factor_toplevel(CELL quot)
{
exception_record_t record;
asm volatile("mov %%fs:0, %0" : "=r" (record.next_handler));
asm volatile("mov %0, %%fs:0" : : "r" (&record));
record.handler_func = exception_handler;
AddVectoredExceptionHandler(0, (void*)exception_handler);
c_to_factor(quot);
asm volatile("mov %0, %%fs:0" : "=r" (record.next_handler));
RemoveVectoredExceptionHandler((void*)exception_handler);
}
void memory_signal_handler_impl(void)
{
memory_protection_error(signal_fault_addr,signal_callstack_top);
}
void divide_by_zero_signal_handler_impl(void)
{
general_error(ERROR_DIVIDE_BY_ZERO,F,F,signal_callstack_top);
}
void misc_signal_handler_impl(void)
{
signal_error(signal_number,signal_callstack_top);
}

View File

@ -1,3 +1,6 @@
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 // For AddVectoredExceptionHandler
#ifndef UNICODE
#define UNICODE
#endif
@ -10,3 +13,11 @@ typedef char F_SYMBOL;
#define FACTOR_OS_STRING "windows"
#define FACTOR_DLL L"factor-nt.dll"
#define FACTOR_DLL_NAME "factor-nt.dll"
CELL signal_number;
CELL signal_fault_addr;
void *signal_callstack_top;
void memory_signal_handler_impl(void);
void divide_by_zero_signal_handler_impl(void);
void misc_signal_handler_impl(void);

View File

@ -52,7 +52,7 @@ void ffi_dlopen (F_DLL *dll, bool error)
dll->dll = NULL;
if(error)
general_error(ERROR_FFI,F,F,
tag_object(get_error_message()));
(void*)tag_object(get_error_message()));
else
return;
}

View File

@ -49,20 +49,5 @@ s64 current_millis(void);
INLINE void reset_stdio(void) {}
/* SEH support. Proceed with caution. */
typedef long exception_handler_t(
PEXCEPTION_RECORD rec, void *frame, void *context, void *dispatch);
long exception_handler(PEXCEPTION_POINTERS pe);
typedef struct exception_record
{
struct exception_record *next_handler;
void *handler_func;
} exception_record_t;
long exception_handler(PEXCEPTION_RECORD rec, void *frame, void *ctx, void *dispatch);
DECLARE_PRIMITIVE(open_file);
DECLARE_PRIMITIVE(stat);
DECLARE_PRIMITIVE(read_dir);
DECLARE_PRIMITIVE(cwd);
DECLARE_PRIMITIVE(cd);