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