view 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 source

 
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)