]> gitweb.factorcode.org Git - factor.git/blob - vm/contexts.hpp
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / vm / contexts.hpp
1 namespace factor
2 {
3
4 /* Assembly code makes assumptions about the layout of this struct:
5    - callstack_top field is 0
6    - callstack_bottom field is 1
7    - datastack field is 2
8    - retainstack field is 3 */
9 struct context {
10         /* C stack pointer on entry */
11         stack_frame *callstack_top;
12         stack_frame *callstack_bottom;
13
14         /* current datastack top pointer */
15         cell datastack;
16
17         /* current retain stack top pointer */
18         cell retainstack;
19
20         /* saved contents of ds register on entry to callback */
21         cell datastack_save;
22
23         /* saved contents of rs register on entry to callback */
24         cell retainstack_save;
25
26         /* callback-bottom stack frame, or NULL for top-level context.
27         When nest_stacks() is called, callstack layout with callbacks
28         is as follows:
29         
30         [ C function ]
31         [ callback stub in code heap ] <-- this is the magic frame
32         [ native frame: c_to_factor() ]
33         [ callback quotation frame ] <-- first call frame in call stack
34         
35         magic frame is retained so that it's XT can be traced and forwarded. */
36         stack_frame *magic_frame;
37
38         /* memory region holding current datastack */
39         segment *datastack_region;
40
41         /* memory region holding current retain stack */
42         segment *retainstack_region;
43
44         /* saved special_objects slots on entry to callback */
45         cell catchstack_save;
46         cell current_callback_save;
47
48         context *next;
49
50         context(cell ds_size, cell rs_size);
51 };
52
53 #define ds_bot (ctx->datastack_region->start)
54 #define ds_top (ctx->datastack_region->end)
55 #define rs_bot (ctx->retainstack_region->start)
56 #define rs_top (ctx->retainstack_region->end)
57
58 inline cell dpeek()
59 {
60         return *(cell *)ds;
61 }
62
63 inline void drepl(cell tagged)
64 {
65         *(cell *)ds = tagged;
66 }
67
68 inline cell dpop()
69 {
70         cell value = dpeek();
71         ds -= sizeof(cell);
72         return value;
73 }
74
75 inline void dpush(cell tagged)
76 {
77         ds += sizeof(cell);
78         drepl(tagged);
79 }
80
81 VM_C_API void nest_stacks(stack_frame *magic_frame, factor_vm *vm);
82 VM_C_API void unnest_stacks(factor_vm *vm);
83
84 }