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;
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 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 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);
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 general_error(vm_error_type error, cell arg1, cell arg2,
81 stack_frame *callstack_top)
83 throw_error(allot_array_4(userenv[ERROR_ENV],
84 tag_fixnum(error),arg1,arg2),callstack_top);
87 void type_error(cell type, cell tagged)
89 general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
92 void not_implemented_error()
94 general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
97 /* Test if 'fault' is in the guard page at the top or bottom (depending on
98 offset being 0 or -1) of area+area_size */
99 bool in_page(cell fault, cell area, cell area_size, int offset)
101 int pagesize = getpagesize();
103 area += offset * pagesize;
105 return fault >= area && fault <= area + pagesize;
108 void memory_protection_error(cell addr, stack_frame *native_stack)
110 if(in_page(addr, ds_bot, 0, -1))
111 general_error(ERROR_DS_UNDERFLOW,F,F,native_stack);
112 else if(in_page(addr, ds_bot, ds_size, 0))
113 general_error(ERROR_DS_OVERFLOW,F,F,native_stack);
114 else if(in_page(addr, rs_bot, 0, -1))
115 general_error(ERROR_RS_UNDERFLOW,F,F,native_stack);
116 else if(in_page(addr, rs_bot, rs_size, 0))
117 general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
118 else if(in_page(addr, nursery.end, 0, 0))
119 critical_error("allot_object() missed GC check",0);
121 general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
124 void signal_error(int signal, stack_frame *native_stack)
126 general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
129 void divide_by_zero_error()
131 general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
134 void fp_trap_error(unsigned int fpu_status, stack_frame *signal_callstack_top)
136 general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),F,signal_callstack_top);
139 PRIMITIVE(call_clear)
141 throw_impl(dpop(),stack_chain->callstack_bottom);
144 /* For testing purposes */
145 PRIMITIVE(unimplemented)
147 not_implemented_error();
150 void memory_signal_handler_impl()
152 memory_protection_error(signal_fault_addr,signal_callstack_top);
155 void misc_signal_handler_impl()
157 signal_error(signal_number,signal_callstack_top);
160 void fp_signal_handler_impl()
162 fp_trap_error(signal_fpu_status,signal_callstack_top);