add an unlimit word, refactor limited-streams, better docs
[factor/jcg.git] / vm / errors.c
blob7c06ec1310568a98a7058e1ff2bfa7a244a3e67e
1 #include "master.h"
3 void out_of_memory(void)
5 print_string("Out of memory\n\n");
6 dump_generations();
7 exit(1);
10 void fatal_error(char* msg, CELL tagged)
12 print_string("fatal_error: "); print_string(msg);
13 print_string(": "); print_cell_hex(tagged); nl();
14 exit(1);
17 void critical_error(char* msg, CELL tagged)
19 print_string("You have triggered a bug in Factor. Please report.\n");
20 print_string("critical_error: "); print_string(msg);
21 print_string(": "); print_cell_hex(tagged); nl();
22 factorbug();
25 void throw_error(CELL error, F_STACK_FRAME *callstack_top)
27 /* If the error handler is set, we rewind any C stack frames and
28 pass the error to user-space. */
29 if(userenv[BREAK_ENV] != F)
31 /* If error was thrown during heap scan, we re-enable the GC */
32 gc_off = false;
34 /* Reset local roots */
35 gc_locals = gc_locals_region->start - CELLS;
36 extra_roots = extra_roots_region->start - CELLS;
38 /* If we had an underflow or overflow, stack pointers might be
39 out of bounds */
40 fix_stacks();
42 dpush(error);
44 /* Errors thrown from C code pass NULL for this parameter.
45 Errors thrown from Factor code, or signal handlers, pass the
46 actual stack pointer at the time, since the saved pointer is
47 not necessarily up to date at that point. */
48 if(callstack_top)
50 callstack_top = fix_callstack_top(callstack_top,
51 stack_chain->callstack_bottom);
53 else
54 callstack_top = stack_chain->callstack_top;
56 throw_impl(userenv[BREAK_ENV],callstack_top);
58 /* Error was thrown in early startup before error handler is set, just
59 crash. */
60 else
62 print_string("You have triggered a bug in Factor. Please report.\n");
63 print_string("early_error: ");
64 print_obj(error);
65 nl();
66 factorbug();
70 void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2,
71 F_STACK_FRAME *callstack_top)
73 throw_error(allot_array_4(userenv[ERROR_ENV],
74 tag_fixnum(error),arg1,arg2),callstack_top);
77 void type_error(CELL type, CELL tagged)
79 general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
82 void not_implemented_error(void)
84 general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
87 /* Test if 'fault' is in the guard page at the top or bottom (depending on
88 offset being 0 or -1) of area+area_size */
89 bool in_page(CELL fault, CELL area, CELL area_size, int offset)
91 int pagesize = getpagesize();
92 area += area_size;
93 area += offset * pagesize;
95 return fault >= area && fault <= area + pagesize;
98 void memory_protection_error(CELL addr, F_STACK_FRAME *native_stack)
100 if(in_page(addr, ds_bot, 0, -1))
101 general_error(ERROR_DS_UNDERFLOW,F,F,native_stack);
102 else if(in_page(addr, ds_bot, ds_size, 0))
103 general_error(ERROR_DS_OVERFLOW,F,F,native_stack);
104 else if(in_page(addr, rs_bot, 0, -1))
105 general_error(ERROR_RS_UNDERFLOW,F,F,native_stack);
106 else if(in_page(addr, rs_bot, rs_size, 0))
107 general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
108 else if(in_page(addr, nursery.end, 0, 0))
109 critical_error("allot_object() missed GC check",0);
110 else if(in_page(addr, gc_locals_region->start, 0, -1))
111 critical_error("gc locals underflow",0);
112 else if(in_page(addr, gc_locals_region->end, 0, 0))
113 critical_error("gc locals overflow",0);
114 else if(in_page(addr, extra_roots_region->start, 0, -1))
115 critical_error("extra roots underflow",0);
116 else if(in_page(addr, extra_roots_region->end, 0, 0))
117 critical_error("extra roots overflow",0);
118 else
119 general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
122 void signal_error(int signal, F_STACK_FRAME *native_stack)
124 general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
127 void divide_by_zero_error(F_STACK_FRAME *native_stack)
129 general_error(ERROR_DIVIDE_BY_ZERO,F,F,native_stack);
132 void memory_signal_handler_impl(void)
134 memory_protection_error(signal_fault_addr,signal_callstack_top);
137 void divide_by_zero_signal_handler_impl(void)
139 divide_by_zero_error(signal_callstack_top);
142 void misc_signal_handler_impl(void)
144 signal_error(signal_number,signal_callstack_top);
147 void primitive_throw(void)
149 dpop();
150 throw_impl(dpop(),stack_chain->callstack_top);
153 void primitive_call_clear(void)
155 throw_impl(dpop(),stack_chain->callstack_bottom);
158 /* For testing purposes */
159 void primitive_unimplemented(void)
161 not_implemented_error();