comparison runtime/builtinworkers.c @ 176:327bcf35e094

Add bytecode interpreter
author Mike Pavone <pavone@retrodev.com>
date Wed, 08 Jun 2011 23:24:29 -0700
parents bac2c74801f0
children e57c151f351e
comparison
equal deleted inserted replaced
175:03e4fa277291 176:327bcf35e094
97 my_cdata->params[0] = NULL; 97 my_cdata->params[0] = NULL;
98 } 98 }
99 EndFuncNoLocals 99 EndFuncNoLocals
100 DISPATCH 100 DISPATCH
101 101
102 f_RunSP_Bytecode:
103 sf_RunSP_Bytecode:
104 Param(0, TYPE_ARRAY)
105 Param(1, TYPE_BOXEDARRAY)
106
107 if(((t_Array *)cdata->params[0])->payload.Eltype->bp->type_id != TYPE_UINT32)
108 {
109 printf("Array has element type of %d, but bytecode must be an array with element type UInt32\n", ((t_Array *)cdata->params[0])->payload.Eltype->bp->type_id);
110 goto _exception;
111 }
112 my_cdata = cdata;
113 bytecode = (uint32_t *)(((t_Array *)cdata->params[0])+1);
114 for(idx = 2; idx < (bytecode[0]+2); ++idx)
115 if(bytecode[idx+1])
116 {
117 Param(idx, bytecode[idx+1])
118 }
119 cur_instruction = bytecode+idx;
120 while(idx < cdata->num_params)
121 release_ref(cdata->params[idx++]);
122 cdata->num_params = bytecode[0];
123 interp_consts = (object **)(((t_BoxedSP_Array *)cdata->params[1])+1);
124 lv_RunSP_Bytecode = alloc_stack(ct, sizeof(object *)*(bytecode[1]+1));
125
126 PrepCall(bytecode[2])
127
128 goto *interp_dispatch[*(++cur_instruction)&0xF];
129 interp_call:
130 *lv_RunSP_Bytecode = cur_instruction;
131
132 cdata->func = RES_1_RunSP_Bytecode;
133 cdata->num_params = *cur_instruction >> 24;
134 cdata->vars = lv_RunSP_Bytecode;
135 func = *cur_instruction >> 4 & 0xFFFFF;
136 DISPATCH
137 r1_RunSP_Bytecode:
138 my_cdata = cdata->lastframe;
139 lv_RunSP_Bytecode = cdata->vars;
140
141 interp_consts = (object **)(((t_BoxedSP_Array *)my_cdata->params[1])+1);
142 cur_instruction = *lv_RunSP_Bytecode;
143 goto *interp_dispatch[*(++cur_instruction)&0xF];
144 interp_param:
145 op1 = (*cur_instruction >> 4) & 0x3FFF;
146 SetParam(*cur_instruction >> 24, op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1])
147 goto *interp_dispatch[*(++cur_instruction)&0xF];
148 interp_load:
149 op1 = (*cur_instruction >> 4) & 0x3FFF;
150 accum = op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1];
151 goto *interp_dispatch[*(++cur_instruction)&0xF];
152 interp_and:
153 op1 = (*cur_instruction >> 4) & 0x3FFF;
154 op2 = *cur_instruction >> 18;
155 if (!op1)
156 {
157 accum = accum && (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]);
158 } else {
159 accum = (op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]) && (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]);
160 }
161 goto *interp_dispatch[*(++cur_instruction)&0xF];
162 interp_or:
163 op1 = (*cur_instruction >> 4) & 0x3FFF;
164 op2 = *cur_instruction >> 18;
165 if (!op1)
166 {
167 accum = accum || (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]);
168 } else {
169 accum = (op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]) || (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]);
170 }
171 goto *interp_dispatch[*(++cur_instruction)&0xF];
172 interp_not:
173 accum = !accum;
174 goto *interp_dispatch[*(++cur_instruction)&0xF];
175 interp_branch:
176 if (accum)
177 if (*cur_instruction & 0x8)
178 cur_instruction += *cur_instruction >> 5;
179 else
180 cur_instruction -= *cur_instruction >> 5;
181 else
182 cur_instruction++;
183 goto *interp_dispatch[*cur_instruction];
184 interp_saveresult:
185 op1 = (*cur_instruction >> 4) & 0x1FFF;
186 lv_RunSP_Bytecode[op1] = cdata->params[*cur_instruction >> 24];
187 goto *interp_dispatch[*(++cur_instruction)&0xF];
188 interp_addref:
189 op1 = (*cur_instruction >> 4) & 0x3FFF;
190 add_ref(op1 >= 0x2000 ? interp_consts[op1-0x2000] : (object *)lv_RunSP_Bytecode[op1]);
191 goto *interp_dispatch[*(++cur_instruction)&0xF];
192 interp_release:
193 op1 = (*cur_instruction >> 4) & 0x3FFF;
194 release_ref(op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]);
195 goto *interp_dispatch[*(++cur_instruction)&0xF];
196 interp_nop:
197 goto *interp_dispatch[*(++cur_instruction)&0xF];
198 interp_return:
199 FreeCall
200 release_ref(my_cdata->params[0]);
201 release_ref(my_cdata->params[1]);
202 op1 = (*cur_instruction >> 4) & 0x3FFF;
203 op2 = *cur_instruction >> 24;
204 for (idx = 0; idx < op2; ++idx)
205 {
206 Ret(idx, lv_RunSP_Bytecode[op1+idx])
207 }
208 EndFunc(RunSP_Bytecode)
209 DISPATCH
210