]> 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 struct context {
6         /* C stack pointer on entry */
7         stack_frame *callstack_top;
8         stack_frame *callstack_bottom;
9
10         /* current datastack top pointer */
11         cell datastack;
12
13         /* current retain stack top pointer */
14         cell retainstack;
15
16         /* callback-bottom stack frame, or NULL for top-level context.
17         When nest_stacks() is called, callstack layout with callbacks
18         is as follows:
19         
20         [ C function ]
21         [ callback stub in code heap ] <-- this is the magic frame
22         [ native frame: c_to_factor() ]
23         [ callback quotation frame ] <-- first call frame in call stack
24         
25         magic frame is retained so that it's XT can be traced and forwarded. */
26         stack_frame *magic_frame;
27
28         /* memory region holding current datastack */
29         segment *datastack_region;
30
31         /* memory region holding current retain stack */
32         segment *retainstack_region;
33
34         /* saved special_objects slots on entry to callback */
35         cell catchstack_save;
36         cell current_callback_save;
37
38         context *next;
39
40         context(cell ds_size, cell rs_size);
41
42         cell peek()
43         {
44                 return *(cell *)datastack;
45         }
46
47         void replace(cell tagged)
48         {
49                 *(cell *)datastack = tagged;
50         }
51
52         cell pop()
53         {
54                 cell value = peek();
55                 datastack -= sizeof(cell);
56                 return value;
57         }
58
59         void push(cell tagged)
60         {
61                 datastack += sizeof(cell);
62                 replace(tagged);
63         }
64
65         void reset_datastack()
66         {
67                 datastack = datastack_region->start - sizeof(cell);
68         }
69
70         void reset_retainstack()
71         {
72                 retainstack = retainstack_region->start - sizeof(cell);
73         }
74
75         static const cell stack_reserved = (64 * sizeof(cell));
76
77         void fix_stacks()
78         {
79                 if(datastack + sizeof(cell) < datastack_region->start
80                         || datastack + stack_reserved >= datastack_region->end)
81                         reset_datastack();
82
83                 if(retainstack + sizeof(cell) < retainstack_region->start
84                         || retainstack + stack_reserved >= retainstack_region->end)
85                         reset_retainstack();
86         }
87 };
88
89 VM_C_API void nest_stacks(stack_frame *magic_frame, factor_vm *vm);
90 VM_C_API void unnest_stacks(factor_vm *vm);
91
92 }