]> gitweb.factorcode.org Git - factor.git/blob - vm/errors.c
7c06ec1310568a98a7058e1ff2bfa7a244a3e67e
[factor.git] / vm / errors.c
1 #include "master.h"
2
3 void out_of_memory(void)
4 {
5         print_string("Out of memory\n\n");
6         dump_generations();
7         exit(1);
8 }
9
10 void fatal_error(char* msg, CELL tagged)
11 {
12         print_string("fatal_error: "); print_string(msg);
13         print_string(": "); print_cell_hex(tagged); nl();
14         exit(1);
15 }
16
17 void critical_error(char* msg, CELL tagged)
18 {
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();
23 }
24
25 void throw_error(CELL error, F_STACK_FRAME *callstack_top)
26 {
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)
30         {
31                 /* If error was thrown during heap scan, we re-enable the GC */
32                 gc_off = false;
33
34                 /* Reset local roots */
35                 gc_locals = gc_locals_region->start - CELLS;
36                 extra_roots = extra_roots_region->start - CELLS;
37
38                 /* If we had an underflow or overflow, stack pointers might be
39                 out of bounds */
40                 fix_stacks();
41
42                 dpush(error);
43
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)
49                 {
50                         callstack_top = fix_callstack_top(callstack_top,
51                                 stack_chain->callstack_bottom);
52                 }
53                 else
54                         callstack_top = stack_chain->callstack_top;
55
56                 throw_impl(userenv[BREAK_ENV],callstack_top);
57         }
58         /* Error was thrown in early startup before error handler is set, just
59         crash. */
60         else
61         {
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();
67         }
68 }
69
70 void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2,
71         F_STACK_FRAME *callstack_top)
72 {
73         throw_error(allot_array_4(userenv[ERROR_ENV],
74                 tag_fixnum(error),arg1,arg2),callstack_top);
75 }
76
77 void type_error(CELL type, CELL tagged)
78 {
79         general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
80 }
81
82 void not_implemented_error(void)
83 {
84         general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
85 }
86
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)
90 {
91         int pagesize = getpagesize();
92         area += area_size;
93         area += offset * pagesize;
94
95         return fault >= area && fault <= area + pagesize;
96 }
97
98 void memory_protection_error(CELL addr, F_STACK_FRAME *native_stack)
99 {
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);
120 }
121
122 void signal_error(int signal, F_STACK_FRAME *native_stack)
123 {
124         general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
125 }
126
127 void divide_by_zero_error(F_STACK_FRAME *native_stack)
128 {
129         general_error(ERROR_DIVIDE_BY_ZERO,F,F,native_stack);
130 }
131
132 void memory_signal_handler_impl(void)
133 {
134         memory_protection_error(signal_fault_addr,signal_callstack_top);
135 }
136
137 void divide_by_zero_signal_handler_impl(void)
138 {
139         divide_by_zero_error(signal_callstack_top);
140 }
141
142 void misc_signal_handler_impl(void)
143 {
144         signal_error(signal_number,signal_callstack_top);
145 }
146
147 void primitive_throw(void)
148 {
149         dpop();
150         throw_impl(dpop(),stack_chain->callstack_top);
151 }
152
153 void primitive_call_clear(void)
154 {
155         throw_impl(dpop(),stack_chain->callstack_bottom);
156 }
157
158 /* For testing purposes */
159 void primitive_unimplemented(void)
160 {
161         not_implemented_error();
162 }