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 -- )
"Unimplemented primitive" print drop ;
: fp-trap-error. ( error -- )
"Floating point trap" print drop ;
PREDICATE: vm-error < array
{
{ [ dup empty? ] [ drop f ] }
{ [ dup first "kernel-error" = not ] [ drop f ] }
[ second 0 15 between? ]
[ second 0 16 between? ]
} cond ;
: vm-errors ( error -- n errors )
@ -149,6 +152,7 @@ PREDICATE: vm-error < array
{ 13 [ retainstack-underflow. ] }
{ 14 [ retainstack-overflow. ] }
{ 15 [ memory-error. ] }
{ 16 [ fp-trap-error. ] }
} ; inline
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);
}
void fp_trap_error()
{
general_error(ERROR_FP_TRAP,F,F,NULL);
}
PRIMITIVE(call_clear)
{
throw_impl(dpop(),stack_chain->callstack_bottom);
@ -151,4 +156,9 @@ void misc_signal_handler_impl()
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_OVERFLOW,
ERROR_MEMORY,
ERROR_FP_TRAP,
};
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 type_error(cell type, cell tagged);
void not_implemented_error();
void fp_trap_error();
PRIMITIVE(call_clear);
PRIMITIVE(unimplemented);
@ -46,6 +48,7 @@ extern cell signal_fault_addr;
extern stack_frame *signal_callstack_top;
void memory_signal_handler_impl();
void fp_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
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. */
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_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);
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
{
if(exception == EXC_ARITHMETIC)
signal_number = SIGFPE;
else
signal_number = SIGABRT;
signal_number = exception == EXC_ARITHMETIC ? SIGFPE : SIGABRT;
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
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..

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_FLAVOR PPC_EXCEPTION_STATE
#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_FLAVOR PPC_THREAD_STATE
#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_FLAVOR i386_EXCEPTION_STATE
#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_FLAVOR i386_THREAD_STATE
#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_FLAVOR x86_EXCEPTION_STATE64
#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_FLAVOR x86_THREAD_STATE64
#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;
}
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)
{
int ret;
@ -149,6 +159,7 @@ void unix_init_signals()
{
struct sigaction memory_sigaction;
struct sigaction misc_sigaction;
struct sigaction fpe_sigaction;
struct sigaction ignore_sigaction;
memset(&memory_sigaction,0,sizeof(struct sigaction));
@ -159,13 +170,19 @@ void unix_init_signals()
sigaction_safe(SIGBUS,&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));
sigemptyset(&misc_sigaction.sa_mask);
misc_sigaction.sa_sigaction = misc_signal_handler;
misc_sigaction.sa_flags = SA_SIGINFO;
sigaction_safe(SIGABRT,&misc_sigaction,NULL);
sigaction_safe(SIGFPE,&misc_sigaction,NULL);
sigaction_safe(SIGQUIT,&misc_sigaction,NULL);
sigaction_safe(SIGILL,&misc_sigaction,NULL);