13 curry = untag_object(obj);
18 type_error(QUOTATION_TYPE,obj);
23 void update_xt(F_WORD* word)
29 else if(type_of(word->def) == QUOTATION_TYPE)
32 word->xt = docol_profiling;
36 else if(type_of(word->def) == FIXNUM_TYPE)
37 word->xt = primitives[to_fixnum(word->def)];
42 DEFINE_PRIMITIVE(uncurry)
47 DEFINE_PRIMITIVE(getenv)
49 F_FIXNUM e = untag_fixnum_fast(dpeek());
53 DEFINE_PRIMITIVE(setenv)
55 F_FIXNUM e = untag_fixnum_fast(dpop());
60 DEFINE_PRIMITIVE(exit)
62 exit(to_fixnum(dpop()));
65 DEFINE_PRIMITIVE(os_env)
67 char *name = unbox_char_string();
68 char *value = getenv(name);
72 box_char_string(value);
79 drepl((lhs == rhs) ? T : F);
82 DEFINE_PRIMITIVE(millis)
84 box_unsigned_8(current_millis());
87 DEFINE_PRIMITIVE(sleep)
89 sleep_millis(to_cell(dpop()));
92 DEFINE_PRIMITIVE(type)
94 drepl(tag_fixnum(type_of(dpeek())));
99 drepl(tag_fixnum(TAG(dpeek())));
102 DEFINE_PRIMITIVE(class_hash)
106 if(tag == TUPLE_TYPE)
108 F_WORD *class = untag_object(get(SLOT(obj,2)));
109 drepl(class->hashcode);
111 else if(tag == OBJECT_TYPE)
112 drepl(get(UNTAG(obj)));
114 drepl(tag_fixnum(tag));
117 DEFINE_PRIMITIVE(slot)
119 F_FIXNUM slot = untag_fixnum_fast(dpop());
121 dpush(get(SLOT(obj,slot)));
124 DEFINE_PRIMITIVE(set_slot)
126 F_FIXNUM slot = untag_fixnum_fast(dpop());
129 set_slot(obj,slot,value);
132 void fatal_error(char* msg, CELL tagged)
134 fprintf(stderr,"fatal_error: %s %lx\n",msg,tagged);
138 void critical_error(char* msg, CELL tagged)
140 fprintf(stderr,"You have triggered a bug in Factor. Please report.\n");
141 fprintf(stderr,"critical_error: %s %lx\n",msg,tagged);
145 void throw_error(CELL error, F_STACK_FRAME *callstack_top)
147 /* If error was thrown during heap scan, we re-enable the GC */
150 /* Reset local roots */
151 extra_roots = stack_chain->extra_roots;
153 /* If we had an underflow or overflow, stack pointers might be
159 /* If the error handler is set, we rewind any C stack frames and
160 pass the error to user-space. */
161 if(userenv[BREAK_ENV] != F)
163 /* Errors thrown from C code pass NULL for this parameter.
164 Errors thrown from Factor code, or signal handlers, pass the
165 actual stack pointer at the time, since the saved pointer is
166 not necessarily up to date at that point. */
168 callstack_top = stack_chain->callstack_top;
170 throw_impl(userenv[BREAK_ENV],callstack_top);
172 /* Error was thrown in early startup before error handler is set, just
176 fprintf(stderr,"You have triggered a bug in Factor. Please report.\n");
177 fprintf(stderr,"early_error: ");
179 fprintf(stderr,"\n");
184 void general_error(F_ERRORTYPE error, CELL arg1, CELL arg2,
185 F_STACK_FRAME *callstack_top)
187 throw_error(allot_array_4(userenv[ERROR_ENV],
188 tag_fixnum(error),arg1,arg2),callstack_top);
191 void type_error(CELL type, CELL tagged)
193 general_error(ERROR_TYPE,tag_fixnum(type),tagged,NULL);
196 void not_implemented_error(void)
198 general_error(ERROR_NOT_IMPLEMENTED,F,F,NULL);
201 /* This function is called from the undefined function in cpu_*.S */
202 void undefined_error(CELL word, F_STACK_FRAME *callstack_top)
204 stack_chain->callstack_top = callstack_top;
205 general_error(ERROR_UNDEFINED_WORD,word,F,NULL);
208 /* Test if 'fault' is in the guard page at the top or bottom (depending on
209 offset being 0 or -1) of area+area_size */
210 bool in_page(CELL fault, CELL area, CELL area_size, int offset)
212 int pagesize = getpagesize();
214 area += offset * pagesize;
216 return fault >= area && fault <= area + pagesize;
219 void memory_protection_error(CELL addr, F_STACK_FRAME *native_stack)
221 if(in_page(addr, ds_bot, 0, -1))
222 general_error(ERROR_DS_UNDERFLOW,F,F,native_stack);
223 else if(in_page(addr, ds_bot, ds_size, 0))
224 general_error(ERROR_DS_OVERFLOW,F,F,native_stack);
225 else if(in_page(addr, rs_bot, 0, -1))
226 general_error(ERROR_RS_UNDERFLOW,F,F,native_stack);
227 else if(in_page(addr, rs_bot, rs_size, 0))
228 general_error(ERROR_RS_OVERFLOW,F,F,native_stack);
229 else if(in_page(addr, nursery->end, 0, 0))
230 critical_error("allot_object() missed GC check",0);
231 else if(in_page(addr, extra_roots_region->start, 0, -1))
232 critical_error("local root underflow",0);
233 else if(in_page(addr, extra_roots_region->end, 0, 0))
234 critical_error("local root overflow",0);
236 general_error(ERROR_MEMORY,allot_cell(addr),F,native_stack);
239 void signal_error(int signal, F_STACK_FRAME *native_stack)
241 general_error(ERROR_SIGNAL,tag_fixnum(signal),F,native_stack);
244 void divide_by_zero_error(F_STACK_FRAME *native_stack)
246 general_error(ERROR_DIVIDE_BY_ZERO,F,F,native_stack);
249 DEFINE_PRIMITIVE(throw)
252 throw_impl(dpop(),stack_chain->callstack_top);
255 void enable_word_profiling(F_WORD *word)
257 if(word->xt == docol)
258 word->xt = docol_profiling;
261 void disable_word_profiling(F_WORD *word)
263 if(word->xt == docol_profiling)
267 DEFINE_PRIMITIVE(profiling)
269 profiling = to_boolean(dpop());
274 while((obj = next_object()) != F)
276 if(type_of(obj) == WORD_TYPE)
279 enable_word_profiling(untag_object(obj));
281 disable_word_profiling(untag_object(obj));
285 gc_off = false; /* end heap scan */