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