Mercurial > repos > rhope
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) +