diff runtime/func_raw.h @ 186:ba35ab624ec2

Add support for raw C function output from C backend as well as an option to use Boehm-GC instead of reference counting
author Mike Pavone <pavone@retrodev.com>
date Fri, 07 Oct 2011 00:10:02 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runtime/func_raw.h	Fri Oct 07 00:10:02 2011 -0700
@@ -0,0 +1,181 @@
+ 
+typedef struct {
+	int num_ret;
+	object ** retvals;
+} returntype;
+
+typedef returntype (*rhope_func)(int, object **);
+
+#define DispatchEntry(name) f_ ## name,
+#define ResumeEntry(num,name)
+#define ResEnum(num,name)
+#define DispatchVar rhope_func func_lookup[] = { DispatchEntries };
+#define EndEntry
+#define EndThreadEntry
+#define DISPATCH
+
+#define lv(func,var) lv_ ## var
+#define lvar(type, name) type lv_ ## name;
+#define my_params(num) params[num]
+#define child_params(num) call_params[num]
+#define my_outputs(num) retvals[num]
+
+#define result(num) callret.retvals[num]
+#define numresults callret.num_ret
+
+#define LocalsType(def,func)
+
+#define Func(name, numparams, numret) \
+returntype f_ ## name(int num_params, object ** params) {\
+		ldec_ ## name;\
+		static object * retvals[numret];\
+		object * call_params[32];\
+		int idx, vcparam_offset, last_vcparam;\
+		returntype callret,retinfo = {numret, &retvals};\
+		for(idx = numparams; idx < num_params; ++idx)\
+			release_ref(params[idx]); num_params = numparams;
+			
+#define FuncNoLocals(name, numparams, numret) \
+returntype f_ ## name(int num_params, object ** params) {\
+		object * call_params[32];\
+		static object * retvals[numret];\
+		int idx, vcparam_offset, last_vcparam;\
+		returntype callret,retinfo = {numret, &retvals};\
+		for(idx = numparams; idx < num_params; ++idx)\
+			release_ref(params[idx]); num_params = numparams;
+			
+#define Param(num,convtypeid) \
+	if(get_blueprint(params[num])->type_id != convtypeid)\
+	{\
+		printf("uh oh, need conversion from type %d to type %d for param %d and that's not implemented yet!", get_blueprint(params[num])->type_id, convtypeid, num);\
+		exit(1);\
+	}
+
+#define CopiedParam(num,convtypeid) Param(num,convtypeid) params[num] = copy_object(params[num]);
+
+#define Ret(num,val) retvals[num] = (object *)(val);
+#define NumRet(num)
+
+#define EndFunc(name) return retinfo;}
+#define EndFuncNoLocals return retinfo;}
+
+#define MethodImpl(name,type_name,mytype_id,numparams,numret) \
+returntype f_ ## name ## AT_ ## type_name(int num_params, object ** params) {\
+		if (num_params < 1)\
+		{\
+			printf("Direct call to %s@%s had no arguments!", #name, #type_name);\
+			printf("%d\n", *((char *)0));\
+			exit(1);\
+		}\
+		if(get_blueprint(params[0])->type_id != mytype_id)\
+		{\
+			printf("uh oh, need conversion from type %d to %s(%d) for %s and that's not implemented yet!\n", get_blueprint(params[0])->type_id, #type_name, mytype_id, #name);\
+			exit(1);\
+		}\
+		return m_ ## name ## AT_ ## type_name(num_params, params);\
+}\
+returntype m_ ## name ## AT_ ## type_name(int num_params, object ** params) {\
+		ldec_ ## name ## AT_ ## type_name;\
+		static object * retvals[numret];\
+		object * call_params[32];\
+		int idx, vcparam_offset, last_vcparam;\
+		returntype callret,retinfo = {numret, &retvals};\
+		for(idx = numparams; idx < num_params; ++idx)\
+			release_ref(params[idx]); num_params = numparams;
+			
+			
+#define MethodImplNoLocals(name,type_name,mytype_id,numparams,numret) \
+returntype f_ ## name ## AT_ ## type_name(int num_params, object ** params) {\
+		if (num_params < 1)\
+		{\
+			printf("Direct call to %s@%s had no arguments!", #name, #type_name);\
+			exit(1);\
+		}\
+		if(get_blueprint(params[0])->type_id != mytype_id)\
+		{\
+			printf("uh oh, need conversion from type %d to %s(%d) for %s and that's not implemented yet!\n", get_blueprint(params[0])->type_id, #type_name, mytype_id, #name);\
+			exit(1);\
+		}\
+		return m_ ## name ## AT_ ## type_name(num_params, params);\
+}\
+returntype m_ ## name ## AT_ ## type_name(int num_params, object ** params) {\
+		static object * retvals[numret];\
+		object * call_params[32];\
+		int idx, vcparam_offset, last_vcparam;\
+		returntype callret,retinfo = {numret, &retvals};\
+		for(idx = numparams; idx < num_params; ++idx)\
+			release_ref(params[idx]); num_params = numparams;
+			
+#define Method(name) \
+returntype f_ ## name(int num_params, object ** params) {\
+	switch(get_blueprint(params[0])->type_id)\
+	{
+
+#define EndMethod(mname) \
+	default:\
+		printf("Type ");\
+		fwrite( ((t_Array *)((t_String *)get_blueprint(params[0])->name)->payload.Buffer)+1, 1, ((t_Array *)((t_String *)get_blueprint(params[0])->name)->payload.Buffer)->payload.Length, stdout);\
+		printf("(%d) does not implement method %s\n", get_blueprint(params[0])->type_id, #mname);\
+		printf("%d\n", *((char *)0));\
+		exit(1);\
+	}\
+}
+
+#define MethodDispatch(type_id,name,type_name) \
+	case type_id:\
+		return m_ ## name ## AT_ ## type_name(num_params, params);
+		
+#define FuncDef(name) returntype f_ ## name(int num_params, object ** params);
+#define MethodDef(name) returntype f_ ## name(int num_params, object ** params); returntype m_ ## name(int num_params, object ** params);
+
+#define PrepCall(callspace)
+#define SetParam(num,value) call_params[num] = value;
+#define VCRePrepCall(func,numparams,lastnumparams) \
+	vcparam_offset = 0;\
+	last_vcparam = -1;
+#define VCPrepCall(func,numparams) \
+	vcparam_offset = 0;\
+	last_vcparam = -1;
+#define VCSetParam(func,num,value) \
+	while((num+vcparam_offset) < ((t_Worker *)func)->payload.Size && ((object **)(((t_Worker *)func)+1))[num+vcparam_offset])\
+	{\
+		call_params[num+vcparam_offset] = add_ref(((object **)(((t_Worker *)func)+1))[num+vcparam_offset]);\
+		++vcparam_offset;\
+	}\
+	call_params[num+vcparam_offset] = value;\
+	last_vcparam = num+vcparam_offset;
+	
+#define ValCall(tocall,numparams,resumeto,myname)\
+	last_vcparam++;\
+	while(last_vcparam < ((t_Worker *)tocall)->payload.Size)\
+	{\
+		if (((object **)(((t_Worker *)tocall)+1))[last_vcparam]) \
+			call_params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\
+		++last_vcparam;\
+	}\
+	callret = func_lookup[((t_Worker *)tocall)->payload.Index](numparams + ((t_Worker *)tocall)->payload.Count, &call_params);
+
+#define ValCallNoLocals(tocall,numparams,resumeto,myname)\
+	last_vcparam++;\
+	while(last_vcparam < ((t_Worker *)tocall)->payload.Size)\
+	{\
+		if (((object **)(((t_Worker *)tocall)+1))[last_vcparam]) \
+			call_params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\
+		++last_vcparam;\
+	}\
+	callret = func_lookup[((t_Worker *)tocall)->payload.Index](numparams + ((t_Worker *)tocall)->payload.Count, &call_params);
+	
+#define ValCallPostlude(resumeto,myname)
+#define ValCallNoLocalsPostlude(resumeto,myname)
+
+#define Call(tocall, numparams, resumeto, myname)\
+	callret = f_ ## tocall(numparams, &call_params);
+	
+#define CallNoLocals(tocall, numparams, resumeto, myname)\
+	callret = f_ ## tocall(numparams, &call_params);
+	
+#define FreeCall
+#define FreeCallMethod(myname,mytype)
+#define TPrepCall(callspace)
+#define TCall(tocall, numparams)
+