-namespace factor
-{
-
-/* 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 */
+namespace factor {
+
+// Context object count and identifiers must be kept in sync with:
+// core/kernel/kernel.factor
+static const cell context_object_count = 4;
+
+enum context_object {
+ OBJ_NAMESTACK,
+ OBJ_CATCHSTACK,
+ OBJ_CONTEXT,
+ OBJ_IN_CALLBACK_P,
+};
+
+// When the callstack fills up (e.g by to deep recursion), a callstack
+// overflow error is triggered. So before continuing executing on it
+// in general_error(), we chop off this many bytes to have some space
+// to work with. Mac OSX 64 bit needs more than 8192. See issue #1419.
+static const cell stack_reserved = 16384;
+
struct context {
- /* C stack pointer on entry */
- stack_frame *callstack_top;
- stack_frame *callstack_bottom;
- /* current datastack top pointer */
- cell datastack;
+ // First 5 fields accessed directly by compiler. See basis/vm/vm.factor
- /* current retain stack top pointer */
- cell retainstack;
+ // Factor callstack pointers
+ cell callstack_top;
+ cell callstack_bottom;
- /* saved contents of ds register on entry to callback */
- cell datastack_save;
+ // current datastack top pointer
+ cell datastack;
- /* saved contents of rs register on entry to callback */
- cell retainstack_save;
+ // current retain stack top pointer
+ cell retainstack;
- /* callback-bottom stack frame, or NULL for top-level context.
- When nest_stacks() is called, callstack layout with callbacks
- is as follows:
-
- [ C function ]
- [ callback stub in code heap ] <-- this is the magic frame
- [ native frame: c_to_factor() ]
- [ callback quotation frame ] <-- first call frame in call stack
-
- magic frame is retained so that it's XT can be traced and forwarded. */
- stack_frame *magic_frame;
+ // C callstack pointer
+ cell callstack_save;
- /* memory region holding current datastack */
- segment *datastack_region;
+ segment* datastack_seg;
+ segment* retainstack_seg;
+ segment* callstack_seg;
- /* memory region holding current retain stack */
- segment *retainstack_region;
+ // context-specific special objects, accessed by context-object and
+ // set-context-object primitives
+ cell context_objects[context_object_count];
- /* saved special_objects slots on entry to callback */
- cell catchstack_save;
- cell current_callback_save;
+ context(cell ds_size, cell rs_size, cell cs_size);
+ ~context();
- context *next;
-};
+ void reset_datastack();
+ void reset_retainstack();
+ void reset_callstack();
+ void reset_context_objects();
+ void reset();
+ void fix_stacks();
+ void fill_stack_seg(cell top_ptr, segment* seg, cell pattern);
+ vm_error_type address_to_error(cell addr);
-#define ds_bot (ctx->datastack_region->start)
-#define ds_top (ctx->datastack_region->end)
-#define rs_bot (ctx->retainstack_region->start)
-#define rs_top (ctx->retainstack_region->end)
+ cell peek() { return *(cell*)datastack; }
-DEFPUSHPOP(d,ds)
-DEFPUSHPOP(r,rs)
+ void replace(cell tagged) { *(cell*)datastack = tagged; }
-VM_C_API void nest_stacks(stack_frame *magic_frame, factor_vm *vm);
-VM_C_API void unnest_stacks(factor_vm *vm);
+ cell pop() {
+ cell value = peek();
+ datastack -= sizeof(cell);
+ return value;
+ }
-}
+ void push(cell tagged) {
+ datastack += sizeof(cell);
+ replace(tagged);
+ }
+};
+VM_C_API context* new_context(factor_vm* parent);
+VM_C_API void delete_context(factor_vm* parent);
+VM_C_API void reset_context(factor_vm* parent);
+VM_C_API cell begin_callback(factor_vm* parent, cell quot);
+VM_C_API void end_callback(factor_vm* parent);
+
+}