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");
22 return vm->out_of_memory();
25 void factorvm::fatal_error(const char* msg, cell tagged)
27 print_string("fatal_error: "); print_string(msg);
28 print_string(": "); print_cell_hex(tagged); nl();
32 void fatal_error(const char* msg, cell tagged)
34 return vm->fatal_error(msg,tagged);
37 void factorvm::critical_error(const char* msg, cell tagged)
39 print_string("You have triggered a bug in Factor. Please report.\n");
40 print_string("critical_error: "); print_string(msg);
41 print_string(": "); print_cell_hex(tagged); nl();
45 void critical_error(const char* msg, cell tagged)
47 return vm->critical_error(msg,tagged);
50 void factorvm::throw_error(cell error, stack_frame *callstack_top)
52 /* If the error handler is set, we rewind any C stack frames and
53 pass the error to user-space. */
54 if(userenv[BREAK_ENV] != F)
56 /* If error was thrown during heap scan, we re-enable the GC */
59 /* Reset local roots */
63 /* If we had an underflow or overflow, stack pointers might be
69 /* Errors thrown from C code pass NULL for this parameter.
70 Errors thrown from Factor code, or signal handlers, pass the
71 actual stack pointer at the time, since the saved pointer is
72 not necessarily up to date at that point. */
75 callstack_top = fix_callstack_top(callstack_top,
76 stack_chain->callstack_bottom);
79 callstack_top = stack_chain->callstack_top;
81 throw_impl(userenv[BREAK_ENV],callstack_top,this);
83 /* Error was thrown in early startup before error handler is set, just
87 print_string("You have triggered a bug in Factor. Please report.\n");
88 print_string("early_error: ");
95 void factorvm::general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *callstack_top)
97 throw_error(allot_array_4(userenv[ERROR_ENV],
98 tag_fixnum(error),arg1,arg2),callstack_top);
101 void general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *callstack_top)
103 return vm->general_error(error,arg1,arg2,callstack_top);
106 void factorvm::type_error(cell type, cell tagged)
108 general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
111 void factorvm::not_implemented_error()
113 general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
116 void not_implemented_error()
118 return vm->not_implemented_error();
121 /* Test if 'fault' is in the guard page at the top or bottom (depending on
122 offset being 0 or -1) of area+area_size */
123 bool factorvm::in_page(cell fault, cell area, cell area_size, int offset)
125 int pagesize = getpagesize();
127 area += offset * pagesize;
129 return fault >= area && fault <= area + pagesize;
132 void factorvm::memory_protection_error(cell addr, stack_frame *native_stack)
134 if(in_page(addr, ds_bot, 0, -1))
135 general_error(ERROR_DS_UNDERFLOW,F,F,native_stack);
136 else if(in_page(addr, ds_bot, ds_size, 0))
137 general_error(ERROR_DS_OVERFLOW,F,F,native_stack);
138 else if(in_page(addr, rs_bot, 0, -1))
139 general_error(ERROR_RS_UNDERFLOW,F,F,native_stack);
140 else if(in_page(addr, rs_bot, rs_size, 0))
141 general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
142 else if(in_page(addr, nursery.end, 0, 0))
143 critical_error("allot_object() missed GC check",0);
145 general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
148 void factorvm::signal_error(int signal, stack_frame *native_stack)
150 general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
153 void factorvm::divide_by_zero_error()
155 general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
158 void divide_by_zero_error()
160 return vm->divide_by_zero_error();
163 void factorvm::fp_trap_error(unsigned int fpu_status, stack_frame *signal_callstack_top)
165 general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),F,signal_callstack_top);
168 inline void factorvm::vmprim_call_clear()
170 throw_impl(dpop(),stack_chain->callstack_bottom,this);
173 PRIMITIVE(call_clear)
175 PRIMITIVE_GETVM()->vmprim_call_clear();
178 /* For testing purposes */
179 inline void factorvm::vmprim_unimplemented()
181 not_implemented_error();
184 PRIMITIVE(unimplemented)
186 PRIMITIVE_GETVM()->vmprim_unimplemented();
189 void factorvm::memory_signal_handler_impl()
191 memory_protection_error(signal_fault_addr,signal_callstack_top);
194 void memory_signal_handler_impl()
196 return vm->memory_signal_handler_impl();
199 void factorvm::misc_signal_handler_impl()
201 signal_error(signal_number,signal_callstack_top);
204 void misc_signal_handler_impl()
206 vm->misc_signal_handler_impl();
209 void factorvm::fp_signal_handler_impl()
211 fp_trap_error(signal_fpu_status,signal_callstack_top);
214 void fp_signal_handler_impl()
216 vm->fp_signal_handler_impl();