6 /* Global variables used to pass fault handler state from signal handler to
9 cell signal_fault_addr;
10 unsigned int signal_fpu_status;
11 stack_frame *signal_callstack_top;
13 void factorvm::out_of_memory()
15 print_string("Out of memory\n\n");
20 void fatal_error(const char* msg, cell tagged)
22 print_string("fatal_error: "); print_string(msg);
23 print_string(": "); print_cell_hex(tagged); nl();
27 void factorvm::critical_error(const char* msg, cell tagged)
29 print_string("You have triggered a bug in Factor. Please report.\n");
30 print_string("critical_error: "); print_string(msg);
31 print_string(": "); print_cell_hex(tagged); nl();
35 void factorvm::throw_error(cell error, stack_frame *callstack_top)
37 /* If the error handler is set, we rewind any C stack frames and
38 pass the error to user-space. */
39 if(userenv[BREAK_ENV] != F)
41 /* If error was thrown during heap scan, we re-enable the GC */
44 /* Reset local roots */
48 /* If we had an underflow or overflow, stack pointers might be
54 /* Errors thrown from C code pass NULL for this parameter.
55 Errors thrown from Factor code, or signal handlers, pass the
56 actual stack pointer at the time, since the saved pointer is
57 not necessarily up to date at that point. */
60 callstack_top = fix_callstack_top(callstack_top,
61 stack_chain->callstack_bottom);
64 callstack_top = stack_chain->callstack_top;
66 throw_impl(userenv[BREAK_ENV],callstack_top,this);
68 /* Error was thrown in early startup before error handler is set, just
72 print_string("You have triggered a bug in Factor. Please report.\n");
73 print_string("early_error: ");
80 void factorvm::general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *callstack_top)
82 throw_error(allot_array_4(userenv[ERROR_ENV],
83 tag_fixnum(error),arg1,arg2),callstack_top);
87 void factorvm::type_error(cell type, cell tagged)
89 general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
92 void factorvm::not_implemented_error()
94 general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
98 /* Test if 'fault' is in the guard page at the top or bottom (depending on
99 offset being 0 or -1) of area+area_size */
100 bool factorvm::in_page(cell fault, cell area, cell area_size, int offset)
102 int pagesize = getpagesize();
104 area += offset * pagesize;
106 return fault >= area && fault <= area + pagesize;
109 void factorvm::memory_protection_error(cell addr, stack_frame *native_stack)
111 if(in_page(addr, ds_bot, 0, -1))
112 general_error(ERROR_DS_UNDERFLOW,F,F,native_stack);
113 else if(in_page(addr, ds_bot, ds_size, 0))
114 general_error(ERROR_DS_OVERFLOW,F,F,native_stack);
115 else if(in_page(addr, rs_bot, 0, -1))
116 general_error(ERROR_RS_UNDERFLOW,F,F,native_stack);
117 else if(in_page(addr, rs_bot, rs_size, 0))
118 general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
119 else if(in_page(addr, nursery.end, 0, 0))
120 critical_error("allot_object() missed GC check",0);
122 general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
125 void factorvm::signal_error(int signal, stack_frame *native_stack)
127 general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
130 void factorvm::divide_by_zero_error()
132 general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
135 void factorvm::fp_trap_error(unsigned int fpu_status, stack_frame *signal_callstack_top)
137 general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),F,signal_callstack_top);
140 inline void factorvm::vmprim_call_clear()
142 throw_impl(dpop(),stack_chain->callstack_bottom,this);
145 PRIMITIVE(call_clear)
147 PRIMITIVE_GETVM()->vmprim_call_clear();
150 /* For testing purposes */
151 inline void factorvm::vmprim_unimplemented()
153 not_implemented_error();
156 PRIMITIVE(unimplemented)
158 PRIMITIVE_GETVM()->vmprim_unimplemented();
161 void factorvm::memory_signal_handler_impl()
163 memory_protection_error(signal_fault_addr,signal_callstack_top);
166 void memory_signal_handler_impl()
168 SIGNAL_VM_PTR()->misc_signal_handler_impl();
171 void factorvm::misc_signal_handler_impl()
173 signal_error(signal_number,signal_callstack_top);
176 void misc_signal_handler_impl()
178 SIGNAL_VM_PTR()->misc_signal_handler_impl();
181 void factorvm::fp_signal_handler_impl()
183 fp_trap_error(signal_fpu_status,signal_callstack_top);
186 void fp_signal_handler_impl()
188 SIGNAL_VM_PTR->fp_signal_handler_impl();