diff options
Diffstat (limited to 'fallback.c')
-rw-r--r-- | fallback.c | 167 |
1 files changed, 83 insertions, 84 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_fallback="$Id: fallback.c,v 1.28 1997/03/19 19:41:10 roberto Exp roberto $"; | 6 | char *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 | ||
21 | static char *typenames[] = { /* ORDER LUA_T */ | ||
22 | "userdata", "line", "cmark", "mark", "function", | ||
23 | "function", "table", "string", "number", "nil", | ||
24 | NULL | ||
25 | }; | ||
26 | |||
27 | |||
28 | void 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 | ||
97 | char *eventname[] = { | 110 | char *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 | ||
110 | char *geventname[] = { | 117 | static 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 | ||
117 | static int luaI_findevent (char *name, char *list[]) | 122 | static 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 | ||
127 | static int luaI_checkevent (char *name, char *list[]) | 132 | static 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 { | |||
141 | static int IMtable_size = 0; | 146 | static int IMtable_size = 0; |
142 | static int last_tag = LUA_T_NIL; | 147 | static int last_tag = LUA_T_NIL; |
143 | 148 | ||
144 | static struct { | 149 | static 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 | 162 | static int validevent (lua_Type t, int e) | |
165 | static 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 | |||
176 | static void init_entry (int tag) | 168 | static void init_entry (int tag) |
177 | { | 169 | { |
178 | int i; | 170 | int i; |
@@ -193,14 +185,14 @@ void luaI_initfallbacks (void) | |||
193 | 185 | ||
194 | int lua_newtag (char *t) | 186 | int 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 | ||
249 | Object *luaI_getim (int tag, int event) | 241 | Object *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 | ||
256 | Object *luaI_getimbyObj (Object *o, int event) | 248 | Object *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) | |||
261 | void luaI_setintmethod (void) | 253 | void 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 | ||
279 | Object *luaI_getgim (int event) | 271 | Object *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 | ||
321 | static 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 | |||
329 | void luaI_setfallback (void) | 329 | void 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 | ||