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