Added cons.
[mozart2.git] / vm.cc
blobf453cf64d5849d4635c5863dcba63085418d79ef
1 struct XSet {
2 size_t count;
3 bool set[X_COUNT];
4 bool mask[X_COUNT];
5 XSet():count(0){
6 for(unsigned int i=0;i<X_COUNT;++i){
7 set[i]=false;
8 mask[i]=true;
11 void read(ptrdiff_t i){
12 if(mask[i]&&!set[i]){
13 set[i]=true;
14 ++count;
17 void write(ptrdiff_t i){
18 mask[i]=false;
20 void arity(size_t s){
21 for(unsigned int i=0;i<s;++i)read(i);
23 void finish(long s){
24 if(s<0){
25 for(int i=0;i<-s;++i)read(i);
26 }else{
27 int i=0;
28 while(s){
29 if(s&1)read(i);
30 s>>=1;
31 ++i;
36 bool VM::run(){
37 if(!initialized){
38 stackTable[S_CONT]=&&stackCont;
39 stackTable[S_GC_CONT]=&&stackGCCont;
40 stackTable[S_X]=&&stackX;
41 //PP_FOR_EACH_INSTR(«
42 instrTable[I_«»PP_INSTR_NAME]=&&lbl_«»PP_INSTR_NAME;
43 //»,«»)
44 //VMInit
45 initialized=1;
46 return 0;
48 do{
49 UnstableNode curThread;
50 VM &vm=*this;
51 threads.get(vm, curThread);
52 Instr* startIP=0;
53 Instr* IP=0;
54 UnstableNode* Y=0;
55 size_t numY=0;
56 StableNode* G=0;
57 StackFrameHeader* stackTop=deref(curThread).vt->stackTop(deref(curThread));
58 StableNode* wPtr=0;
59 BIStatus* st=0;
60 goto lbl_doPop;
61 //PP_FOR_EACH_INSTR(«
62 lbl_«»PP_INSTR_NAME:
64 s_«»PP_INSTR_NAME &i __attribute__((unused)) =*(s_«»PP_INSTR_NAME *)IP;
65 IP+=sizeof(s_«»PP_INSTR_NAME)/sizeof(Instr);
66 PP_INSTR_CODE;
67 goto **IP;
69 //»,«»)
70 specialStatus:
71 //Do something
72 goto lbl_doPop;
73 stackGCCont:
75 GCContStackFrame &f=*(GCContStackFrame*)stackTop;
76 stackTop=f.next;
77 Y=f.Y;
78 numY=f.numY;
79 Node &n=deref(f.abstr);
80 Instr* nIP;
81 StableNode* nG;
82 n.vt->call(n, nIP, nG, -1);
83 startIP=nIP;
84 IP=nIP+f.offset;
85 G=nG;
86 free(&f,1);
87 if(scheduleNext())goto nextThread;
88 goto **IP;
90 stackCont:
92 ContStackFrame &f=*(ContStackFrame*)stackTop;
93 stackTop=f.next;
94 startIP=f.startIP;
95 IP=f.IP;
96 Y=f.Y;
97 numY=f.numY;
98 G=f.G;
99 free(&f,1);
100 if(scheduleNext())goto nextThread;
101 goto **IP;
103 stackX:
105 XStackFrame &f=*(XStackFrame*)stackTop;
106 stackTop=f.next;
107 for(unsigned int i=0;i<f.count;++i){
108 SavedX &s=f.ptr[i];
109 move(X[s.x],s.r);
111 free(f.ptr,f.count);
112 free(&f,1);
113 goto lbl_doPop;
115 stackEmpty:
116 //Do something
117 return 0;
118 nextThread:
120 ContStackFrame *fc=alloc<ContStackFrame>(1);
121 fc->kind=&&stackCont;
122 fc->next=stackTop;
123 fc->startIP=startIP;
124 fc->IP=IP;
125 fc->Y=Y;
126 fc->numY=numY;
127 fc->G=G;
128 XSet live;
129 while(1){
130 //PP_FOR_EACH_INSTR(«
131 if(*IP==&&lbl_«»PP_INSTR_NAME)
133 s_«»PP_INSTR_NAME &i __attribute__((unused)) =*(s_«»PP_INSTR_NAME *)IP;
134 IP+=sizeof(s_«»PP_INSTR_NAME)/sizeof(Instr);
135 m4_dnl /*
136 PP_FOR_EACH_INSTR_PARAM(«
137 m4_ifelse(m4_defn(«PP_INSTR_PARAM_TYPE»),«WX»,«live.write(i.»PP_INSTR_PARAM_NAME«-X);»,
138 m4_defn(«PP_INSTR_PARAM_TYPE»),«RX»,«live.read(i.»PP_INSTR_PARAM_NAME«-X);»,
139 m4_defn(«PP_INSTR_PARAM_TYPE»),«PA»,«live.arity(i.»PP_INSTR_PARAM_NAME«);break;»,
140 m4_defn(«PP_INSTR_PARAM_TYPE»),«LX»,«live.finish(i.»PP_INSTR_PARAM_NAME«);break;»)»
141 ,«»)
142 m4_dnl */
144 else
145 //»,«»)
146 {/*should never be reached*/}
148 XStackFrame *fx=alloc<XStackFrame>(1);
149 fx->kind=&&stackX;
150 fx->next=fc;
151 fx->count=live.count;
152 fx->ptr=alloc<SavedX>(live.count);
153 int j=0;
154 for(unsigned int i=0;i<live.count;++i){
155 while(!live.set[j])++j;
156 SavedX &s=(fx->ptr)[i];
157 s.x=j;
158 move(s.r,X[j]);
159 ++j;
161 deref(curThread).vt->stackTop(deref(curThread))=fx;
162 threads.schedule(vm, curThread);
164 }while(!interrupted());
165 return 1;
167 void VM::pushCall(Node &thread, Node &proc){
168 Node &t=deref(thread);
169 StackFrameHeader* &stackTop=t.vt->stackTop(t);
170 ContStackFrame *f=alloc<ContStackFrame>(1);
171 Node &n=deref(proc);
172 f->kind=stackTable[S_CONT];
173 f->next=stackTop;
174 f->Y=0;
175 f->numY=0;
176 n.vt->call(n,f->IP,f->G,0);
177 f->startIP=f->IP;
178 stackTop=f;
180 void VM::gc(){
181 exchange(active,shadow);
182 exchange(bigEmulAlloc,bigEmulAllocShadow);
183 exchange(smallEmulAlloc,smallEmulAllocShadow);
184 uniques.gc();
185 GC* gc=allocShadow<GC>(1);
186 new((void*)gc)GC(*this);
187 threads.gc(*gc);
188 gc->process();
189 bigEmulAllocShadow.clear();
190 smallEmulAllocShadow.clear();
191 shadow.release();
193 void VM::gcStack(GC &gc, StackFrameHeader* &from, StackFrameHeader* &to){
194 StackFrameHeader* f=from;
195 StackFrameHeader** t=&to;
196 size_t count=0;
197 while(f){
198 count++;
199 if(f->kind==stackTable[S_CONT]){
200 *t=alloc<GCContStackFrame>(1);
201 GCContStackFrame &tt=*(GCContStackFrame*)*t;
202 ContStackFrame &ff=*(ContStackFrame*)f;
203 tt.kind=stackTable[S_GC_CONT];
204 tt.offset=ff.IP-ff.startIP;
205 tt.numY=ff.numY;
206 new((void*)&(tt.abstr)) UnstableNode(gc,ff.G[-1]);
207 tt.Y=alloc<UnstableNode>(ff.numY);
208 for(unsigned int i=0;i<ff.numY;++i){
209 new((void*)&(tt.Y[i])) UnstableNode(gc,ff.Y[i]);
211 f=f->next;
212 t=&(tt.next);
213 freeShadow(&ff,1);
214 }else if(f->kind==stackTable[S_GC_CONT]){
215 *t=alloc<GCContStackFrame>(1);
216 GCContStackFrame &tt=*(GCContStackFrame*)*t;
217 GCContStackFrame &ff=*(GCContStackFrame*)f;
218 tt.kind=ff.kind;
219 tt.offset=ff.offset;
220 tt.numY=ff.numY;
221 new((void*)&(tt.abstr)) UnstableNode(gc,ff.abstr);
222 tt.Y=alloc<UnstableNode>(ff.numY);
223 for(unsigned int i=0;i<ff.numY;++i){
224 new((void*)&(tt.Y[i])) UnstableNode(gc,ff.Y[i]);
226 f=f->next;
227 t=&(tt.next);
228 }else if(f->kind==stackTable[S_X]){
229 *t=alloc<XStackFrame>(1);
230 XStackFrame &tt=*(XStackFrame*)*t;
231 XStackFrame &ff=*(XStackFrame*)f;
232 tt.kind=ff.kind;
233 tt.count=ff.count;
234 tt.ptr=alloc<SavedX>(ff.count);
235 for(unsigned int i=0;i<ff.count;++i){
236 tt.ptr[i].x=ff.ptr[i].x;
237 new((void*)&(tt.ptr[i].r)) UnstableNode(gc,ff.ptr[i].r);
239 f=f->next;
240 t=&(tt.next);
241 freeShadow(&ff,1);
242 }else{/*never reached*/}
244 *t=0;