comparison runtime/func.h @ 56:d2f9b0a9403d

Initial experiment with goto and switch
author Mike Pavone <pavone@retrodev.com>
date Thu, 08 Oct 2009 01:52:38 -0400
parents 3498713c3dc9
children 2174878a6e4b
comparison
equal deleted inserted replaced
38:7f05bbe82f24 56:d2f9b0a9403d
13 typedef returntype (*rhope_func)(struct calldata *); 13 typedef returntype (*rhope_func)(struct calldata *);
14 typedef void (*special_func) (struct object *); 14 typedef void (*special_func) (struct object *);
15 15
16 #define MethodName(name,type) f_ ## name ## _AT_ ## type 16 #define MethodName(name,type) f_ ## name ## _AT_ ## type
17 17
18 #define Func(name,numparams,callspace,localtype) \ 18
19 returntype f_ ## name (calldata * cdata)\ 19 #define Func(name,numparams) \
20 {\ 20 case FUNC_ ## name:\
21 localtype *locals;\ 21 f_ ## name:\
22 calldata *call;\ 22 switch(resume)\
23 returntype ret;\
24 int idx;\
25 if(cdata->resume)\
26 {\
27 call = cdata->call;\
28 locals = cdata->locals;\
29 }\
30 switch(cdata->resume)\
31 {\ 23 {\
32 case 0:\ 24 case 0:\
33 for(idx = numparams; idx < cdata->num_params; ++idx)\ 25 for(idx = numparams; idx < cdata->num_params; ++idx)\
34 release_ref(cdata->params[idx]); cdata->num_params = numparams;\ 26 release_ref(cdata->params[0-idx]); cdata->num_params = numparams;\
35 cdata->num_params = numparams;\ 27 lv_ ## name = alloc_stack(ct, sizeof(lt_ ## name));
36 cdata->call = call = alloc_cdata(cdata->ct, callspace);\
37 cdata->locals = locals = alloc_stack(cdata->ct, sizeof(localtype));
38 28
39 #define FuncNoLocals(name,numparams,callspace) \ 29
40 returntype f_ ## name (calldata * cdata)\ 30 #define FuncNoLocals(name,numparams) \
41 {\ 31 case FUNC_ ## name:\
42 calldata *call;\ 32 f_ ## name:\
43 returntype ret;\ 33 switch(resume)\
44 int idx;\
45 if(cdata->resume)\
46 call = cdata->locals;\
47 switch(cdata->resume)\
48 {\ 34 {\
49 case 0:\ 35 case 0:\
50 for(idx = numparams; idx < cdata->num_params; ++idx)\ 36 for(idx = numparams; idx < cdata->num_params; ++idx)\
51 release_ref(cdata->params[idx]);\ 37 release_ref(cdata->params[0-idx]); cdata->num_params = numparams;\
52 cdata->num_params = numparams;\
53 cdata->locals = call = alloc_cdata(cdata->ct, callspace);
54 38
55 #define EndFunc \ 39 #define EndFunc(name) \
56 free_stack(cdata->ct, call);\ 40 free_stack(ct, lv_ ## name);\
57 return NORMAL_RETURN;\ 41 func = cdata->func;\
58 }\ 42 resume = cdata->resume;\
59 } 43 goto _dispatch;\
44 }
45
46 #define EndFuncNoLocals \
47 func = cdata->func;\
48 resume = cdata->resume;\
49 goto _dispatch;\
50 }
60 51
61 #define Method(name,type,numparams,callspace,localtype) \ 52 #define Method(name) \
62 returntype MethodName(name,type) (calldata * cdata)\ 53 case FUNC_ ## name:\
63 {\ 54 f_ ## name:\
64 localtype *locals;\ 55 if (cdata->num_params < 1)\
65 calldata *call;\ 56 goto _exception;\
66 returntype ret;\ 57 switch(get_blueprint(cdata->params[0])->type_id)\
67 int idx;\ 58 {
68 if(cdata->resume)\ 59
69 {\ 60 #define EndMethod \
70 call = cdata->call;\ 61 default:\
71 locals = cdata->locals;\ 62 goto _exception;\
72 }\ 63 }
73 switch(cdata->resume)\ 64
65
66 #define MethodDispatch(type_id,name,type_name) \
67 case type_id:\
68 goto m_ ## name ## _AT_ ## type_name;
69
70 #define MethodImpl(name,type_name,mytype_id,numparams) \
71 case FUNC_ ## name ## _AT_ ## type_name:\
72 f_ ## name ## _AT_ ## type_name:\
73 switch(resume)\
74 {\ 74 {\
75 case 0:\ 75 case 0:\
76 if (cdata->num_params < 1)\
77 goto _exception;\
78 if(get_blueprint(cdata->params[0])->type_id != mytype_id)\
79 {\
80 puts("uh oh, need conversion and that's not implemented yet!");\
81 exit(1);\
82 }\
83 m_ ## name ## _AT_ ## type_name:\
76 for(idx = numparams; idx < cdata->num_params; ++idx)\ 84 for(idx = numparams; idx < cdata->num_params; ++idx)\
77 release_ref(cdata->params[idx]); cdata->num_params = numparams;\ 85 release_ref(cdata->params[0-idx]); cdata->num_params = numparams;\
78 cdata->num_params = numparams;\ 86 lv_ ## name ## _AT_ ## type_name = alloc_stack(ct, sizeof(lt_ ## name ## _AT_ ## type_name));
79 cdata->call = call = alloc_cdata(cdata->ct, callspace);\ 87
80 cdata->locals = locals = alloc_stack(cdata->ct, sizeof(localtype)); 88
81 89 #define MethodImplNoLocals(name,type_name,mytype_id,numparams) \
82 #define MethodNoLocals(name,type,numparams,callspace) \ 90 case FUNC_ ## name ## _AT_ ## type_name:\
83 returntype MethodName(name,type) (calldata * cdata)\ 91 f_ ## name ## _AT_ ## type_name:\
84 {\ 92 switch(resume)\
85 calldata *call;\
86 returntype ret;\
87 int idx;\
88 if(cdata->resume)\
89 call = cdata->locals;\
90 switch(cdata->resume)\
91 {\ 93 {\
92 case 0:\ 94 case 0:\
95 if (cdata->num_params < 1)\
96 goto _exception;\
97 if(get_blueprint(cdata->params[0])->type_id != mytype_id)\
98 {\
99 puts("uh oh, need conversion and that's not implemented yet!");\
100 exit(1);\
101 }\
102 m_ ## name ## _AT_ ## type_name:\
93 for(idx = numparams; idx < cdata->num_params; ++idx)\ 103 for(idx = numparams; idx < cdata->num_params; ++idx)\
94 release_ref(cdata->params[idx]);\ 104 release_ref(cdata->params[0-idx]); cdata->num_params = numparams;
95 cdata->num_params = numparams;\ 105
96 cdata->locals = call = alloc_cdata(cdata->ct, callspace);
97
98 #define NumParams 106 #define NumParams
99 #define CallSpace 107 #define CallSpace
100 108
101 #define Param(num,convtypeid) \ 109 #define Param(num,convtypeid) \
102 call->params[0] = cdata->params[num];\ 110 if(get_blueprint(cdata->params[0-num])->type_id != convtypeid)\
103 call->resume = 0;\
104 ret = coerce_value(convtypeid, call);\
105 while(ret == TAIL_RETURN)\
106 ret = call->tail_func(call);\
107 if(ret == EXCEPTION_RETURN)\
108 {\ 111 {\
109 for(idx = 0; idx < cdata->num_params; ++idx)\ 112 puts("uh oh, need conversion and that's not implemented yet!");\
110 if(idx != num && cdata->params[idx])\ 113 exit(1);\
111 release_ref(cdata->params[idx]);\ 114 }
112 cdata->params[0] = call->params[0];\
113 free_stack(cdata->ct, call);\
114 return ret;\
115 }\
116 cdata->params[num] = call->params[0];
117 115
118 #define CopiedParam(num,convtypeid) Param(num,convtypeid) cdata->params[num] = copy_object(cdata->params[num]); 116 #define CopiedParam(num,convtypeid) Param(num,convtypeid) cdata->params[num] = copy_object(cdata->params[num]);
119 #define Ret(num,val) cdata->params[num] = (object *)(val); 117 #define Ret(num,val) cdata->params[0-num] = (object *)(val);
120 #define Return return NORMAL_RETURN;
121 #define Exception 118 #define Exception
122 #define FuncDef(name) returntype f_ ## name (calldata * cdata); 119 #define FuncDef(name) lt_ ## name * lv_ ## name;
123 #define MethodDef(name,type) returntype MethodName(name,type) (calldata * cdata); 120 #define MethodDef(name) lt_ ## name ## _AT_ ## type_name * lv_ ## name ## _AT_ ## type_name;
124 121
125 #define Call(func, numparams)\ 122
126 call->num_params = numparams;\ 123 #define PrepCall(callspace) cdata = alloc_cdata(ct, cdata, callspace);
127 call->resume = 0;\ 124
128 ret = f_ ## func (call);\ 125 #define SetParam(num,value) cdata->params[0-num] = value;
129 while(ret == TAIL_RETURN)\ 126
130 ret = call->tail_func(call);\ 127 #define Call(tocall, numparams, resumeto, myname)\
131 if(ret == EXCEPTION_RETURN)\ 128 cdata->func = FUNC_ ## myname;\
132 {\ 129 cdata->resume = resumeto;\
133 for(idx = 0; idx < cdata->num_params; ++idx)\ 130 cdata->num_params = numparams;\
134 if(cdata->params[idx])\ 131 resume = 0;\
135 release_ref(cdata->params[idx]);\ 132 goto f_ ## tocall;\
136 cdata->params[0] = call->params[0];\ 133 case resumeto:\
137 free_stack(cdata->ct, call);\ 134 lv_ ## myname = (lt_ ## myname *)(cdata->lastframe+1);
138 return ret;\
139 }
140 135
141 #define MCall(methodid, numparams)\ 136 #define FreeCall\
142 call->num_params = numparams;\ 137 temp_cdata = cdata->lastframe;\
143 call->resume = 0;\ 138 free_stack(ct, cdata);\
144 ret = call_method(methodid, call);\ 139 cdata = temp_cdata;
145 while(ret == TAIL_RETURN)\
146 ret = call->tail_func(call);\
147 if(ret == EXCEPTION_RETURN)\
148 {\
149 for(idx = 0; idx < cdata->num_params; ++idx)\
150 if(cdata->params[idx])\
151 release_ref(cdata->params[idx]);\
152 cdata->params[0] = call->params[0];\
153 free_stack(cdata->ct, call);\
154 return ret;\
155 }
156
157 #define GFieldCall(fieldid)\
158 call->num_params = 1;\
159 call->resume = 0;\
160 ret = get_field(fieldid, call);\
161 while(ret == TAIL_RETURN)\
162 ret = call->tail_func(call);\
163 if(ret == EXCEPTION_RETURN)\
164 {\
165 for(idx = 0; idx < cdata->num_params; ++idx)\
166 if(cdata->params[idx])\
167 release_ref(cdata->params[idx]);\
168 cdata->params[0] = call->params[0];\
169 free_stack(cdata->ct, call);\
170 return ret;\
171 }
172
173 #define SFieldCall(fieldid)\
174 call->num_params = 2;\
175 call->resume = 0;\
176 ret = set_field(fieldid, call);\
177 while(ret == TAIL_RETURN)\
178 ret = call->tail_func(call);\
179 if(ret == EXCEPTION_RETURN)\
180 {\
181 for(idx = 0; idx < cdata->num_params; ++idx)\
182 if(cdata->params[idx])\
183 release_ref(cdata->params[idx]);\
184 cdata->params[0] = call->params[0];\
185 free_stack(cdata->ct, call);\
186 return ret;\
187 }
188 140
189 #define TMCall(methodid, numparams)\ 141 #define FreeCallMethod(myname,mytype)\
190 free_stack(cdata->ct, call);\ 142 temp_cdata = cdata->lastframe;\
191 cdata->num_params = numparams;\ 143 free_stack(ct, cdata);\
192 cdata->resume = 0;\ 144 cdata = temp_cdata;\
193 ret = call_method(methodid, cdata);\ 145 lv_ ## myname ## _AT_ ## type_name = (lt_ ## myname ## _AT_ ## type_name *)(cdata+1);
194 return ret;
195 146
196 #define TCall(func, numparams)\ 147 #define TCall(func, numparams)\
197 free_stack(cdata->ct, call);\ 148 free_stack(cdata->ct, call);\
198 cdata->num_params = numparams;\ 149 cdata->num_params = numparams;\
199 cdata->resume = 0;\ 150 cdata->resume = 0;\