add an unlimit word, refactor limited-streams, better docs
[factor/jcg.git] / vm / run.h
blob06b631701508d282f0640a22d34e1709e26c2657
1 #define USER_ENV 70
3 typedef enum {
4 NAMESTACK_ENV, /* used by library only */
5 CATCHSTACK_ENV, /* used by library only, per-callback */
7 CURRENT_CALLBACK_ENV = 2, /* used by library only, per-callback */
8 WALKER_HOOK_ENV, /* non-local exit hook, used by library only */
9 CALLCC_1_ENV, /* used to pass the value in callcc1 */
11 BREAK_ENV = 5, /* quotation called by throw primitive */
12 ERROR_ENV, /* a marker consed onto kernel errors */
14 CELL_SIZE_ENV = 7, /* sizeof(CELL) */
15 CPU_ENV, /* CPU architecture */
16 OS_ENV, /* operating system name */
18 ARGS_ENV = 10, /* command line arguments */
19 STDIN_ENV, /* stdin FILE* handle */
20 STDOUT_ENV, /* stdout FILE* handle */
22 IMAGE_ENV = 13, /* image path name */
23 EXECUTABLE_ENV, /* runtime executable path name */
25 EMBEDDED_ENV = 15, /* are we embedded in another app? */
26 EVAL_CALLBACK_ENV, /* used when Factor is embedded in a C app */
27 YIELD_CALLBACK_ENV, /* used when Factor is embedded in a C app */
28 SLEEP_CALLBACK_ENV, /* used when Factor is embedded in a C app */
30 COCOA_EXCEPTION_ENV = 19, /* Cocoa exception handler quotation */
32 BOOT_ENV = 20, /* boot quotation */
33 GLOBAL_ENV, /* global namespace */
35 /* Used by the JIT compiler */
36 JIT_CODE_FORMAT = 22,
37 JIT_PROLOG,
38 JIT_PRIMITIVE_WORD,
39 JIT_PRIMITIVE,
40 JIT_WORD_JUMP,
41 JIT_WORD_CALL,
42 JIT_IF_WORD,
43 JIT_IF_1,
44 JIT_IF_2,
45 JIT_DISPATCH_WORD,
46 JIT_DISPATCH,
47 JIT_EPILOG,
48 JIT_RETURN,
49 JIT_PROFILING,
50 JIT_PUSH_IMMEDIATE,
51 JIT_DECLARE_WORD = 42,
52 JIT_SAVE_STACK,
53 JIT_DIP_WORD,
54 JIT_DIP,
55 JIT_2DIP_WORD,
56 JIT_2DIP,
57 JIT_3DIP_WORD,
58 JIT_3DIP,
60 STACK_TRACES_ENV = 59,
62 UNDEFINED_ENV = 60, /* default quotation for undefined words */
64 STDERR_ENV = 61, /* stderr FILE* handle */
66 STAGE2_ENV = 62, /* have we bootstrapped? */
68 CURRENT_THREAD_ENV = 63,
70 THREADS_ENV = 64,
71 RUN_QUEUE_ENV = 65,
72 SLEEP_QUEUE_ENV = 66,
73 } F_ENVTYPE;
75 #define FIRST_SAVE_ENV BOOT_ENV
76 #define LAST_SAVE_ENV STAGE2_ENV
78 /* TAGGED user environment data; see getenv/setenv prims */
79 DLLEXPORT CELL userenv[USER_ENV];
81 /* macros for reading/writing memory, useful when working around
82 C's type system */
83 INLINE CELL get(CELL where)
85 return *((CELL*)where);
88 INLINE void put(CELL where, CELL what)
90 *((CELL*)where) = what;
93 INLINE CELL cget(CELL where)
95 return *((u16 *)where);
98 INLINE void cput(CELL where, CELL what)
100 *((u16 *)where) = what;
103 INLINE CELL bget(CELL where)
105 return *((u8 *)where);
108 INLINE void bput(CELL where, CELL what)
110 *((u8 *)where) = what;
113 INLINE CELL align(CELL a, CELL b)
115 return (a + (b-1)) & ~(b-1);
118 #define align8(a) align(a,8)
119 #define align_page(a) align(a,getpagesize())
121 /* Canonical T object. It's just a word */
122 CELL T;
124 INLINE CELL tag_header(CELL cell)
126 return cell << TAG_BITS;
129 INLINE CELL untag_header(CELL cell)
131 return cell >> TAG_BITS;
134 INLINE CELL tag_object(void* cell)
136 return RETAG(cell,OBJECT_TYPE);
139 INLINE CELL object_type(CELL tagged)
141 return untag_header(get(UNTAG(tagged)));
144 INLINE CELL type_of(CELL tagged)
146 CELL tag = TAG(tagged);
147 if(tag == OBJECT_TYPE)
148 return object_type(tagged);
149 else
150 return tag;
153 #define DEFPUSHPOP(prefix,ptr) \
154 INLINE CELL prefix##pop(void) \
156 CELL value = get(ptr); \
157 ptr -= CELLS; \
158 return value; \
160 INLINE void prefix##push(CELL tagged) \
162 ptr += CELLS; \
163 put(ptr,tagged); \
165 INLINE void prefix##repl(CELL tagged) \
167 put(ptr,tagged); \
169 INLINE CELL prefix##peek() \
171 return get(ptr); \
174 DEFPUSHPOP(d,ds)
175 DEFPUSHPOP(r,rs)
177 typedef struct {
178 CELL start;
179 CELL size;
180 CELL end;
181 } F_SEGMENT;
183 /* Assembly code makes assumptions about the layout of this struct:
184 - callstack_top field is 0
185 - callstack_bottom field is 1
186 - datastack field is 2
187 - retainstack field is 3 */
188 typedef struct _F_CONTEXT {
189 /* C stack pointer on entry */
190 F_STACK_FRAME *callstack_top;
191 F_STACK_FRAME *callstack_bottom;
193 /* current datastack top pointer */
194 CELL datastack;
196 /* current retain stack top pointer */
197 CELL retainstack;
199 /* saved contents of ds register on entry to callback */
200 CELL datastack_save;
202 /* saved contents of rs register on entry to callback */
203 CELL retainstack_save;
205 /* memory region holding current datastack */
206 F_SEGMENT *datastack_region;
208 /* memory region holding current retain stack */
209 F_SEGMENT *retainstack_region;
211 /* saved userenv slots on entry to callback */
212 CELL catchstack_save;
213 CELL current_callback_save;
215 struct _F_CONTEXT *next;
216 } F_CONTEXT;
218 DLLEXPORT F_CONTEXT *stack_chain;
220 F_CONTEXT *unused_contexts;
222 CELL ds_size, rs_size;
224 #define ds_bot (stack_chain->datastack_region->start)
225 #define ds_top (stack_chain->datastack_region->end)
226 #define rs_bot (stack_chain->retainstack_region->start)
227 #define rs_top (stack_chain->retainstack_region->end)
229 void reset_datastack(void);
230 void reset_retainstack(void);
231 void fix_stacks(void);
232 DLLEXPORT void save_stacks(void);
233 DLLEXPORT void nest_stacks(void);
234 DLLEXPORT void unnest_stacks(void);
235 void init_stacks(CELL ds_size, CELL rs_size);
237 void primitive_datastack(void);
238 void primitive_retainstack(void);
239 void primitive_getenv(void);
240 void primitive_setenv(void);
241 void primitive_exit(void);
242 void primitive_os_env(void);
243 void primitive_os_envs(void);
244 void primitive_set_os_env(void);
245 void primitive_unset_os_env(void);
246 void primitive_set_os_envs(void);
247 void primitive_micros(void);
248 void primitive_sleep(void);
249 void primitive_set_slot(void);
250 void primitive_load_locals(void);
252 bool stage2;