# HG changeset patch # User Mike Pavone # Date 1307600669 25200 # Node ID 327bcf35e094b7797aaa92a34d224ab5d1169e60 # Parent 03e4fa2772913d363e2a9801a31203a4effcbcee Add bytecode interpreter diff -r 03e4fa277291 -r 327bcf35e094 cbackend_c.rhope --- a/cbackend_c.rhope Wed Jun 08 23:24:15 2011 -0700 +++ b/cbackend_c.rhope Wed Jun 08 23:24:29 2011 -0700 @@ -598,6 +598,7 @@ + Do AddRef@C Function[func,psource,pdest:out] { source <- [psource]Make Op[func] @@ -1545,12 +1546,12 @@ { out <- [[[[["typedef enum {\n" ]Append[Fold[_Dispatch Enum[?], - [Fold[_Dispatch Enum Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tFUNC_Build,\n\tFUNC_BlueprintSP_Of,\n\tFUNC_ID,\n\tFUNC_BlueprintSP_FromSP_ID,\n\tFUNC_Pause,\n\tRES_1_Pause,\n\tFUNC_Resume,\n"], + [Fold[_Dispatch Enum Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tFUNC_Build,\n\tFUNC_BlueprintSP_Of,\n\tFUNC_ID,\n\tFUNC_BlueprintSP_FromSP_ID,\n\tFUNC_Pause,\n\tRES_1_Pause,\n\tFUNC_Resume,\n\tFUNC_RunSP_Bytecode,\n\tRES_1_RunSP_Bytecode,\n"], [program]Functions >>]] ]Append["\tEND,\n\tEND_THREAD\n} funcids;\n\n"] ]Append["#define DispatchEntries \\\n"] ]Append[Fold[_Dispatch Switch[?], - [Fold[_Dispatch Switch Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tDispatchEntry(Build)\\\n\tDispatchEntry(BlueprintSP_Of)\\\n\tDispatchEntry(ID)\\\n\tDispatchEntry(BlueprintSP_FromSP_ID)\\\n\tDispatchEntry(Pause)\\\n\tResumeEntry(1,Pause)\\\n\tDispatchEntry(Resume)\\\n"], + [Fold[_Dispatch Switch Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tDispatchEntry(Build)\\\n\tDispatchEntry(BlueprintSP_Of)\\\n\tDispatchEntry(ID)\\\n\tDispatchEntry(BlueprintSP_FromSP_ID)\\\n\tDispatchEntry(Pause)\\\n\tResumeEntry(1,Pause)\\\n\tDispatchEntry(Resume)\\\n\tDispatchEntry(RunSP_Bytecode)\\\n\tResumeEntry(1,RunSP_Bytecode)\\\n"], [program]Functions >>]] ]Append["\tEndEntry\\\n\tEndThreadEntry\n\n"] } diff -r 03e4fa277291 -r 327bcf35e094 nworker_c.rhope --- a/nworker_c.rhope Wed Jun 08 23:24:15 2011 -0700 +++ b/nworker_c.rhope Wed Jun 08 23:24:29 2011 -0700 @@ -1661,7 +1661,7 @@ Register Builtins@NProgram[prog:out] { - registered <- [[[[[[[[[[[prog]Register Worker["Print", "rhope", 1, 1] + registered <- [[[[[[[[[[[[prog]Register Worker["Print", "rhope", 1, 1] ]Register Worker["If@Boolean", "rhope", 1, 2] ]Register Worker["Build", "rhope", 1, 1] ]Register Worker["Blueprint Of", "rhope", 1, 1] @@ -1671,9 +1671,10 @@ ]Register Worker["Blueprint From ID", "rhope", 1, 2] ]Register Worker["Pause", "rhope", 1, 1] ]Register Worker["Resume", "rhope", 2, 2] + ]Register Worker["Run Bytecode", "rhope", 2, 1] ]Register Number Methods - out <- [[[[[[[[[registered]Bind Worker["If@Boolean", + out <- [[[[[[[[[[registered]Bind Worker["If@Boolean", [[[[[NWorker["rhope"] ]Inputs <<[("condition")] ]Input Types <<[ [()]Append[Type Instance["Boolean"]] ] @@ -1736,6 +1737,14 @@ ]Outputs <<[("success","cantresume")] ]Output Types <<[ [[()]Append[Type Instance["Any Type"]]]Append[Type Instance["Any Type"]] ] ]Builtin? <<[Yes]] + ]Bind Worker["Run Bytecode", + [[[[[NWorker["rhope"] + ]Inputs <<[("bytecode","constants")] + ]Input Types <<[ [[()]Append[Type Instance["Array"]]]Append[Type Instance["Boxed Array"]] ] + ]Outputs <<[("ret1")] + ]Output Types <<[ [()]Append[Type Instance["Any Type"]] ] + ]Builtin? <<[Yes] + ] } Find Worker@NProgram[prog, name:out,notfound] diff -r 03e4fa277291 -r 327bcf35e094 runtime/builtinworkers.c --- 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 + diff -r 03e4fa277291 -r 327bcf35e094 runtime/rhopefuncs_prolog.c --- a/runtime/rhopefuncs_prolog.c Wed Jun 08 23:24:15 2011 -0700 +++ b/runtime/rhopefuncs_prolog.c Wed Jun 08 23:24:29 2011 -0700 @@ -12,6 +12,27 @@ struct timeval proftime; #endif uint16_t resume,idx, vcparam_offset, last_vcparam; + uint32_t *bytecode, *cur_instruction, op1, op2, accum; + object ** interp_consts; + void * interp_dispatch[] = { + &&interp_call, + &&interp_param, + &&interp_load, + &&interp_and, + &&interp_or, + &&interp_not, + &&interp_branch, + &&interp_saveresult, + &&interp_addref, + &&interp_release, + &&interp_return, + &&interp_nop, + &&interp_nop, + &&interp_nop, + &&interp_nop, + &&interp_nop + }; + context *ct,*temp_ct; void *tmp; calldata * cdata, *temp_cdata, *my_cdata; @@ -20,4 +41,5 @@ FuncDef(BlueprintSP_Of) FuncDef(ID) FuncDef(BlueprintSP_FromSP_ID) + void ** lv_RunSP_Bytecode;