]> gitweb.factorcode.org Git - factor.git/blob - vm/errors.cpp
Split data out into separate vm-data struct
[factor.git] / vm / errors.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 void factorvm::out_of_memory()
7 {
8         print_string("Out of memory\n\n");
9         dump_generations();
10         exit(1);
11 }
12
13 void fatal_error(const char* msg, cell tagged)
14 {
15         print_string("fatal_error: "); print_string(msg);
16         print_string(": "); print_cell_hex(tagged); nl();
17         exit(1);
18 }
19
20 void factorvm::critical_error(const char* msg, cell tagged)
21 {
22         print_string("You have triggered a bug in Factor. Please report.\n");
23         print_string("critical_error: "); print_string(msg);
24         print_string(": "); print_cell_hex(tagged); nl();
25         factorbug();
26 }
27
28 void factorvm::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(userenv[BREAK_ENV] != F)
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                 {
53                         callstack_top = fix_callstack_top(callstack_top,
54                                 stack_chain->callstack_bottom);
55                 }
56                 else
57                         callstack_top = stack_chain->callstack_top;
58
59                 throw_impl(userenv[BREAK_ENV],callstack_top,this);
60         }
61         /* Error was thrown in early startup before error handler is set, just
62         crash. */
63         else
64         {
65                 print_string("You have triggered a bug in Factor. Please report.\n");
66                 print_string("early_error: ");
67                 print_obj(error);
68                 nl();
69                 factorbug();
70         }
71 }
72
73 void factorvm::general_error(vm_error_type error, cell arg1, cell arg2, stack_frame *callstack_top)
74 {
75         throw_error(allot_array_4(userenv[ERROR_ENV],
76                 tag_fixnum(error),arg1,arg2),callstack_top);
77 }
78
79
80 void factorvm::type_error(cell type, cell tagged)
81 {
82         general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
83 }
84
85 void factorvm::not_implemented_error()
86 {
87         general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
88 }
89
90
91 /* Test if 'fault' is in the guard page at the top or bottom (depending on
92 offset being 0 or -1) of area+area_size */
93 bool factorvm::in_page(cell fault, cell area, cell area_size, int offset)
94 {
95         int pagesize = getpagesize();
96         area += area_size;
97         area += offset * pagesize;
98
99         return fault >= area && fault <= area + pagesize;
100 }
101
102 void factorvm::memory_protection_error(cell addr, stack_frame *native_stack)
103 {
104         if(in_page(addr, ds_bot, 0, -1))
105                 general_error(ERROR_DS_UNDERFLOW,F,F,native_stack);
106         else if(in_page(addr, ds_bot, ds_size, 0))
107                 general_error(ERROR_DS_OVERFLOW,F,F,native_stack);
108         else if(in_page(addr, rs_bot, 0, -1))
109                 general_error(ERROR_RS_UNDERFLOW,F,F,native_stack);
110         else if(in_page(addr, rs_bot, rs_size, 0))
111                 general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
112         else if(in_page(addr, nursery.end, 0, 0))
113                 critical_error("allot_object() missed GC check",0);
114         else
115                 general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
116 }
117
118 void factorvm::signal_error(int signal, stack_frame *native_stack)
119 {
120         general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
121 }
122
123 void factorvm::divide_by_zero_error()
124 {
125         general_error(ERROR_DIVIDE_BY_ZERO,F,F,NULL);
126 }
127
128 void factorvm::fp_trap_error(unsigned int fpu_status, stack_frame *signal_callstack_top)
129 {
130         general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),F,signal_callstack_top);
131 }
132
133 inline void factorvm::vmprim_call_clear()
134 {
135         throw_impl(dpop(),stack_chain->callstack_bottom,this);
136 }
137
138 PRIMITIVE(call_clear)
139 {
140         PRIMITIVE_GETVM()->vmprim_call_clear();
141 }
142
143 /* For testing purposes */
144 inline void factorvm::vmprim_unimplemented()
145 {
146         not_implemented_error();
147 }
148
149 PRIMITIVE(unimplemented)
150 {
151         PRIMITIVE_GETVM()->vmprim_unimplemented();
152 }
153
154 void factorvm::memory_signal_handler_impl()
155 {
156         memory_protection_error(signal_fault_addr,signal_callstack_top);
157 }
158
159 void memory_signal_handler_impl()
160 {
161         SIGNAL_VM_PTR()->memory_signal_handler_impl();
162 }
163
164 void factorvm::misc_signal_handler_impl()
165 {
166         signal_error(signal_number,signal_callstack_top);
167 }
168
169 void misc_signal_handler_impl()
170 {
171         SIGNAL_VM_PTR()->misc_signal_handler_impl();
172 }
173
174 void factorvm::fp_signal_handler_impl()
175 {
176         fp_trap_error(signal_fpu_status,signal_callstack_top);
177 }
178
179 void fp_signal_handler_impl()
180 {
181         SIGNAL_VM_PTR()->fp_signal_handler_impl();
182 }
183
184 }