Mercurial > repos > rhope
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 |