factor/vm/contexts.hpp

64 lines
1.6 KiB
C++

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 */
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;
/* saved contents of ds register on entry to callback */
cell datastack_save;
/* saved contents of rs register on entry to callback */
cell retainstack_save;
/* 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 userenv slots on entry to callback */
cell catchstack_save;
cell current_callback_save;
context *next;
};
#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)
DEFPUSHPOP(d,ds)
DEFPUSHPOP(r,rs)
VM_C_API void nest_stacks(stack_frame *magic_frame, factor_vm *vm);
VM_C_API void unnest_stacks(factor_vm *vm);
}