Send FP trap signals to Factor as a different vm-error type
parent
96db254311
commit
7ba71a524e
|
@ -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" ;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
signal_number = SIGFPE;
|
||||
else
|
||||
signal_number = SIGABRT;
|
||||
else if(exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV)
|
||||
{
|
||||
MACH_PROGRAM_COUNTER(thread_state) = (cell)fp_signal_handler_impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
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..
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue