-namespace factor
-{
+namespace factor {
-static const cell context_object_count = 10;
+// 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_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 {
- // First 4 fields accessed directly by compiler. See basis/vm/vm.factor
-
- /* Factor callstack pointers */
- stack_frame *callstack_top;
- stack_frame *callstack_bottom;
-
- /* current datastack top pointer */
- cell datastack;
-
- /* current retain stack top pointer */
- cell retainstack;
-
- /* C callstack pointer */
- cell callstack_save;
-
- /* context-specific special objects, accessed by context-object and
- set-context-object primitives */
- cell context_objects[context_object_count];
-
- segment *datastack_seg;
- segment *retainstack_seg;
- segment *callstack_seg;
-
- context(cell datastack_size, cell retainstack_size, cell callstack_size);
- ~context();
-
- void reset_datastack();
- void reset_retainstack();
- void reset_callstack();
- void reset_context_objects();
- void reset();
-
- cell peek()
- {
- return *(cell *)datastack;
- }
-
- void replace(cell tagged)
- {
- *(cell *)datastack = tagged;
- }
-
- cell pop()
- {
- cell value = peek();
- datastack -= sizeof(cell);
- return value;
- }
-
- void push(cell tagged)
- {
- datastack += sizeof(cell);
- replace(tagged);
- }
-
- static const cell stack_reserved = (64 * sizeof(cell));
-
- void fix_stacks()
- {
- if(datastack + sizeof(cell) < datastack_seg->start
- || datastack + stack_reserved >= datastack_seg->end)
- reset_datastack();
-
- if(retainstack + sizeof(cell) < retainstack_seg->start
- || retainstack + stack_reserved >= retainstack_seg->end)
- reset_retainstack();
- }
+ // First 5 fields accessed directly by compiler. See basis/vm/vm.factor
+
+ // Factor callstack pointers
+ cell callstack_top;
+ cell callstack_bottom;
+
+ // current datastack top pointer
+ cell datastack;
+
+ // current retain stack top pointer
+ cell retainstack;
+
+ // C callstack pointer
+ cell callstack_save;
+
+ segment* datastack_seg;
+ segment* retainstack_seg;
+ segment* callstack_seg;
+
+ // context-specific special objects, accessed by context-object and
+ // set-context-object primitives
+ cell context_objects[context_object_count];
+
+ context(cell ds_size, cell rs_size, cell cs_size);
+ ~context();
+
+ 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);
+
+ cell peek() { return *(cell*)datastack; }
+
+ void replace(cell tagged) { *(cell*)datastack = tagged; }
+
+ cell pop() {
+ cell value = peek();
+ datastack -= sizeof(cell);
+ return value;
+ }
+
+ void push(cell tagged) {
+ datastack += sizeof(cell);
+ replace(tagged);
+ }
};
-VM_C_API void begin_callback(factor_vm *vm);
-VM_C_API void end_callback(factor_vm *vm);
+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);
}