Send FP trap signals to Factor as a different vm-error type

db4
Joe Groff 2009-09-06 08:44:25 -05:00
parent 96db254311
commit 7ba71a524e
8 changed files with 50 additions and 10 deletions

View File

@ -124,11 +124,14 @@ HOOK: signal-error. os ( obj -- )
: primitive-error. ( error -- ) : primitive-error. ( error -- )
"Unimplemented primitive" print drop ; "Unimplemented primitive" print drop ;
: fp-trap-error. ( error -- )
"Floating point trap" print drop ;
PREDICATE: vm-error < array PREDICATE: vm-error < array
{ {
{ [ dup empty? ] [ drop f ] } { [ dup empty? ] [ drop f ] }
{ [ dup first "kernel-error" = not ] [ drop f ] } { [ dup first "kernel-error" = not ] [ drop f ] }
[ second 0 15 between? ] [ second 0 16 between? ]
} cond ; } cond ;
: vm-errors ( error -- n errors ) : vm-errors ( error -- n errors )
@ -149,6 +152,7 @@ PREDICATE: vm-error < array
{ 13 [ retainstack-underflow. ] } { 13 [ retainstack-underflow. ] }
{ 14 [ retainstack-overflow. ] } { 14 [ retainstack-overflow. ] }
{ 15 [ memory-error. ] } { 15 [ memory-error. ] }
{ 16 [ fp-trap-error. ] }
} ; inline } ; inline
M: vm-error summary drop "VM error" ; M: vm-error summary drop "VM error" ;

View File

@ -130,6 +130,11 @@ void divide_by_zero_error()
general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL); general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
} }
void fp_trap_error()
{
general_error(ERROR_FP_TRAP,F,F,NULL);
}
PRIMITIVE(call_clear) PRIMITIVE(call_clear)
{ {
throw_impl(dpop(),stack_chain->callstack_bottom); throw_impl(dpop(),stack_chain->callstack_bottom);
@ -151,4 +156,9 @@ void misc_signal_handler_impl()
signal_error(signal_number,signal_callstack_top); signal_error(signal_number,signal_callstack_top);
} }
void fp_signal_handler_impl()
{
fp_trap_error();
}
} }

View File

@ -20,6 +20,7 @@ enum vm_error_type
ERROR_RS_UNDERFLOW, ERROR_RS_UNDERFLOW,
ERROR_RS_OVERFLOW, ERROR_RS_OVERFLOW,
ERROR_MEMORY, ERROR_MEMORY,
ERROR_FP_TRAP,
}; };
void out_of_memory(); void out_of_memory();
@ -35,6 +36,7 @@ void memory_protection_error(cell addr, stack_frame *native_stack);
void signal_error(int signal, stack_frame *native_stack); void signal_error(int signal, stack_frame *native_stack);
void type_error(cell type, cell tagged); void type_error(cell type, cell tagged);
void not_implemented_error(); void not_implemented_error();
void fp_trap_error();
PRIMITIVE(call_clear); PRIMITIVE(call_clear);
PRIMITIVE(unimplemented); PRIMITIVE(unimplemented);
@ -46,6 +48,7 @@ extern cell signal_fault_addr;
extern stack_frame *signal_callstack_top; extern stack_frame *signal_callstack_top;
void memory_signal_handler_impl(); void memory_signal_handler_impl();
void fp_signal_handler_impl();
void misc_signal_handler_impl(); void misc_signal_handler_impl();
} }

View File

@ -28,7 +28,9 @@ http://www.wodeveloper.com/omniLists/macosx-dev/2000/June/msg00137.html */
/* Modify a suspended thread's thread_state so that when the thread resumes /* Modify a suspended thread's thread_state so that when the thread resumes
executing, the call frame of the current C primitive (if any) is rewound, and executing, the call frame of the current C primitive (if any) is rewound, and
the appropriate Factor error is thrown from the top-most Factor frame. */ the appropriate Factor error is thrown from the top-most Factor frame. */
static void call_fault_handler(exception_type_t exception, static void call_fault_handler(
exception_type_t exception,
exception_data_type_t code,
MACH_EXC_STATE_TYPE *exc_state, MACH_EXC_STATE_TYPE *exc_state,
MACH_THREAD_STATE_TYPE *thread_state) MACH_THREAD_STATE_TYPE *thread_state)
{ {
@ -52,12 +54,13 @@ static void call_fault_handler(exception_type_t exception,
signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state); signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
MACH_PROGRAM_COUNTER(thread_state) = (cell)memory_signal_handler_impl; MACH_PROGRAM_COUNTER(thread_state) = (cell)memory_signal_handler_impl;
} }
else if(exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV)
{
MACH_PROGRAM_COUNTER(thread_state) = (cell)fp_signal_handler_impl;
}
else else
{ {
if(exception == EXC_ARITHMETIC) signal_number = exception == EXC_ARITHMETIC ? SIGFPE : SIGABRT;
signal_number = SIGFPE;
else
signal_number = SIGABRT;
MACH_PROGRAM_COUNTER(thread_state) = (cell)misc_signal_handler_impl; MACH_PROGRAM_COUNTER(thread_state) = (cell)misc_signal_handler_impl;
} }
} }
@ -102,7 +105,7 @@ catch_exception_raise (mach_port_t exception_port,
/* Modify registers so to have the thread resume executing the /* Modify registers so to have the thread resume executing the
fault handler */ fault handler */
call_fault_handler(exception,&exc_state,&thread_state); call_fault_handler(exception,code[0],&exc_state,&thread_state);
/* Set the faulting thread's register contents.. /* Set the faulting thread's register contents..

View File

@ -18,6 +18,7 @@ Modified for Factor by Slava Pestov */
#define MACH_EXC_STATE_TYPE ppc_exception_state_t #define MACH_EXC_STATE_TYPE ppc_exception_state_t
#define MACH_EXC_STATE_FLAVOR PPC_EXCEPTION_STATE #define MACH_EXC_STATE_FLAVOR PPC_EXCEPTION_STATE
#define MACH_EXC_STATE_COUNT PPC_EXCEPTION_STATE_COUNT #define MACH_EXC_STATE_COUNT PPC_EXCEPTION_STATE_COUNT
#define MACH_EXC_INTEGER_DIV EXC_PPC_ZERO_DIVIDE
#define MACH_THREAD_STATE_TYPE ppc_thread_state_t #define MACH_THREAD_STATE_TYPE ppc_thread_state_t
#define MACH_THREAD_STATE_FLAVOR PPC_THREAD_STATE #define MACH_THREAD_STATE_FLAVOR PPC_THREAD_STATE
#define MACH_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT #define MACH_THREAD_STATE_COUNT PPC_THREAD_STATE_COUNT

View File

@ -16,6 +16,7 @@ Modified for Factor by Slava Pestov */
#define MACH_EXC_STATE_TYPE i386_exception_state_t #define MACH_EXC_STATE_TYPE i386_exception_state_t
#define MACH_EXC_STATE_FLAVOR i386_EXCEPTION_STATE #define MACH_EXC_STATE_FLAVOR i386_EXCEPTION_STATE
#define MACH_EXC_STATE_COUNT i386_EXCEPTION_STATE_COUNT #define MACH_EXC_STATE_COUNT i386_EXCEPTION_STATE_COUNT
#define MACH_EXC_INTEGER_DIV EXC_I386_DIV
#define MACH_THREAD_STATE_TYPE i386_thread_state_t #define MACH_THREAD_STATE_TYPE i386_thread_state_t
#define MACH_THREAD_STATE_FLAVOR i386_THREAD_STATE #define MACH_THREAD_STATE_FLAVOR i386_THREAD_STATE
#define MACH_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT #define MACH_THREAD_STATE_COUNT i386_THREAD_STATE_COUNT

View File

@ -16,6 +16,7 @@ Modified for Factor by Slava Pestov and Daniel Ehrenberg */
#define MACH_EXC_STATE_TYPE x86_exception_state64_t #define MACH_EXC_STATE_TYPE x86_exception_state64_t
#define MACH_EXC_STATE_FLAVOR x86_EXCEPTION_STATE64 #define MACH_EXC_STATE_FLAVOR x86_EXCEPTION_STATE64
#define MACH_EXC_STATE_COUNT x86_EXCEPTION_STATE64_COUNT #define MACH_EXC_STATE_COUNT x86_EXCEPTION_STATE64_COUNT
#define MACH_EXC_INTEGER_DIV EXC_I386_DIV
#define MACH_THREAD_STATE_TYPE x86_thread_state64_t #define MACH_THREAD_STATE_TYPE x86_thread_state64_t
#define MACH_THREAD_STATE_FLAVOR x86_THREAD_STATE64 #define MACH_THREAD_STATE_FLAVOR x86_THREAD_STATE64
#define MACH_THREAD_STATE_COUNT MACHINE_THREAD_STATE_COUNT #define MACH_THREAD_STATE_COUNT MACHINE_THREAD_STATE_COUNT

View File

@ -132,6 +132,16 @@ void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
UAP_PROGRAM_COUNTER(uap) = (cell)misc_signal_handler_impl; UAP_PROGRAM_COUNTER(uap) = (cell)misc_signal_handler_impl;
} }
void fpe_signal_handler(int signal, siginfo_t *siginfo, void *uap)
{
signal_number = signal;
signal_callstack_top = uap_stack_pointer(uap);
UAP_PROGRAM_COUNTER(uap) =
(siginfo->si_code == FPE_INTDIV || siginfo->si_code == FPE_INTOVF)
? (cell)misc_signal_handler_impl
: (cell)fp_signal_handler_impl;
}
static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact) static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
{ {
int ret; int ret;
@ -149,6 +159,7 @@ void unix_init_signals()
{ {
struct sigaction memory_sigaction; struct sigaction memory_sigaction;
struct sigaction misc_sigaction; struct sigaction misc_sigaction;
struct sigaction fpe_sigaction;
struct sigaction ignore_sigaction; struct sigaction ignore_sigaction;
memset(&memory_sigaction,0,sizeof(struct sigaction)); memset(&memory_sigaction,0,sizeof(struct sigaction));
@ -159,13 +170,19 @@ void unix_init_signals()
sigaction_safe(SIGBUS,&memory_sigaction,NULL); sigaction_safe(SIGBUS,&memory_sigaction,NULL);
sigaction_safe(SIGSEGV,&memory_sigaction,NULL); sigaction_safe(SIGSEGV,&memory_sigaction,NULL);
memset(&fpe_sigaction,0,sizeof(struct sigaction));
sigemptyset(&fpe_sigaction.sa_mask);
fpe_sigaction.sa_sigaction = fpe_signal_handler;
fpe_sigaction.sa_flags = SA_SIGINFO;
sigaction_safe(SIGFPE,&fpe_sigaction,NULL);
memset(&misc_sigaction,0,sizeof(struct sigaction)); memset(&misc_sigaction,0,sizeof(struct sigaction));
sigemptyset(&misc_sigaction.sa_mask); sigemptyset(&misc_sigaction.sa_mask);
misc_sigaction.sa_sigaction = misc_signal_handler; misc_sigaction.sa_sigaction = misc_signal_handler;
misc_sigaction.sa_flags = SA_SIGINFO; misc_sigaction.sa_flags = SA_SIGINFO;
sigaction_safe(SIGABRT,&misc_sigaction,NULL); sigaction_safe(SIGABRT,&misc_sigaction,NULL);
sigaction_safe(SIGFPE,&misc_sigaction,NULL);
sigaction_safe(SIGQUIT,&misc_sigaction,NULL); sigaction_safe(SIGQUIT,&misc_sigaction,NULL);
sigaction_safe(SIGILL,&misc_sigaction,NULL); sigaction_safe(SIGILL,&misc_sigaction,NULL);