| 
									
										
										
										
											2008-07-07 11:39:04 -04:00
										 |  |  | #define USER_ENV 70
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef enum { | 
					
						
							|  |  |  | 	NAMESTACK_ENV,            /* used by library only */ | 
					
						
							|  |  |  | 	CATCHSTACK_ENV,           /* used by library only, per-callback */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CURRENT_CALLBACK_ENV = 2, /* used by library only, per-callback */ | 
					
						
							|  |  |  | 	WALKER_HOOK_ENV,          /* non-local exit hook, used by library only */ | 
					
						
							|  |  |  | 	CALLCC_1_ENV,             /* used to pass the value in callcc1 */ | 
					
						
							| 
									
										
										
										
											2007-12-26 02:33:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	BREAK_ENV            = 5, /* quotation called by throw primitive */ | 
					
						
							|  |  |  | 	ERROR_ENV,                /* a marker consed onto kernel errors */ | 
					
						
							| 
									
										
										
										
											2007-12-26 02:33:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	CELL_SIZE_ENV        = 7, /* sizeof(CELL) */ | 
					
						
							|  |  |  | 	CPU_ENV,                  /* CPU architecture */ | 
					
						
							|  |  |  | 	OS_ENV,                   /* operating system name */ | 
					
						
							| 
									
										
										
										
											2007-12-26 02:33:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	ARGS_ENV            = 10, /* command line arguments */ | 
					
						
							| 
									
										
										
										
											2008-01-18 19:43:14 -05:00
										 |  |  | 	STDIN_ENV,                /* stdin FILE* handle */ | 
					
						
							|  |  |  | 	STDOUT_ENV,               /* stdout FILE* handle */ | 
					
						
							| 
									
										
										
										
											2007-12-26 02:33:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	IMAGE_ENV           = 13, /* image path name */ | 
					
						
							|  |  |  | 	EXECUTABLE_ENV,		  /* runtime executable path name */ | 
					
						
							| 
									
										
										
										
											2007-12-26 02:33:49 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	EMBEDDED_ENV 	    = 15, /* are we embedded in another app? */ | 
					
						
							|  |  |  | 	EVAL_CALLBACK_ENV,        /* used when Factor is embedded in a C app */ | 
					
						
							|  |  |  | 	YIELD_CALLBACK_ENV,       /* used when Factor is embedded in a C app */ | 
					
						
							|  |  |  | 	SLEEP_CALLBACK_ENV,       /* used when Factor is embedded in a C app */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	COCOA_EXCEPTION_ENV = 19, /* Cocoa exception handler quotation */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BOOT_ENV            = 20, /* boot quotation */ | 
					
						
							|  |  |  | 	GLOBAL_ENV,               /* global namespace */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Used by the JIT compiler */ | 
					
						
							|  |  |  | 	JIT_CODE_FORMAT     = 22, | 
					
						
							|  |  |  | 	JIT_PROLOG, | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 	JIT_PRIMITIVE_WORD, | 
					
						
							|  |  |  | 	JIT_PRIMITIVE, | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	JIT_WORD_JUMP, | 
					
						
							|  |  |  | 	JIT_WORD_CALL, | 
					
						
							|  |  |  | 	JIT_PUSH_LITERAL, | 
					
						
							|  |  |  | 	JIT_IF_WORD, | 
					
						
							|  |  |  | 	JIT_IF_JUMP, | 
					
						
							|  |  |  | 	JIT_DISPATCH_WORD, | 
					
						
							|  |  |  | 	JIT_DISPATCH, | 
					
						
							|  |  |  | 	JIT_EPILOG, | 
					
						
							|  |  |  | 	JIT_RETURN, | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 	JIT_PROFILING, | 
					
						
							| 
									
										
										
										
											2008-07-12 23:27:28 -04:00
										 |  |  | 	JIT_PUSH_IMMEDIATE, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	JIT_DECLARE_WORD    = 42, | 
					
						
							| 
									
										
										
										
											2008-07-07 11:39:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	STACK_TRACES_ENV    = 59, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	UNDEFINED_ENV       = 60, /* default quotation for undefined words */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	STDERR_ENV          = 61, /* stderr FILE* handle */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	STAGE2_ENV          = 62, /* have we bootstrapped? */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CURRENT_THREAD_ENV  = 63, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	THREADS_ENV         = 64, | 
					
						
							|  |  |  | 	RUN_QUEUE_ENV       = 65, | 
					
						
							|  |  |  | 	SLEEP_QUEUE_ENV     = 66, | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } F_ENVTYPE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define FIRST_SAVE_ENV BOOT_ENV
 | 
					
						
							| 
									
										
										
										
											2008-02-28 02:22:53 -05:00
										 |  |  | #define LAST_SAVE_ENV STAGE2_ENV
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* TAGGED user environment data; see getenv/setenv prims */ | 
					
						
							|  |  |  | DLLEXPORT CELL userenv[USER_ENV]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* macros for reading/writing memory, useful when working around
 | 
					
						
							|  |  |  | C's type system */ | 
					
						
							|  |  |  | INLINE CELL get(CELL where) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return *((CELL*)where); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE void put(CELL where, CELL what) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*((CELL*)where) = what; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | INLINE CELL cget(CELL where) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 	return *((u16 *)where); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | INLINE void cput(CELL where, CELL what) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 	*((u16 *)where) = what; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE CELL bget(CELL where) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return *((u8 *)where); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE void bput(CELL where, CELL what) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	*((u8 *)where) = what; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE CELL align(CELL a, CELL b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-05-09 18:30:32 -04:00
										 |  |  | 	return (a + (b-1)) & ~(b-1); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-09 18:30:32 -04:00
										 |  |  | #define align8(a) align(a,8)
 | 
					
						
							|  |  |  | #define align_page(a) align(a,getpagesize())
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Canonical T object. It's just a word */ | 
					
						
							|  |  |  | CELL T; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE CELL tag_header(CELL cell) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return cell << TAG_BITS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE CELL untag_header(CELL cell) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return cell >> TAG_BITS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE CELL tag_object(void* cell) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return RETAG(cell,OBJECT_TYPE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE CELL object_type(CELL tagged) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return untag_header(get(UNTAG(tagged))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | INLINE CELL type_of(CELL tagged) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL tag = TAG(tagged); | 
					
						
							|  |  |  | 	if(tag == OBJECT_TYPE) | 
					
						
							|  |  |  | 		return object_type(tagged); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return tag; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define DEFPUSHPOP(prefix,ptr) \
 | 
					
						
							|  |  |  | 	INLINE CELL prefix##pop(void) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		CELL value = get(ptr); \ | 
					
						
							|  |  |  | 		ptr -= CELLS; \ | 
					
						
							|  |  |  | 		return value; \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	INLINE void prefix##push(CELL tagged) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		ptr += CELLS; \ | 
					
						
							|  |  |  | 		put(ptr,tagged); \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	INLINE void prefix##repl(CELL tagged) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		put(ptr,tagged); \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	INLINE CELL prefix##peek() \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		return get(ptr); \ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFPUSHPOP(d,ds) | 
					
						
							|  |  |  | DEFPUSHPOP(r,rs) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-03 16:56:49 -04:00
										 |  |  | typedef struct { | 
					
						
							|  |  |  | 	CELL start; | 
					
						
							|  |  |  | 	CELL size; | 
					
						
							|  |  |  | 	CELL end; | 
					
						
							|  |  |  | } F_SEGMENT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-02 17:53:05 -04:00
										 |  |  | /* Assembly code makes assumptions about the layout of this struct:
 | 
					
						
							|  |  |  |    - callstack_top field is 0 | 
					
						
							|  |  |  |    - callstack_bottom field is 1 | 
					
						
							|  |  |  |    - datastack field is 2 | 
					
						
							|  |  |  |    - retainstack field is 3 */ | 
					
						
							|  |  |  | typedef struct _F_CONTEXT { | 
					
						
							|  |  |  | 	/* C stack pointer on entry */ | 
					
						
							|  |  |  | 	F_STACK_FRAME *callstack_top; | 
					
						
							|  |  |  | 	F_STACK_FRAME *callstack_bottom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* current datastack top pointer */ | 
					
						
							|  |  |  | 	CELL datastack; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* current retain stack top pointer */ | 
					
						
							|  |  |  | 	CELL retainstack; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* saved contents of ds register on entry to callback */ | 
					
						
							|  |  |  | 	CELL datastack_save; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* saved contents of rs register on entry to callback */ | 
					
						
							|  |  |  | 	CELL retainstack_save; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* memory region holding current datastack */ | 
					
						
							|  |  |  | 	F_SEGMENT *datastack_region; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* memory region holding current retain stack */ | 
					
						
							|  |  |  | 	F_SEGMENT *retainstack_region; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* saved userenv slots on entry to callback */ | 
					
						
							|  |  |  | 	CELL catchstack_save; | 
					
						
							|  |  |  | 	CELL current_callback_save; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct _F_CONTEXT *next; | 
					
						
							|  |  |  | } F_CONTEXT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DLLEXPORT F_CONTEXT *stack_chain; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CELL ds_size, rs_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ds_bot (stack_chain->datastack_region->start)
 | 
					
						
							|  |  |  | #define ds_top (stack_chain->datastack_region->end)
 | 
					
						
							|  |  |  | #define rs_bot (stack_chain->retainstack_region->start)
 | 
					
						
							|  |  |  | #define rs_top (stack_chain->retainstack_region->end)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void reset_datastack(void); | 
					
						
							|  |  |  | void reset_retainstack(void); | 
					
						
							|  |  |  | void fix_stacks(void); | 
					
						
							|  |  |  | DLLEXPORT void save_stacks(void); | 
					
						
							|  |  |  | DLLEXPORT void nest_stacks(void); | 
					
						
							|  |  |  | DLLEXPORT void unnest_stacks(void); | 
					
						
							|  |  |  | void init_stacks(CELL ds_size, CELL rs_size); | 
					
						
							| 
									
										
										
										
											2008-07-11 18:25:46 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-02 17:53:05 -04:00
										 |  |  | DECLARE_PRIMITIVE(datastack); | 
					
						
							|  |  |  | DECLARE_PRIMITIVE(retainstack); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | DECLARE_PRIMITIVE(getenv); | 
					
						
							|  |  |  | DECLARE_PRIMITIVE(setenv); | 
					
						
							|  |  |  | DECLARE_PRIMITIVE(exit); | 
					
						
							|  |  |  | DECLARE_PRIMITIVE(os_env); | 
					
						
							| 
									
										
										
										
											2007-11-12 23:18:29 -05:00
										 |  |  | DECLARE_PRIMITIVE(os_envs); | 
					
						
							| 
									
										
										
										
											2008-04-09 00:08:11 -04:00
										 |  |  | DECLARE_PRIMITIVE(set_os_env); | 
					
						
							|  |  |  | DECLARE_PRIMITIVE(unset_os_env); | 
					
						
							| 
									
										
										
										
											2008-03-06 21:44:52 -05:00
										 |  |  | DECLARE_PRIMITIVE(set_os_envs); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | DECLARE_PRIMITIVE(millis); | 
					
						
							|  |  |  | DECLARE_PRIMITIVE(sleep); | 
					
						
							|  |  |  | DECLARE_PRIMITIVE(set_slot); | 
					
						
							| 
									
										
										
										
											2007-12-26 02:33:49 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool stage2; |