]> gitweb.factorcode.org Git - factor.git/blob - vm/errors.cpp
give better error message for windows exceptions, and don't lop off the top end of...
[factor.git] / vm / errors.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 void fatal_error(const char *msg, cell tagged)
7 {
8         print_string("fatal_error: "); print_string(msg);
9         print_string(": "); print_cell_hex(tagged); nl();
10         exit(1);
11 }
12
13 void critical_error(const char *msg, cell tagged)
14 {
15         print_string("You have triggered a bug in Factor. Please report.\n");
16         print_string("critical_error: "); print_string(msg);
17         print_string(": "); print_cell_hex(tagged); nl();
18         tls_vm()->factorbug();
19 }
20
21 void out_of_memory()
22 {
23         print_string("Out of memory\n\n");
24         tls_vm()->dump_generations();
25         exit(1);
26 }
27
28 void factor_vm::throw_error(cell error, stack_frame *callstack_top)
29 {
30         /* If the error handler is set, we rewind any C stack frames and
31         pass the error to user-space. */
32         if(!current_gc && to_boolean(userenv[BREAK_ENV]))
33         {
34                 /* If error was thrown during heap scan, we re-enable the GC */
35                 gc_off = false;
36
37                 /* Reset local roots */
38                 gc_locals.clear();
39                 gc_bignums.clear();
40
41                 /* If we had an underflow or overflow, stack pointers might be
42                 out of bounds */
43                 fix_stacks();
44
45                 dpush(error);
46
47                 /* Errors thrown from C code pass NULL for this parameter.
48                 Errors thrown from Factor code, or signal handlers, pass the
49                 actual stack pointer at the time, since the saved pointer is
50                 not necessarily up to date at that point. */
51                 if(callstack_top)
52                         callstack_top = fix_callstack_top(callstack_top,ctx->callstack_bottom);
53                 else
54                         callstack_top = ctx->callstack_top;
55
56                 throw_impl(userenv[BREAK_ENV],callstack_top,this);
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 factor_vm::general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *callstack_top)
71 {
72         throw_error(allot_array_4(userenv[ERROR_ENV],
73                 tag_fixnum(error),arg1,arg2),callstack_top);
74 }
75
76 void factor_vm::type_error(cell type, cell tagged)
77 {
78         general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
79 }
80
81 void factor_vm::not_implemented_error()
82 {
83         general_error(ERROR_NOT_IMPLEMENTED,false_object,false_object,NULL);
84 }
85
86 /* Test if 'fault' is in the guard page at the top or bottom (depending on
87 offset being 0 or -1) of area+area_size */
88 bool factor_vm::in_page(cell fault, cell area, cell area_size, int offset)
89 {
90         int pagesize = getpagesize();
91         area += area_size;
92         area += offset * pagesize;
93
94         return fault >= area && fault <= area + pagesize;
95 }
96
97 void factor_vm::memory_protection_error(cell addr, stack_frame *native_stack)
98 {
99         if(in_page(addr, ds_bot, 0, -1))
100                 general_error(ERROR_DS_UNDERFLOW,false_object,false_object,native_stack);
101         else if(in_page(addr, ds_bot, ds_size, 0))
102                 general_error(ERROR_DS_OVERFLOW,false_object,false_object,native_stack);
103         else if(in_page(addr, rs_bot, 0, -1))
104                 general_error(ERROR_RS_UNDERFLOW,false_object,false_object,native_stack);
105         else if(in_page(addr, rs_bot, rs_size, 0))
106                 general_error(ERROR_RS_OVERFLOW,false_object,false_object,native_stack);
107         else if(in_page(addr, nursery.end, 0, 0))
108                 critical_error("allot_object() missed GC check",0);
109         else
110                 general_error(ERROR_MEMORY,allot_cell(addr),false_object,native_stack);
111 }
112
113 void factor_vm::signal_error(int signal, stack_frame *native_stack)
114 {
115         general_error(ERROR_SIGNAL,allot_cell(signal),false_object,native_stack);
116 }
117
118 void factor_vm::divide_by_zero_error()
119 {
120         general_error(ERROR_DIVIDE_BY_ZERO,false_object,false_object,NULL);
121 }
122
123 void factor_vm::fp_trap_error(unsigned int fpu_status, stack_frame *signal_callstack_top)
124 {
125         general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),false_object,signal_callstack_top);
126 }
127
128 void factor_vm::primitive_call_clear()
129 {
130         throw_impl(dpop(),ctx->callstack_bottom,this);
131 }
132
133 /* For testing purposes */
134 void factor_vm::primitive_unimplemented()
135 {
136         not_implemented_error();
137 }
138
139 void factor_vm::memory_signal_handler_impl()
140 {
141         memory_protection_error(signal_fault_addr,signal_callstack_top);
142 }
143
144 void memory_signal_handler_impl()
145 {
146         tls_vm()->memory_signal_handler_impl();
147 }
148
149 void factor_vm::misc_signal_handler_impl()
150 {
151         signal_error(signal_number,signal_callstack_top);
152 }
153
154 void misc_signal_handler_impl()
155 {
156         tls_vm()->misc_signal_handler_impl();
157 }
158
159 void factor_vm::fp_signal_handler_impl()
160 {
161         fp_trap_error(signal_fpu_status,signal_callstack_top);
162 }
163
164 void fp_signal_handler_impl()
165 {
166         tls_vm()->fp_signal_handler_impl();
167 }
168
169 }