Mercurial > repos > rhope
view runtime/func.h @ 180:c40e0faa1c92
Add Call to Dict and List
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 19 Jun 2011 10:43:11 -0700 |
parents | d2b941f82d74 |
children | ba35ab624ec2 |
line wrap: on
line source
#ifndef _FUNC_H_ #define _FUNC_H_ typedef struct object object; typedef struct calldata calldata; typedef enum { NORMAL_RETURN=0, EXCEPTION_RETURN, TAIL_RETURN, NO_CONVERSION, STACK_UNWIND } returntype; typedef returntype (*rhope_func)(calldata *); typedef void (*special_func) (object *); #ifdef MULTI_SWITCH #define DispatchEntry(name) case FUNC_##name: goto f_##name; #define ResumeEntry(num,name) case RES_##num##_##name: goto r##num##_##name; #define DispatchVar #define DISPATCH switch(func) { DispatchEntries } #define EndEntry case END: goto DO_END; #define EndThreadEntry case END_THREAD: goto DO_END_THREAD; #else #define DispatchEntry(name) &&f_##name, #define ResumeEntry(num,name) &&r##num##_##name, #define DispatchVar void * funcs[] = { DispatchEntries }; #define DISPATCH goto *funcs[func]; #define EndEntry &&DO_END, #define EndThreadEntry &&DO_END_THREAD #endif #define MethodName(name,type) f_ ## name ## AT_ ## type #ifdef ENABLE_PROFILING #define START_PROFILE \ gettimeofday(&proftime, NULL);\ cdata->accum = cdata->self_accum = 0;\ cdata->self_start = cdata->start = ((uint64_t)proftime.tv_sec) * 1000000ULL + ((uint64_t)proftime.tv_usec); #define PAUSE_SELF \ gettimeofday(&proftime, NULL);\ my_cdata->self_accum += ((uint64_t)proftime.tv_sec) * 1000000ULL + ((uint64_t)proftime.tv_usec) - my_cdata->self_start; #define AND_TOTAL \ *(my_cdata->myactivationlevel)--;\ my_cdata->accum += ((uint64_t)proftime.tv_sec) * 1000000ULL + ((uint64_t)proftime.tv_usec) - my_cdata->start; #define RESUME_SELF \ gettimeofday(&proftime, NULL);\ my_cdata->self_start = ((uint64_t)proftime.tv_sec) * 1000000ULL + ((uint64_t)proftime.tv_usec); #define AND_RESUME_TOTAL \ *(my_cdata->myactivationlevel)++;\ my_cdata->start = my_cdata->self_start; #define EndFunc(name) \ free_stack(ct, lv_ ## name);\ func = cdata->func;\ profile_activationlevel[FUNC_ ## name]--;\ gettimeofday(&proftime, NULL);\ if(profile_activationlevel[FUNC_ ## name])\ {\ profile_nestedcounts[FUNC_ ## name]++;\ } else {\ profile_counts[FUNC_ ## name]++;\ profile_totals[FUNC_ ## name] += ((uint64_t)proftime.tv_sec) * 1000000ULL + ((uint64_t)proftime.tv_usec) - cdata->start + cdata->accum;\ }\ profile_selftotals[FUNC_ ## name] += ((uint64_t)proftime.tv_sec) * 1000000ULL + ((uint64_t)proftime.tv_usec) - cdata->self_start + cdata->self_accum; #define Func(name,numparams) \ f_ ## name:\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ sf_ ## name:\ profile_activationlevel[FUNC_ ## name]++;\ cdata->myactivationlevel = &profile_activationlevel[FUNC_ ## name];\ START_PROFILE\ lv_ ## name = alloc_stack(ct, sizeof(lt_ ## name));\ my_cdata = cdata; #define MethodImpl(name,type_name,mytype_id,numparams) \ f_ ## name ## AT_ ## type_name:\ sf_ ## name ## AT_ ## type_name:\ if (cdata->num_params < 1)\ {\ cdata = alloc_cdata(ct, cdata, 0);\ cdata->func = FUNC_ ## name ## AT_ ## type_name;\ goto _exception;\ }\ if(get_blueprint(cdata->params[0])->type_id != mytype_id)\ {\ puts("uh oh, need conversion and that's not implemented yet!");\ exit(1);\ }\ m_ ## name ## AT_ ## type_name:\ profile_activationlevel[FUNC_ ## name ## AT_ ## type_name]++;\ cdata->myactivationlevel = &profile_activationlevel[FUNC_ ## name ## AT_ ## type_name];\ START_PROFILE\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ lv_ ## name ## AT_ ## type_name = alloc_stack(ct, sizeof(lt_ ## name ## AT_ ## type_name));\ my_cdata = cdata; #else #define START_PROFILE #define PAUSE_SELF #define RESUME_SELF #define AND_TOTAL #define AND_RESUME_TOTAL #define EndFunc(name) \ free_stack(ct, lv_ ## name);\ func = cdata->func; #define Func(name,numparams) \ f_ ## name:\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ sf_ ## name:\ lv_ ## name = alloc_stack(ct, sizeof(lt_ ## name));\ my_cdata = cdata; #define MethodImpl(name,type_name,mytype_id,numparams) \ f_ ## name ## AT_ ## type_name:\ sf_ ## name ## AT_ ## type_name:\ if (cdata->num_params < 1)\ {\ cdata = alloc_cdata(ct, cdata, 0);\ cdata->func = FUNC_ ## name ## AT_ ## type_name;\ goto _exception;\ }\ if(get_blueprint(cdata->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(cdata->params[0])->type_id, #type_name, mytype_id, #name);\ goto _exception;\ }\ m_ ## name ## AT_ ## type_name:\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ lv_ ## name ## AT_ ## type_name = alloc_stack(ct, sizeof(lt_ ## name ## AT_ ## type_name));\ my_cdata = cdata; #endif #define EndFuncNoLocals \ func = cdata->func; #define FuncNoLocals(name,numparams) \ f_ ## name:\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ sf_ ## name:\ my_cdata = cdata; #define MethodImplNoLocals(name,type_name,mytype_id,numparams) \ f_ ## name ## AT_ ## type_name:\ sf_ ## name ## AT_ ## type_name:\ if (cdata->num_params < 1)\ cdata = alloc_cdata(ct, cdata, 0);\ cdata->func = FUNC_ ## name ## AT_ ## type_name;\ goto _exception;\ if(get_blueprint(cdata->params[0])->type_id != mytype_id)\ {\ puts("uh oh, need conversion and that's not implemented yet!");\ exit(1);\ }\ m_ ## name ## AT_ ## type_name:\ for(idx = numparams; idx < cdata->num_params; ++idx)\ release_ref(cdata->params[idx]); cdata->num_params = numparams;\ my_cdata = cdata; #define Method(name) \ f_ ## name:\ sf_ ## name:\ switch(get_blueprint(cdata->params[0])->type_id)\ { #define EndMethod(mname) \ default:\ printf("Type ");\ fwrite( ((t_Array *)((t_String *)get_blueprint(cdata->params[0])->name)->payload.Buffer)+1, 1, ((t_Array *)((t_String *)get_blueprint(cdata->params[0])->name)->payload.Buffer)->payload.Length, stdout);\ printf("(%d) does not implement method %s\n", get_blueprint(cdata->params[0])->type_id, #mname);\ cdata = alloc_cdata(ct, cdata, 0);\ cdata->func = FUNC_ ## mname;\ goto _exception;\ } #define MethodDispatch(type_id,name,type_name) \ case type_id:\ goto m_ ## name ## AT_ ## type_name; #define NumParams #define CallSpace #define Param(num,convtypeid) \ if(get_blueprint(cdata->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(cdata->params[num])->type_id, convtypeid, num);\ goto _exception;\ } #define CopiedParam(num,convtypeid) Param(num,convtypeid) cdata->params[num] = copy_object(cdata->params[num]); #define Ret(num,val) cdata->params[num] = (object *)(val); #define NumRet(num) cdata->num_params = num;\ if (num == 1 && !cdata->params[0])\ {\ puts("Worker with only one output failed to produce data for that output!");\ goto _exception;\ } #define Exception #define FuncDef(name) lt_ ## name * lv_ ## name; #define MethodDef(name) lt_ ## name ## AT_ ## type_name * lv_ ## name ## AT_ ## type_name; #define PrepCall(callspace) cdata = alloc_cdata(ct, cdata, callspace); #define SetParam(num,value) cdata->params[num] = value; #define VCRePrepCall(func,numparams,lastnumparams) \ if(numparams + ((t_Worker *)func)->payload.Count > lastnumparams)\ {\ temp_cdata = cdata->lastframe;\ free_stack(ct, cdata);\ cdata = alloc_cdata(ct, temp_cdata, numparams + ((t_Worker *)func)->payload.Count);\ }\ vcparam_offset = 0;\ last_vcparam = -1; #define VCPrepCall(func,numparams) \ cdata = alloc_cdata(ct, cdata, numparams + ((t_Worker *)func)->payload.Count);\ 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])\ {\ cdata->params[num+vcparam_offset] = add_ref(((object **)(((t_Worker *)func)+1))[num+vcparam_offset]);\ ++vcparam_offset;\ }\ cdata->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]) \ cdata->params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\ ++last_vcparam;\ }\ cdata->func = RES_ ## resumeto ## _ ## myname;\ cdata->num_params = numparams + ((t_Worker *)tocall)->payload.Count;\ cdata->vars = lv_ ## myname;\ func = ((t_Worker *)tocall)->payload.Index;\ PAUSE_SELF #define ValCallPostlude(resumeto,myname)\ r ## resumeto ## _ ## myname:\ my_cdata = cdata->lastframe;\ RESUME_SELF\ lv_ ## myname = cdata->vars; #define ValCallNoLocals(tocall,numparams,resumeto,myname)\ last_vcparam++;\ while(last_vcparam < ((t_Worker *)tocall)->payload.Size)\ {\ if (((object **)(((t_Worker *)tocall)+1))[last_vcparam]) \ cdata->params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\ ++last_vcparam;\ }\ cdata->func = RES_ ## resumeto ## _ ## myname;\ cdata->num_params = numparams + ((t_Worker *)tocall)->payload.Count;\ func = ((t_Worker *)tocall)->payload.Index;\ PAUSE_SELF #define ValCallNoLocalsPostlude(resumeto,myname)\ r ## resumeto ## _ ## myname:\ my_cdata = cdata->lastframe;\ RESUME_SELF #define CallNoLocals(tocall, numparams, resumeto, myname)\ cdata->func = RES_ ## resumeto ## _ ## myname;\ cdata->num_params = numparams;\ if(FUNC_ ## tocall == FUNC_ ## myname) {\ PAUSE_SELF\ AND_TOTAL\ } else if (FUNC_ ## tocall != FUNC_PL_ && FUNC_ ## tocall != FUNC_MN_ && FUNC_ ## tocall != FUNC_TM_ && FUNC_ ## tocall != FUNC_DV_ && FUNC_ ## tocall != FUNC_If) {\ PAUSE_SELF\ }\ goto sf_ ## tocall;\ r ## resumeto ## _ ## myname:\ my_cdata = cdata->lastframe;\ if(FUNC_ ## tocall == FUNC_ ## myname) {\ RESUME_SELF\ AND_RESUME_TOTAL\ } else if (FUNC_ ## tocall != FUNC_PL_ && FUNC_ ## tocall != FUNC_MN_ && FUNC_ ## tocall != FUNC_TM_ && FUNC_ ## tocall != FUNC_DV_ && FUNC_ ## tocall != FUNC_If) {\ RESUME_SELF\ } #define Call(tocall, numparams, resumeto, myname)\ cdata->func = RES_ ## resumeto ## _ ## myname;\ cdata->num_params = numparams;\ cdata->vars = lv_ ## myname;\ if(FUNC_ ## tocall == FUNC_ ## myname) {\ PAUSE_SELF\ AND_TOTAL\ } else if (FUNC_ ## tocall != FUNC_PL_ && FUNC_ ## tocall != FUNC_MN_ && FUNC_ ## tocall != FUNC_TM_ && FUNC_ ## tocall != FUNC_DV_ && FUNC_ ## tocall != FUNC_If) {\ PAUSE_SELF\ }\ goto sf_ ## tocall;\ r ## resumeto ## _ ## myname:\ my_cdata = cdata->lastframe;\ if(FUNC_ ## tocall == FUNC_ ## myname) {\ RESUME_SELF\ AND_RESUME_TOTAL\ } else if (FUNC_ ## tocall != FUNC_PL_ && FUNC_ ## tocall != FUNC_MN_ && FUNC_ ## tocall != FUNC_TM_ && FUNC_ ## tocall != FUNC_DV_ && FUNC_ ## tocall != FUNC_If) {\ RESUME_SELF\ }\ lv_ ## myname = cdata->vars; #define FreeCall\ temp_cdata = cdata->lastframe;\ free_stack(ct, cdata);\ cdata = temp_cdata; #define FreeCallMethod(myname,mytype)\ temp_cdata = cdata->lastframe;\ free_stack(ct, cdata);\ cdata = temp_cdata;\ lv_ ## myname ## AT_ ## type_name = (lt_ ## myname ## AT_ ## type_name *)(cdata+1); #define TPrepCall(callspace) \ func = cdata->lastframe->func;\ temp_cdata = cdata->lastframe->lastframe;\ free_stack(ct, cdata->lastframe);\ cdata = alloc_cdata(ct, temp_cdata, callspace);\ cdata->func = func; #define TCall(tocall, numparams)\ cdata->num_params = numparams;\ goto sf_ ## tocall; #endif //_FUNC_H_