factor/vm/contexts.hpp

82 lines
1.6 KiB
C++

namespace factor
{
static const cell context_object_count = 10;
enum context_object {
OBJ_NAMESTACK,
OBJ_CATCHSTACK,
OBJ_CONTEXT_ID,
};
/* 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;
/* memory region holding current datastack */
segment *datastack_region;
/* 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];
context *next;
context(cell ds_size, cell rs_size);
void reset_datastack();
void reset_retainstack();
void reset_context_objects();
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_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();
}
};
VM_C_API void nest_stacks(factor_vm *vm);
VM_C_API void unnest_stacks(factor_vm *vm);
}