]> gitweb.factorcode.org Git - factor.git/blobdiff - vm/contexts.hpp
audio.engine.test: cleanup using
[factor.git] / vm / contexts.hpp
index 14a853bf37927c3fdcd3d92dcac3bc9803fddd27..945b9cda7d50ae9d5fd1f9ecbb3bb36aa25be61f 100644 (file)
@@ -1,92 +1,79 @@
-namespace factor
-{
+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;
 
-/* Assembly code makes assumptions about the layout of this struct */
 struct context {
-       /* C stack pointer on entry */
-       stack_frame *callstack_top;
-       stack_frame *callstack_bottom;
-
-       /* current datastack top pointer */
-       cell datastack;
-
-       /* 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;
-
-       /* memory region holding current datastack */
-       segment *datastack_region;
-
-       /* memory region holding current retain stack */
-       segment *retainstack_region;
-
-       /* saved special_objects slots on entry to callback */
-       cell catchstack_save;
-       cell current_callback_save;
-
-       context *next;
-
-       context(cell ds_size, cell rs_size);
-
-       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);
-       }
-
-       void reset_datastack()
-       {
-               datastack = datastack_region->start - sizeof(cell);
-       }
-
-       void reset_retainstack()
-       {
-               retainstack = retainstack_region->start - sizeof(cell);
-       }
-
-       static const cell stack_reserved = (64 * sizeof(cell));
-
-       void fix_stacks()
-       {
-               if(datastack + sizeof(cell) < datastack_region->start
-                       || datastack + stack_reserved >= datastack_region->end)
-                       reset_datastack();
-
-               if(retainstack + sizeof(cell) < retainstack_region->start
-                       || retainstack + stack_reserved >= retainstack_region->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 nest_stacks(stack_frame *magic_frame, factor_vm *vm);
-VM_C_API void unnest_stacks(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);
 
 }