6 /* Global variables used to pass fault handler state from signal handler to
9 cell signal_fault_addr;
10 stack_frame *signal_callstack_top;
14 print_string("Out of memory\n\n");
19 void fatal_error(const char* msg, cell tagged)
21 print_string("fatal_error: "); print_string(msg);
22 print_string(": "); print_cell_hex(tagged); nl();
26 void critical_error(const char* msg, cell tagged)
28 print_string("You have triggered a bug in Factor. Please report.\n");
29 print_string("critical_error: "); print_string(msg);
30 print_string(": "); print_cell_hex(tagged); nl();
34 void throw_error(cell error, stack_frame *callstack_top)
36 /* If the error handler is set, we rewind any C stack frames and
37 pass the error to user-space. */
38 if(userenv[BREAK_ENV] != F)
40 /* If error was thrown during heap scan, we re-enable the GC */
43 /* Reset local roots */
47 /* If we had an underflow or overflow, stack pointers might be
53 /* Errors thrown from C code pass NULL for this parameter.
54 Errors thrown from Factor code, or signal handlers, pass the
55 actual stack pointer at the time, since the saved pointer is
56 not necessarily up to date at that point. */
59 callstack_top = fix_callstack_top(callstack_top,
60 stack_chain->callstack_bottom);
63 callstack_top = stack_chain->callstack_top;
65 throw_impl(userenv[BREAK_ENV],callstack_top);
67 /* Error was thrown in early startup before error handler is set, just
71 print_string("You have triggered a bug in Factor. Please report.\n");
72 print_string("early_error: ");
79 void general_error(vm_error_type error, cell arg1, cell arg2,
80 stack_frame *callstack_top)
82 throw_error(allot_array_4(userenv[ERROR_ENV],
83 tag_fixnum(error),arg1,arg2),callstack_top);
86 void type_error(cell type, cell tagged)
88 general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
91 void not_implemented_error()
93 general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
96 /* Test if 'fault' is in the guard page at the top or bottom (depending on
97 offset being 0 or -1) of area+area_size */
98 bool in_page(cell fault, cell area, cell area_size, int offset)
100 int pagesize = getpagesize();
102 area += offset * pagesize;
104 return fault >= area && fault <= area + pagesize;
107 void memory_protection_error(cell addr, stack_frame *native_stack)
109 if(in_page(addr, ds_bot, 0, -1))
110 general_error(ERROR_DS_UNDERFLOW,F,F,native_stack);
111 else if(in_page(addr, ds_bot, ds_size, 0))
112 general_error(ERROR_DS_OVERFLOW,F,F,native_stack);
113 else if(in_page(addr, rs_bot, 0, -1))
114 general_error(ERROR_RS_UNDERFLOW,F,F,native_stack);
115 else if(in_page(addr, rs_bot, rs_size, 0))
116 general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
117 else if(in_page(addr, nursery.end, 0, 0))
118 critical_error("allot_object() missed GC check",0);
120 general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
123 void signal_error(int signal, stack_frame *native_stack)
125 general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
128 void divide_by_zero_error()
130 general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
135 general_error(ERROR_FP_TRAP,F,F,NULL);
138 PRIMITIVE(call_clear)
140 throw_impl(dpop(),stack_chain->callstack_bottom);
143 /* For testing purposes */
144 PRIMITIVE(unimplemented)
146 not_implemented_error();
149 void memory_signal_handler_impl()
151 memory_protection_error(signal_fault_addr,signal_callstack_top);
154 void misc_signal_handler_impl()
156 signal_error(signal_number,signal_callstack_top);
159 void fp_signal_handler_impl()