changeset 176:327bcf35e094

Add bytecode interpreter
author Mike Pavone <pavone@retrodev.com>
date Wed, 08 Jun 2011 23:24:29 -0700
parents 03e4fa277291
children e57c151f351e
files cbackend_c.rhope nworker_c.rhope runtime/builtinworkers.c runtime/rhopefuncs_prolog.c
diffstat 4 files changed, 145 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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"]
 }
--- 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]
--- 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
+
--- 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;