xref: /inferno-os/libinterp/stack.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include "lib9.h"
2 #include "isa.h"
3 #include "interp.h"
4 #include "raise.h"
5 #include <pool.h>
6 
7 #define T(r)	*((void**)(R.r))
8 
9 void
newstack(Prog * p)10 newstack(Prog *p)
11 {
12 	int l;
13 	Type *t;
14 	Frame *f;
15 	Stkext *ns;
16 
17 	f = T(s);
18 
19 	t = f->t;
20 	if(t == nil)
21 		t = SEXTYPE(f)->reg.TR;
22 
23 	f->lr = nil;
24 	f->mr = nil;
25 	f->fp = nil;
26 	l = p->R.M->m->ss;
27 	/* 16 bytes for Stkext record keeping */
28 	if(l < t->size+16)
29 		l = t->size+16;
30 	ns = mallocz(l, 0);
31 	if(ns == nil)
32 		error(exNomem);
33 
34 	ns->reg.TR = t;
35 	ns->reg.SP = nil;
36 	ns->reg.TS = nil;
37 	ns->reg.EX = nil;
38 	p->R.EX = ns->stack;
39 	p->R.TS = ns->stack + l;
40 	p->R.SP = ns->reg.tos.fu + t->size;
41 	p->R.FP = ns->reg.tos.fu;
42 
43 	memmove(p->R.FP, f, t->size);
44 	f = (Frame*)p->R.FP;
45 	f->t = nil;
46 }
47 
48 void
extend(void)49 extend(void)
50 {
51 	int l;
52 	Type *t;
53 	Frame *f;
54 	Stkext *ns;
55 
56 	t = R.s;
57 	l = R.M->m->ss;
58 	/* 16 bytes for Stkext record keeping */
59 	if(l < t->size+16)
60 		l = 2*t->size+16;
61 	ns = mallocz(l, 0);
62 	if(ns == nil)
63 		error(exNomem);
64 
65 	ns->reg.TR = t;
66 	ns->reg.SP = R.SP;
67 	ns->reg.TS = R.TS;
68 	ns->reg.EX = R.EX;
69 	f = ns->reg.tos.fr;
70 	f->t  = nil;
71 	f->mr = nil;
72 	R.s = f;
73 	R.EX = ns->stack;
74 	R.TS = ns->stack + l;
75 	R.SP = ns->reg.tos.fu + t->size;
76 
77 	if (t->np)
78 		initmem(t, f);
79 }
80 
81 void
unextend(Frame * f)82 unextend(Frame *f)
83 {
84 	Stkext *sx;
85 	Type *t;
86 
87 	sx = SEXTYPE(f);
88 	R.SP = sx->reg.SP;
89 	R.TS = sx->reg.TS;
90 	R.EX = sx->reg.EX;
91 	t = sx->reg.TR;
92 	if (t->np)
93 		freeptrs(f, t);
94 	free(sx);
95 }
96 
97 void
unframe(void)98 unframe(void)
99 {
100 	Type *t;
101 	Frame *f;
102 	Stkext *sx;
103 
104 	f = (Frame*)R.FP;
105 	t = f->t;
106 	if(t == nil)
107 		t = SEXTYPE(f)->reg.TR;
108 
109 	R.SP = R.FP+t->size;
110 
111 	f = T(s);
112 	if(f->t == nil) {
113 		sx = SEXTYPE(f);
114 		R.TS = sx->reg.TS;
115 		R.EX = sx->reg.EX;
116 		free(sx);
117 	}
118 }
119