]> gitweb.factorcode.org Git - factor.git/blob - vm/run.h
Refactor all usages of >r/r> in core to use dip, 2dip, 3dip
[factor.git] / vm / run.h
1 #define USER_ENV 70
2
3 typedef enum {
4         NAMESTACK_ENV,            /* used by library only */
5         CATCHSTACK_ENV,           /* used by library only, per-callback */
6
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 */
10
11         BREAK_ENV            = 5, /* quotation called by throw primitive */
12         ERROR_ENV,                /* a marker consed onto kernel errors */
13
14         CELL_SIZE_ENV        = 7, /* sizeof(CELL) */
15         CPU_ENV,                  /* CPU architecture */
16         OS_ENV,                   /* operating system name */
17
18         ARGS_ENV            = 10, /* command line arguments */
19         STDIN_ENV,                /* stdin FILE* handle */
20         STDOUT_ENV,               /* stdout FILE* handle */
21
22         IMAGE_ENV           = 13, /* image path name */
23         EXECUTABLE_ENV,           /* runtime executable path name */
24
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 */
29
30         COCOA_EXCEPTION_ENV = 19, /* Cocoa exception handler quotation */
31
32         BOOT_ENV            = 20, /* boot quotation */
33         GLOBAL_ENV,               /* global namespace */
34
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_PUSH_LITERAL,
43         JIT_IF_WORD,
44         JIT_IF_JUMP,
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,
59
60         STACK_TRACES_ENV    = 59,
61
62         UNDEFINED_ENV       = 60, /* default quotation for undefined words */
63
64         STDERR_ENV          = 61, /* stderr FILE* handle */
65
66         STAGE2_ENV          = 62, /* have we bootstrapped? */
67
68         CURRENT_THREAD_ENV  = 63,
69
70         THREADS_ENV         = 64,
71         RUN_QUEUE_ENV       = 65,
72         SLEEP_QUEUE_ENV     = 66,
73 } F_ENVTYPE;
74
75 #define FIRST_SAVE_ENV BOOT_ENV
76 #define LAST_SAVE_ENV STAGE2_ENV
77
78 /* TAGGED user environment data; see getenv/setenv prims */
79 DLLEXPORT CELL userenv[USER_ENV];
80
81 /* macros for reading/writing memory, useful when working around
82 C's type system */
83 INLINE CELL get(CELL where)
84 {
85         return *((CELL*)where);
86 }
87
88 INLINE void put(CELL where, CELL what)
89 {
90         *((CELL*)where) = what;
91 }
92
93 INLINE CELL cget(CELL where)
94 {
95         return *((u16 *)where);
96 }
97
98 INLINE void cput(CELL where, CELL what)
99 {
100         *((u16 *)where) = what;
101 }
102
103 INLINE CELL bget(CELL where)
104 {
105         return *((u8 *)where);
106 }
107
108 INLINE void bput(CELL where, CELL what)
109 {
110         *((u8 *)where) = what;
111 }
112
113 INLINE CELL align(CELL a, CELL b)
114 {
115         return (a + (b-1)) & ~(b-1);
116 }
117
118 #define align8(a) align(a,8)
119 #define align_page(a) align(a,getpagesize())
120
121 /* Canonical T object. It's just a word */
122 CELL T;
123
124 INLINE CELL tag_header(CELL cell)
125 {
126         return cell << TAG_BITS;
127 }
128
129 INLINE CELL untag_header(CELL cell)
130 {
131         return cell >> TAG_BITS;
132 }
133
134 INLINE CELL tag_object(void* cell)
135 {
136         return RETAG(cell,OBJECT_TYPE);
137 }
138
139 INLINE CELL object_type(CELL tagged)
140 {
141         return untag_header(get(UNTAG(tagged)));
142 }
143
144 INLINE CELL type_of(CELL tagged)
145 {
146         CELL tag = TAG(tagged);
147         if(tag == OBJECT_TYPE)
148                 return object_type(tagged);
149         else
150                 return tag;
151 }
152
153 #define DEFPUSHPOP(prefix,ptr) \
154         INLINE CELL prefix##pop(void) \
155         { \
156                 CELL value = get(ptr); \
157                 ptr -= CELLS; \
158                 return value; \
159         } \
160         INLINE void prefix##push(CELL tagged) \
161         { \
162                 ptr += CELLS; \
163                 put(ptr,tagged); \
164         } \
165         INLINE void prefix##repl(CELL tagged) \
166         { \
167                 put(ptr,tagged); \
168         } \
169         INLINE CELL prefix##peek() \
170         { \
171                 return get(ptr); \
172         }
173
174 DEFPUSHPOP(d,ds)
175 DEFPUSHPOP(r,rs)
176
177 typedef struct {
178         CELL start;
179         CELL size;
180         CELL end;
181 } F_SEGMENT;
182
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;
192
193         /* current datastack top pointer */
194         CELL datastack;
195
196         /* current retain stack top pointer */
197         CELL retainstack;
198
199         /* saved contents of ds register on entry to callback */
200         CELL datastack_save;
201
202         /* saved contents of rs register on entry to callback */
203         CELL retainstack_save;
204
205         /* memory region holding current datastack */
206         F_SEGMENT *datastack_region;
207
208         /* memory region holding current retain stack */
209         F_SEGMENT *retainstack_region;
210
211         /* saved userenv slots on entry to callback */
212         CELL catchstack_save;
213         CELL current_callback_save;
214
215         struct _F_CONTEXT *next;
216 } F_CONTEXT;
217
218 DLLEXPORT F_CONTEXT *stack_chain;
219
220 F_CONTEXT *unused_contexts;
221
222 CELL ds_size, rs_size;
223
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)
228
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);
236
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_millis(void);
248 void primitive_sleep(void);
249 void primitive_set_slot(void);
250
251 bool stage2;