Mercurial > repos > rhope
comparison 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 |
comparison
equal
deleted
inserted
replaced
185:4580c08fd4e8 | 186:ba35ab624ec2 |
---|---|
1 | |
2 typedef struct { | |
3 int num_ret; | |
4 object ** retvals; | |
5 } returntype; | |
6 | |
7 typedef returntype (*rhope_func)(int, object **); | |
8 | |
9 #define DispatchEntry(name) f_ ## name, | |
10 #define ResumeEntry(num,name) | |
11 #define ResEnum(num,name) | |
12 #define DispatchVar rhope_func func_lookup[] = { DispatchEntries }; | |
13 #define EndEntry | |
14 #define EndThreadEntry | |
15 #define DISPATCH | |
16 | |
17 #define lv(func,var) lv_ ## var | |
18 #define lvar(type, name) type lv_ ## name; | |
19 #define my_params(num) params[num] | |
20 #define child_params(num) call_params[num] | |
21 #define my_outputs(num) retvals[num] | |
22 | |
23 #define result(num) callret.retvals[num] | |
24 #define numresults callret.num_ret | |
25 | |
26 #define LocalsType(def,func) | |
27 | |
28 #define Func(name, numparams, numret) \ | |
29 returntype f_ ## name(int num_params, object ** params) {\ | |
30 ldec_ ## name;\ | |
31 static object * retvals[numret];\ | |
32 object * call_params[32];\ | |
33 int idx, vcparam_offset, last_vcparam;\ | |
34 returntype callret,retinfo = {numret, &retvals};\ | |
35 for(idx = numparams; idx < num_params; ++idx)\ | |
36 release_ref(params[idx]); num_params = numparams; | |
37 | |
38 #define FuncNoLocals(name, numparams, numret) \ | |
39 returntype f_ ## name(int num_params, object ** params) {\ | |
40 object * call_params[32];\ | |
41 static object * retvals[numret];\ | |
42 int idx, vcparam_offset, last_vcparam;\ | |
43 returntype callret,retinfo = {numret, &retvals};\ | |
44 for(idx = numparams; idx < num_params; ++idx)\ | |
45 release_ref(params[idx]); num_params = numparams; | |
46 | |
47 #define Param(num,convtypeid) \ | |
48 if(get_blueprint(params[num])->type_id != convtypeid)\ | |
49 {\ | |
50 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);\ | |
51 exit(1);\ | |
52 } | |
53 | |
54 #define CopiedParam(num,convtypeid) Param(num,convtypeid) params[num] = copy_object(params[num]); | |
55 | |
56 #define Ret(num,val) retvals[num] = (object *)(val); | |
57 #define NumRet(num) | |
58 | |
59 #define EndFunc(name) return retinfo;} | |
60 #define EndFuncNoLocals return retinfo;} | |
61 | |
62 #define MethodImpl(name,type_name,mytype_id,numparams,numret) \ | |
63 returntype f_ ## name ## AT_ ## type_name(int num_params, object ** params) {\ | |
64 if (num_params < 1)\ | |
65 {\ | |
66 printf("Direct call to %s@%s had no arguments!", #name, #type_name);\ | |
67 printf("%d\n", *((char *)0));\ | |
68 exit(1);\ | |
69 }\ | |
70 if(get_blueprint(params[0])->type_id != mytype_id)\ | |
71 {\ | |
72 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);\ | |
73 exit(1);\ | |
74 }\ | |
75 return m_ ## name ## AT_ ## type_name(num_params, params);\ | |
76 }\ | |
77 returntype m_ ## name ## AT_ ## type_name(int num_params, object ** params) {\ | |
78 ldec_ ## name ## AT_ ## type_name;\ | |
79 static object * retvals[numret];\ | |
80 object * call_params[32];\ | |
81 int idx, vcparam_offset, last_vcparam;\ | |
82 returntype callret,retinfo = {numret, &retvals};\ | |
83 for(idx = numparams; idx < num_params; ++idx)\ | |
84 release_ref(params[idx]); num_params = numparams; | |
85 | |
86 | |
87 #define MethodImplNoLocals(name,type_name,mytype_id,numparams,numret) \ | |
88 returntype f_ ## name ## AT_ ## type_name(int num_params, object ** params) {\ | |
89 if (num_params < 1)\ | |
90 {\ | |
91 printf("Direct call to %s@%s had no arguments!", #name, #type_name);\ | |
92 exit(1);\ | |
93 }\ | |
94 if(get_blueprint(params[0])->type_id != mytype_id)\ | |
95 {\ | |
96 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);\ | |
97 exit(1);\ | |
98 }\ | |
99 return m_ ## name ## AT_ ## type_name(num_params, params);\ | |
100 }\ | |
101 returntype m_ ## name ## AT_ ## type_name(int num_params, object ** params) {\ | |
102 static object * retvals[numret];\ | |
103 object * call_params[32];\ | |
104 int idx, vcparam_offset, last_vcparam;\ | |
105 returntype callret,retinfo = {numret, &retvals};\ | |
106 for(idx = numparams; idx < num_params; ++idx)\ | |
107 release_ref(params[idx]); num_params = numparams; | |
108 | |
109 #define Method(name) \ | |
110 returntype f_ ## name(int num_params, object ** params) {\ | |
111 switch(get_blueprint(params[0])->type_id)\ | |
112 { | |
113 | |
114 #define EndMethod(mname) \ | |
115 default:\ | |
116 printf("Type ");\ | |
117 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);\ | |
118 printf("(%d) does not implement method %s\n", get_blueprint(params[0])->type_id, #mname);\ | |
119 printf("%d\n", *((char *)0));\ | |
120 exit(1);\ | |
121 }\ | |
122 } | |
123 | |
124 #define MethodDispatch(type_id,name,type_name) \ | |
125 case type_id:\ | |
126 return m_ ## name ## AT_ ## type_name(num_params, params); | |
127 | |
128 #define FuncDef(name) returntype f_ ## name(int num_params, object ** params); | |
129 #define MethodDef(name) returntype f_ ## name(int num_params, object ** params); returntype m_ ## name(int num_params, object ** params); | |
130 | |
131 #define PrepCall(callspace) | |
132 #define SetParam(num,value) call_params[num] = value; | |
133 #define VCRePrepCall(func,numparams,lastnumparams) \ | |
134 vcparam_offset = 0;\ | |
135 last_vcparam = -1; | |
136 #define VCPrepCall(func,numparams) \ | |
137 vcparam_offset = 0;\ | |
138 last_vcparam = -1; | |
139 #define VCSetParam(func,num,value) \ | |
140 while((num+vcparam_offset) < ((t_Worker *)func)->payload.Size && ((object **)(((t_Worker *)func)+1))[num+vcparam_offset])\ | |
141 {\ | |
142 call_params[num+vcparam_offset] = add_ref(((object **)(((t_Worker *)func)+1))[num+vcparam_offset]);\ | |
143 ++vcparam_offset;\ | |
144 }\ | |
145 call_params[num+vcparam_offset] = value;\ | |
146 last_vcparam = num+vcparam_offset; | |
147 | |
148 #define ValCall(tocall,numparams,resumeto,myname)\ | |
149 last_vcparam++;\ | |
150 while(last_vcparam < ((t_Worker *)tocall)->payload.Size)\ | |
151 {\ | |
152 if (((object **)(((t_Worker *)tocall)+1))[last_vcparam]) \ | |
153 call_params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\ | |
154 ++last_vcparam;\ | |
155 }\ | |
156 callret = func_lookup[((t_Worker *)tocall)->payload.Index](numparams + ((t_Worker *)tocall)->payload.Count, &call_params); | |
157 | |
158 #define ValCallNoLocals(tocall,numparams,resumeto,myname)\ | |
159 last_vcparam++;\ | |
160 while(last_vcparam < ((t_Worker *)tocall)->payload.Size)\ | |
161 {\ | |
162 if (((object **)(((t_Worker *)tocall)+1))[last_vcparam]) \ | |
163 call_params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\ | |
164 ++last_vcparam;\ | |
165 }\ | |
166 callret = func_lookup[((t_Worker *)tocall)->payload.Index](numparams + ((t_Worker *)tocall)->payload.Count, &call_params); | |
167 | |
168 #define ValCallPostlude(resumeto,myname) | |
169 #define ValCallNoLocalsPostlude(resumeto,myname) | |
170 | |
171 #define Call(tocall, numparams, resumeto, myname)\ | |
172 callret = f_ ## tocall(numparams, &call_params); | |
173 | |
174 #define CallNoLocals(tocall, numparams, resumeto, myname)\ | |
175 callret = f_ ## tocall(numparams, &call_params); | |
176 | |
177 #define FreeCall | |
178 #define FreeCallMethod(myname,mytype) | |
179 #define TPrepCall(callspace) | |
180 #define TCall(tocall, numparams) | |
181 |