aboutsummaryrefslogtreecommitdiff
path: root/fallback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fallback.c')
-rw-r--r--fallback.c167
1 files changed, 83 insertions, 84 deletions
diff --git a/fallback.c b/fallback.c
index 385a1495..0516919c 100644
--- a/fallback.c
+++ b/fallback.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_fallback="$Id: fallback.c,v 1.28 1997/03/19 19:41:10 roberto Exp roberto $"; 6char *rcs_fallback="$Id: fallback.c,v 1.29 1997/03/19 21:12:34 roberto Exp roberto $";
7 7
8#include <stdio.h> 8#include <stdio.h>
9#include <string.h> 9#include <string.h>
@@ -18,6 +18,19 @@ char *rcs_fallback="$Id: fallback.c,v 1.28 1997/03/19 19:41:10 roberto Exp rober
18#include "hash.h" 18#include "hash.h"
19 19
20 20
21static char *typenames[] = { /* ORDER LUA_T */
22 "userdata", "line", "cmark", "mark", "function",
23 "function", "table", "string", "number", "nil",
24 NULL
25};
26
27
28void luaI_type (void)
29{
30 lua_Object o = lua_getparam(1);
31 lua_pushstring(typenames[-ttype(luaI_Address(o))]);
32 lua_pushnumber(lua_tag(o));
33}
21 34
22 35
23/* ------------------------------------------- 36/* -------------------------------------------
@@ -94,27 +107,19 @@ void luaI_invalidaterefs (void)
94* Internal Methods 107* Internal Methods
95*/ 108*/
96 109
97char *eventname[] = { 110char *luaI_eventname[] = { /* ORDER IM */
98 "gettable", /* IM_GETTABLE */ 111 "gettable", "settable", "index", "add", "sub", "mul", "div",
99 "arith", /* IM_ARITH */ 112 "pow", "unm", "lt", "le", "gt", "ge", "concat", "gc", "function",
100 "order", /* IM_ORDER */
101 "concat", /* IM_CONCAT */
102 "settable", /* IM_SETTABLE */
103 "gc", /* IM_GC */
104 "function", /* IM_FUNCTION */
105 "index", /* IM_INDEX */
106 NULL 113 NULL
107}; 114};
108 115
109 116
110char *geventname[] = { 117static char *geventname[] = { /* ORDER GIM */
111 "error", /* GIM_ERROR */ 118 "error", "getglobal", "setglobal",
112 "getglobal", /* GIM_GETGLOBAL */
113 "setglobal", /* GIM_SETGLOBAL */
114 NULL 119 NULL
115}; 120};
116 121
117static int luaI_findevent (char *name, char *list[]) 122static int findstring (char *name, char *list[])
118{ 123{
119 int i; 124 int i;
120 for (i=0; list[i]; i++) 125 for (i=0; list[i]; i++)
@@ -126,7 +131,7 @@ static int luaI_findevent (char *name, char *list[])
126 131
127static int luaI_checkevent (char *name, char *list[]) 132static int luaI_checkevent (char *name, char *list[])
128{ 133{
129 int e = luaI_findevent(name, list); 134 int e = findstring(name, list);
130 if (e < 0) 135 if (e < 0)
131 lua_error("invalid event name"); 136 lua_error("invalid event name");
132 return e; 137 return e;
@@ -141,38 +146,25 @@ static struct IM {
141static int IMtable_size = 0; 146static int IMtable_size = 0;
142static int last_tag = LUA_T_NIL; 147static int last_tag = LUA_T_NIL;
143 148
144static struct { 149static char validevents[NUM_TYPES][IM_N] = { /* ORDER LUA_T, ORDER IM */
145 lua_Type t; 150{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_USERDATA */
146 int event; 151{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_LINE */
147} exceptions[] = { /* list of events that cannot be modified */ 152{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_CMARK */
148 {LUA_T_NUMBER, IM_ARITH}, 153{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_MARK */
149 {LUA_T_NUMBER, IM_ORDER}, 154{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */
150 {LUA_T_NUMBER, IM_GC}, 155{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_FUNCTION */
151 {LUA_T_STRING, IM_ARITH}, 156{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */
152 {LUA_T_STRING, IM_ORDER}, 157{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
153 {LUA_T_STRING, IM_CONCAT}, 158{1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}, /* LUA_T_NUMBER */
154 {LUA_T_STRING, IM_GC}, 159{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0} /* LUA_T_NIL */
155 {LUA_T_ARRAY, IM_GETTABLE},
156 {LUA_T_ARRAY, IM_SETTABLE},
157 {LUA_T_FUNCTION, IM_FUNCTION},
158 {LUA_T_FUNCTION, IM_GC},
159 {LUA_T_CFUNCTION, IM_FUNCTION},
160 {LUA_T_CFUNCTION, IM_GC},
161 {LUA_T_NIL, 0} /* flag end of list */
162}; 160};
163 161
164 162static int validevent (lua_Type t, int e)
165static int validevent (int t, int event)
166{ 163{
167 int i; 164 return (t < LUA_T_NIL) ? 1 : validevents[-t][e];
168 if (t == LUA_T_NIL) /* cannot modify any event for nil */
169 return 0;
170 for (i=0; exceptions[i].t != LUA_T_NIL; i++)
171 if (exceptions[i].t == t && exceptions[i].event == event)
172 return 0;
173 return 1;
174} 165}
175 166
167
176static void init_entry (int tag) 168static void init_entry (int tag)
177{ 169{
178 int i; 170 int i;
@@ -193,14 +185,14 @@ void luaI_initfallbacks (void)
193 185
194int lua_newtag (char *t) 186int lua_newtag (char *t)
195{ 187{
188 int tp;
196 --last_tag; 189 --last_tag;
197 if ((-last_tag) >= IMtable_size) 190 if ((-last_tag) >= IMtable_size)
198 IMtable_size = growvector(&luaI_IMtable, IMtable_size, 191 IMtable_size = growvector(&luaI_IMtable, IMtable_size,
199 struct IM, memEM, MAX_INT); 192 struct IM, memEM, MAX_INT);
200 if (strcmp(t, "table") == 0) 193 tp = -findstring(t, typenames);
201 luaI_IMtable[-last_tag].tp = LUA_T_ARRAY; 194 if (tp == LUA_T_ARRAY || tp == LUA_T_USERDATA)
202 else if (strcmp(t, "userdata") == 0) 195 luaI_IMtable[-last_tag].tp = tp;
203 luaI_IMtable[-last_tag].tp = LUA_T_USERDATA;
204 else 196 else
205 lua_error("invalid type for new tag"); 197 lua_error("invalid type for new tag");
206 init_entry(last_tag); 198 init_entry(last_tag);
@@ -246,14 +238,14 @@ int luaI_tag (Object *o)
246 else return t; 238 else return t;
247} 239}
248 240
249Object *luaI_getim (int tag, int event) 241Object *luaI_getim (int tag, IMS event)
250{ 242{
251 if (tag > LUA_T_USERDATA) 243 if (tag > LUA_T_USERDATA)
252 tag = LUA_T_USERDATA; /* default for non-registered tags */ 244 tag = LUA_T_USERDATA; /* default for non-registered tags */
253 return &luaI_IMtable[-tag].int_method[event]; 245 return &luaI_IMtable[-tag].int_method[event];
254} 246}
255 247
256Object *luaI_getimbyObj (Object *o, int event) 248Object *luaI_getimbyObj (Object *o, IMS event)
257{ 249{
258 return luaI_getim(luaI_tag(o), event); 250 return luaI_getim(luaI_tag(o), event);
259} 251}
@@ -261,13 +253,13 @@ Object *luaI_getimbyObj (Object *o, int event)
261void luaI_setintmethod (void) 253void luaI_setintmethod (void)
262{ 254{
263 int t = (int)luaL_check_number(1, "setintmethod"); 255 int t = (int)luaL_check_number(1, "setintmethod");
264 int e = luaI_checkevent(luaL_check_string(2, "setintmethod"), eventname); 256 int e = luaI_checkevent(luaL_check_string(2, "setintmethod"), luaI_eventname);
265 lua_Object func = lua_getparam(3); 257 lua_Object func = lua_getparam(3);
258 checktag(t);
266 if (!validevent(t, e)) 259 if (!validevent(t, e))
267 lua_error("cannot change this internal method"); 260 lua_error("cannot change this internal method");
268 luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod", 261 luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod",
269 3, "function expected"); 262 3, "function expected");
270 checktag(t);
271 luaI_pushobject(&luaI_IMtable[-t].int_method[e]); 263 luaI_pushobject(&luaI_IMtable[-t].int_method[e]);
272 luaI_IMtable[-t].int_method[e] = *luaI_Address(func); 264 luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
273} 265}
@@ -276,7 +268,7 @@ static Object gmethod[GIM_N] = {
276 {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}} 268 {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}
277}; 269};
278 270
279Object *luaI_getgim (int event) 271Object *luaI_getgim (IMGS event)
280{ 272{
281 return &gmethod[event]; 273 return &gmethod[event];
282} 274}
@@ -326,47 +318,54 @@ static void typeFB (void)
326} 318}
327 319
328 320
321static void fillvalids (IMS e, Object *func)
322{
323 int t;
324 for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
325 if (validevent(t, e))
326 luaI_IMtable[-t].int_method[e] = *func;
327}
328
329void luaI_setfallback (void) 329void luaI_setfallback (void)
330{ 330{
331 int e; 331 int e;
332 Object oldfunc;
333 lua_CFunction replace;
332 char *name = luaL_check_string(1, "setfallback"); 334 char *name = luaL_check_string(1, "setfallback");
333 lua_Object func = lua_getparam(2); 335 lua_Object func = lua_getparam(2);
334 luaL_arg_check(lua_isfunction(func), "setfallback", 2, "function expected"); 336 luaL_arg_check(lua_isfunction(func), "setfallback", 2, "function expected");
335 e = luaI_findevent(name, geventname); 337 e = findstring(name, geventname);
336 if (e >= 0) { /* global event */ 338 if (e >= 0) { /* global event */
337 switch (e) { 339 oldfunc = gmethod[e];
338 case GIM_ERROR: 340 gmethod[e] = *luaI_Address(func);
339 gmethod[e] = *luaI_Address(func); 341 replace = (e == GIM_ERROR) ? errorFB : nilFB;
340 lua_pushcfunction(errorFB);
341 break;
342 case GIM_GETGLOBAL: /* goes through */
343 case GIM_SETGLOBAL:
344 gmethod[e] = *luaI_Address(func);
345 lua_pushcfunction(nilFB);
346 break;
347 default: lua_error("internal error");
348 }
349 } 342 }
350 else { /* tagged name? */ 343 else if ((e = findstring(name, luaI_eventname)) >= 0) {
351 int t;
352 Object oldfunc;
353 e = luaI_checkevent(name, eventname);
354 oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[e]; 344 oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[e];
355 for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++) 345 fillvalids(e, luaI_Address(func));
356 if (validevent(t, e)) 346 replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB;
357 luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
358 if (oldfunc.ttype != LUA_T_NIL)
359 luaI_pushobject(&oldfunc);
360 else {
361 switch (e) {
362 case IM_GC: case IM_INDEX:
363 lua_pushcfunction(nilFB);
364 break;
365 default:
366 lua_pushcfunction(typeFB);
367 break;
368 }
369 }
370 } 347 }
348 else if (strcmp(name, "arith") == 0) { /* old arith fallback */
349 int i;
350 oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[IM_ADD];
351 for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */
352 fillvalids(i, luaI_Address(func));
353 replace = typeFB;
354 }
355 else if (strcmp(name, "order") == 0) { /* old order fallback */
356 int i;
357 oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[IM_LT];
358 for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */
359 fillvalids(i, luaI_Address(func));
360 replace = typeFB;
361 }
362 else {
363 lua_error("invalid fallback name");
364 replace = NULL; /* to avoid warnings */
365 }
366 if (oldfunc.ttype != LUA_T_NIL)
367 luaI_pushobject(&oldfunc);
368 else
369 lua_pushcfunction(replace);
371} 370}
372 371