Mercurial > repos > rhope
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;\ |