Mercurial > repos > rhope
diff 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 |
line wrap: on
line diff
--- a/runtime/builtinworkers.c Wed Jun 08 23:24:15 2011 -0700 +++ b/runtime/builtinworkers.c Wed Jun 08 23:24:29 2011 -0700 @@ -99,3 +99,112 @@ EndFuncNoLocals DISPATCH +f_RunSP_Bytecode: +sf_RunSP_Bytecode: + Param(0, TYPE_ARRAY) + Param(1, TYPE_BOXEDARRAY) + + if(((t_Array *)cdata->params[0])->payload.Eltype->bp->type_id != TYPE_UINT32) + { + 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); + goto _exception; + } + my_cdata = cdata; + bytecode = (uint32_t *)(((t_Array *)cdata->params[0])+1); + for(idx = 2; idx < (bytecode[0]+2); ++idx) + if(bytecode[idx+1]) + { + Param(idx, bytecode[idx+1]) + } + cur_instruction = bytecode+idx; + while(idx < cdata->num_params) + release_ref(cdata->params[idx++]); + cdata->num_params = bytecode[0]; + interp_consts = (object **)(((t_BoxedSP_Array *)cdata->params[1])+1); + lv_RunSP_Bytecode = alloc_stack(ct, sizeof(object *)*(bytecode[1]+1)); + + PrepCall(bytecode[2]) + + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_call: + *lv_RunSP_Bytecode = cur_instruction; + + cdata->func = RES_1_RunSP_Bytecode; + cdata->num_params = *cur_instruction >> 24; + cdata->vars = lv_RunSP_Bytecode; + func = *cur_instruction >> 4 & 0xFFFFF; + DISPATCH +r1_RunSP_Bytecode: + my_cdata = cdata->lastframe; + lv_RunSP_Bytecode = cdata->vars; + + interp_consts = (object **)(((t_BoxedSP_Array *)my_cdata->params[1])+1); + cur_instruction = *lv_RunSP_Bytecode; + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_param: + op1 = (*cur_instruction >> 4) & 0x3FFF; + SetParam(*cur_instruction >> 24, op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]) + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_load: + op1 = (*cur_instruction >> 4) & 0x3FFF; + accum = op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]; + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_and: + op1 = (*cur_instruction >> 4) & 0x3FFF; + op2 = *cur_instruction >> 18; + if (!op1) + { + accum = accum && (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]); + } else { + accum = (op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]) && (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]); + } + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_or: + op1 = (*cur_instruction >> 4) & 0x3FFF; + op2 = *cur_instruction >> 18; + if (!op1) + { + accum = accum || (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]); + } else { + accum = (op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]) || (op2 >= 0x2000 ? interp_consts[op2-0x2000] : lv_RunSP_Bytecode[op2]); + } + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_not: + accum = !accum; + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_branch: + if (accum) + if (*cur_instruction & 0x8) + cur_instruction += *cur_instruction >> 5; + else + cur_instruction -= *cur_instruction >> 5; + else + cur_instruction++; + goto *interp_dispatch[*cur_instruction]; +interp_saveresult: + op1 = (*cur_instruction >> 4) & 0x1FFF; + lv_RunSP_Bytecode[op1] = cdata->params[*cur_instruction >> 24]; + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_addref: + op1 = (*cur_instruction >> 4) & 0x3FFF; + add_ref(op1 >= 0x2000 ? interp_consts[op1-0x2000] : (object *)lv_RunSP_Bytecode[op1]); + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_release: + op1 = (*cur_instruction >> 4) & 0x3FFF; + release_ref(op1 >= 0x2000 ? interp_consts[op1-0x2000] : lv_RunSP_Bytecode[op1]); + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_nop: + goto *interp_dispatch[*(++cur_instruction)&0xF]; +interp_return: + FreeCall + release_ref(my_cdata->params[0]); + release_ref(my_cdata->params[1]); + op1 = (*cur_instruction >> 4) & 0x3FFF; + op2 = *cur_instruction >> 24; + for (idx = 0; idx < op2; ++idx) + { + Ret(idx, lv_RunSP_Bytecode[op1+idx]) + } +EndFunc(RunSP_Bytecode) +DISPATCH +