diff options
-rw-r--r-- | fallback.c | 353 | ||||
-rw-r--r-- | fallback.h | 64 | ||||
-rw-r--r-- | ltm.c | 317 | ||||
-rw-r--r-- | ltm.h | 61 |
4 files changed, 378 insertions, 417 deletions
diff --git a/fallback.c b/fallback.c deleted file mode 100644 index edec9184..00000000 --- a/fallback.c +++ /dev/null | |||
@@ -1,353 +0,0 @@ | |||
1 | /* | ||
2 | ** fallback.c | ||
3 | ** TecCGraf - PUC-Rio | ||
4 | */ | ||
5 | |||
6 | char *rcs_fallback="$Id: fallback.c,v 2.10 1997/07/03 22:06:06 roberto Exp $"; | ||
7 | |||
8 | #include <stdio.h> | ||
9 | #include <string.h> | ||
10 | |||
11 | #include "auxlib.h" | ||
12 | #include "luamem.h" | ||
13 | #include "fallback.h" | ||
14 | #include "opcode.h" | ||
15 | #include "lua.h" | ||
16 | #include "table.h" | ||
17 | #include "tree.h" | ||
18 | #include "hash.h" | ||
19 | |||
20 | |||
21 | |||
22 | /* ------------------------------------------- | ||
23 | ** Reference routines | ||
24 | */ | ||
25 | |||
26 | static struct ref { | ||
27 | TObject o; | ||
28 | enum {LOCK, HOLD, FREE, COLLECTED} status; | ||
29 | } *refArray = NULL; | ||
30 | static int refSize = 0; | ||
31 | |||
32 | int luaI_ref (TObject *object, int lock) | ||
33 | { | ||
34 | int i; | ||
35 | int oldSize; | ||
36 | if (ttype(object) == LUA_T_NIL) | ||
37 | return -1; /* special ref for nil */ | ||
38 | for (i=0; i<refSize; i++) | ||
39 | if (refArray[i].status == FREE) | ||
40 | goto found; | ||
41 | /* no more empty spaces */ | ||
42 | oldSize = refSize; | ||
43 | refSize = growvector(&refArray, refSize, struct ref, refEM, MAX_WORD); | ||
44 | for (i=oldSize; i<refSize; i++) | ||
45 | refArray[i].status = FREE; | ||
46 | i = oldSize; | ||
47 | found: | ||
48 | refArray[i].o = *object; | ||
49 | refArray[i].status = lock ? LOCK : HOLD; | ||
50 | return i; | ||
51 | } | ||
52 | |||
53 | |||
54 | void lua_unref (int ref) | ||
55 | { | ||
56 | if (ref >= 0 && ref < refSize) | ||
57 | refArray[ref].status = FREE; | ||
58 | } | ||
59 | |||
60 | |||
61 | TObject *luaI_getref (int ref) | ||
62 | { | ||
63 | static TObject nul = {LUA_T_NIL, {0}}; | ||
64 | if (ref == -1) | ||
65 | return &nul; | ||
66 | if (ref >= 0 && ref < refSize && | ||
67 | (refArray[ref].status == LOCK || refArray[ref].status == HOLD)) | ||
68 | return &refArray[ref].o; | ||
69 | else | ||
70 | return NULL; | ||
71 | } | ||
72 | |||
73 | |||
74 | void luaI_travlock (int (*fn)(TObject *)) | ||
75 | { | ||
76 | int i; | ||
77 | for (i=0; i<refSize; i++) | ||
78 | if (refArray[i].status == LOCK) | ||
79 | fn(&refArray[i].o); | ||
80 | } | ||
81 | |||
82 | |||
83 | void luaI_invalidaterefs (void) | ||
84 | { | ||
85 | int i; | ||
86 | for (i=0; i<refSize; i++) | ||
87 | if (refArray[i].status == HOLD && !luaI_ismarked(&refArray[i].o)) | ||
88 | refArray[i].status = COLLECTED; | ||
89 | } | ||
90 | |||
91 | |||
92 | /* ------------------------------------------- | ||
93 | * Internal Methods | ||
94 | */ | ||
95 | |||
96 | char *luaI_eventname[] = { /* ORDER IM */ | ||
97 | "gettable", "settable", "index", "getglobal", "setglobal", "add", | ||
98 | "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge", | ||
99 | "concat", "gc", "function", | ||
100 | NULL | ||
101 | }; | ||
102 | |||
103 | |||
104 | |||
105 | static int luaI_checkevent (char *name, char *list[]) | ||
106 | { | ||
107 | int e = luaI_findstring(name, list); | ||
108 | if (e < 0) | ||
109 | luaL_verror("`%s' is not a valid event name", name); | ||
110 | return e; | ||
111 | } | ||
112 | |||
113 | |||
114 | struct IM *luaI_IMtable = NULL; | ||
115 | |||
116 | static int IMtable_size = 0; | ||
117 | static int last_tag = LUA_T_NIL; /* ORDER LUA_T */ | ||
118 | |||
119 | |||
120 | /* events in LUA_T_LINE are all allowed, since this is used as a | ||
121 | * 'placeholder' for "default" fallbacks | ||
122 | */ | ||
123 | static char validevents[NUM_TYPES][IM_N] = { /* ORDER LUA_T, ORDER IM */ | ||
124 | {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */ | ||
125 | {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_LINE */ | ||
126 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_CMARK */ | ||
127 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_MARK */ | ||
128 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */ | ||
129 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_FUNCTION */ | ||
130 | {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */ | ||
131 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */ | ||
132 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */ | ||
133 | {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */ | ||
134 | }; | ||
135 | |||
136 | static int validevent (lua_Type t, int e) | ||
137 | { /* ORDER LUA_T */ | ||
138 | return (t < LUA_T_NIL) ? 1 : validevents[-t][e]; | ||
139 | } | ||
140 | |||
141 | |||
142 | static void init_entry (int tag) | ||
143 | { | ||
144 | int i; | ||
145 | for (i=0; i<IM_N; i++) | ||
146 | ttype(luaI_getim(tag, i)) = LUA_T_NIL; | ||
147 | } | ||
148 | |||
149 | void luaI_initfallbacks (void) | ||
150 | { | ||
151 | if (luaI_IMtable == NULL) { | ||
152 | int i; | ||
153 | IMtable_size = NUM_TYPES+10; | ||
154 | luaI_IMtable = newvector(IMtable_size, struct IM); | ||
155 | for (i=LUA_T_NIL; i<=LUA_T_USERDATA; i++) | ||
156 | init_entry(i); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | int lua_newtag (void) | ||
161 | { | ||
162 | --last_tag; | ||
163 | if ((-last_tag) >= IMtable_size) { | ||
164 | luaI_initfallbacks(); | ||
165 | IMtable_size = growvector(&luaI_IMtable, IMtable_size, | ||
166 | struct IM, memEM, MAX_INT); | ||
167 | } | ||
168 | init_entry(last_tag); | ||
169 | return last_tag; | ||
170 | } | ||
171 | |||
172 | |||
173 | static void checktag (int tag) | ||
174 | { | ||
175 | if (!(last_tag <= tag && tag <= 0)) | ||
176 | luaL_verror("%d is not a valid tag", tag); | ||
177 | } | ||
178 | |||
179 | void luaI_realtag (int tag) | ||
180 | { | ||
181 | if (!(last_tag <= tag && tag < LUA_T_NIL)) | ||
182 | luaL_verror("tag %d is not result of `newtag'", tag); | ||
183 | } | ||
184 | |||
185 | |||
186 | void luaI_settag (int tag, TObject *o) | ||
187 | { | ||
188 | luaI_realtag(tag); | ||
189 | switch (ttype(o)) { | ||
190 | case LUA_T_ARRAY: | ||
191 | o->value.a->htag = tag; | ||
192 | break; | ||
193 | case LUA_T_USERDATA: | ||
194 | o->value.ts->tag = tag; | ||
195 | break; | ||
196 | default: | ||
197 | luaL_verror("cannot change the tag of a %s", luaI_typenames[-ttype(o)]); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | |||
202 | int luaI_efectivetag (TObject *o) | ||
203 | { | ||
204 | lua_Type t = ttype(o); | ||
205 | if (t == LUA_T_USERDATA) { | ||
206 | int tag = o->value.ts->tag; | ||
207 | return (tag >= 0) ? LUA_T_USERDATA : tag; | ||
208 | } | ||
209 | else if (t == LUA_T_ARRAY) | ||
210 | return o->value.a->htag; | ||
211 | else return t; | ||
212 | } | ||
213 | |||
214 | |||
215 | void luaI_gettagmethod (void) | ||
216 | { | ||
217 | int t = (int)luaL_check_number(1); | ||
218 | int e = luaI_checkevent(luaL_check_string(2), luaI_eventname); | ||
219 | checktag(t); | ||
220 | if (validevent(t, e)) | ||
221 | luaI_pushobject(luaI_getim(t,e)); | ||
222 | } | ||
223 | |||
224 | |||
225 | void luaI_settagmethod (void) | ||
226 | { | ||
227 | int t = (int)luaL_check_number(1); | ||
228 | int e = luaI_checkevent(luaL_check_string(2), luaI_eventname); | ||
229 | lua_Object func = lua_getparam(3); | ||
230 | checktag(t); | ||
231 | if (!validevent(t, e)) | ||
232 | luaL_verror("cannot change internal method `%s' for tag %d", | ||
233 | luaI_eventname[e], t); | ||
234 | luaL_arg_check(lua_isnil(func) || lua_isfunction(func), | ||
235 | 3, "function expected"); | ||
236 | luaI_pushobject(luaI_getim(t,e)); | ||
237 | *luaI_getim(t, e) = *luaI_Address(func); | ||
238 | } | ||
239 | |||
240 | |||
241 | void luaI_seterrormethod (void) | ||
242 | { | ||
243 | lua_Object func = lua_getparam(1); | ||
244 | luaL_arg_check(lua_isnil(func) || lua_isfunction(func), | ||
245 | 1, "function expected"); | ||
246 | luaI_pushobject(&luaI_errorim); | ||
247 | luaI_errorim = *luaI_Address(func); | ||
248 | } | ||
249 | |||
250 | char *luaI_travfallbacks (int (*fn)(TObject *)) | ||
251 | { | ||
252 | int e; | ||
253 | if (fn(&luaI_errorim)) | ||
254 | return "error"; | ||
255 | for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */ | ||
256 | int t; | ||
257 | for (t=0; t>=last_tag; t--) | ||
258 | if (fn(luaI_getim(t,e))) | ||
259 | return luaI_eventname[e]; | ||
260 | } | ||
261 | return NULL; | ||
262 | } | ||
263 | |||
264 | |||
265 | /* | ||
266 | * =================================================================== | ||
267 | * compatibility with old fallback system | ||
268 | */ | ||
269 | #if LUA_COMPAT2_5 | ||
270 | |||
271 | static void errorFB (void) | ||
272 | { | ||
273 | lua_Object o = lua_getparam(1); | ||
274 | if (lua_isstring(o)) | ||
275 | fprintf (stderr, "lua: %s\n", lua_getstring(o)); | ||
276 | else | ||
277 | fprintf(stderr, "lua: unknown error\n"); | ||
278 | } | ||
279 | |||
280 | |||
281 | static void nilFB (void) { } | ||
282 | |||
283 | |||
284 | static void typeFB (void) | ||
285 | { | ||
286 | lua_error("unexpected type"); | ||
287 | } | ||
288 | |||
289 | |||
290 | static void fillvalids (IMS e, TObject *func) | ||
291 | { | ||
292 | int t; | ||
293 | for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++) | ||
294 | if (validevent(t, e)) | ||
295 | *luaI_getim(t, e) = *func; | ||
296 | } | ||
297 | |||
298 | |||
299 | void luaI_setfallback (void) | ||
300 | { | ||
301 | static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; | ||
302 | TObject oldfunc; | ||
303 | lua_CFunction replace; | ||
304 | char *name = luaL_check_string(1); | ||
305 | lua_Object func = lua_getparam(2); | ||
306 | luaI_initfallbacks(); | ||
307 | luaL_arg_check(lua_isfunction(func), 2, "function expected"); | ||
308 | switch (luaI_findstring(name, oldnames)) { | ||
309 | case 0: /* old error fallback */ | ||
310 | oldfunc = luaI_errorim; | ||
311 | luaI_errorim = *luaI_Address(func); | ||
312 | replace = errorFB; | ||
313 | break; | ||
314 | case 1: /* old getglobal fallback */ | ||
315 | oldfunc = *luaI_getim(LUA_T_NIL, IM_GETGLOBAL); | ||
316 | *luaI_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaI_Address(func); | ||
317 | replace = nilFB; | ||
318 | break; | ||
319 | case 2: { /* old arith fallback */ | ||
320 | int i; | ||
321 | oldfunc = *luaI_getim(LUA_T_NUMBER, IM_POW); | ||
322 | for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ | ||
323 | fillvalids(i, luaI_Address(func)); | ||
324 | replace = typeFB; | ||
325 | break; | ||
326 | } | ||
327 | case 3: { /* old order fallback */ | ||
328 | int i; | ||
329 | oldfunc = *luaI_getim(LUA_T_LINE, IM_LT); | ||
330 | for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ | ||
331 | fillvalids(i, luaI_Address(func)); | ||
332 | replace = typeFB; | ||
333 | break; | ||
334 | } | ||
335 | default: { | ||
336 | int e; | ||
337 | if ((e = luaI_findstring(name, luaI_eventname)) >= 0) { | ||
338 | oldfunc = *luaI_getim(LUA_T_LINE, e); | ||
339 | fillvalids(e, luaI_Address(func)); | ||
340 | replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; | ||
341 | } | ||
342 | else { | ||
343 | luaL_verror("`%s' is not a valid fallback name", name); | ||
344 | replace = NULL; /* to avoid warnings */ | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | if (oldfunc.ttype != LUA_T_NIL) | ||
349 | luaI_pushobject(&oldfunc); | ||
350 | else | ||
351 | lua_pushcfunction(replace); | ||
352 | } | ||
353 | #endif | ||
diff --git a/fallback.h b/fallback.h deleted file mode 100644 index 1e2ecc56..00000000 --- a/fallback.h +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /* | ||
2 | ** $Id: fallback.h,v 1.24 1997/07/03 22:06:06 roberto Exp $ | ||
3 | */ | ||
4 | |||
5 | #ifndef fallback_h | ||
6 | #define fallback_h | ||
7 | |||
8 | #include "lua.h" | ||
9 | #include "opcode.h" | ||
10 | |||
11 | /* | ||
12 | * WARNING: if you change the order of this enumeration, | ||
13 | * grep "ORDER IM" | ||
14 | */ | ||
15 | typedef enum { | ||
16 | IM_GETTABLE = 0, | ||
17 | IM_SETTABLE, | ||
18 | IM_INDEX, | ||
19 | IM_GETGLOBAL, | ||
20 | IM_SETGLOBAL, | ||
21 | IM_ADD, | ||
22 | IM_SUB, | ||
23 | IM_MUL, | ||
24 | IM_DIV, | ||
25 | IM_POW, | ||
26 | IM_UNM, | ||
27 | IM_LT, | ||
28 | IM_LE, | ||
29 | IM_GT, | ||
30 | IM_GE, | ||
31 | IM_CONCAT, | ||
32 | IM_GC, | ||
33 | IM_FUNCTION | ||
34 | } IMS; | ||
35 | |||
36 | #define IM_N 18 | ||
37 | |||
38 | |||
39 | extern struct IM { | ||
40 | TObject int_method[IM_N]; | ||
41 | } *luaI_IMtable; | ||
42 | |||
43 | extern char *luaI_eventname[]; | ||
44 | |||
45 | #define luaI_getim(tag,event) (&luaI_IMtable[-(tag)].int_method[event]) | ||
46 | #define luaI_getimbyObj(o,e) (luaI_getim(luaI_efectivetag(o),(e))) | ||
47 | |||
48 | void luaI_setfallback (void); | ||
49 | int luaI_ref (TObject *object, int lock); | ||
50 | TObject *luaI_getref (int ref); | ||
51 | void luaI_travlock (int (*fn)(TObject *)); | ||
52 | void luaI_invalidaterefs (void); | ||
53 | char *luaI_travfallbacks (int (*fn)(TObject *)); | ||
54 | |||
55 | void luaI_settag (int tag, TObject *o); | ||
56 | void luaI_realtag (int tag); | ||
57 | int luaI_efectivetag (TObject *o); | ||
58 | void luaI_settagmethod (void); | ||
59 | void luaI_gettagmethod (void); | ||
60 | void luaI_seterrormethod (void); | ||
61 | void luaI_initfallbacks (void); | ||
62 | |||
63 | #endif | ||
64 | |||
@@ -0,0 +1,317 @@ | |||
1 | /* | ||
2 | ** $Id: $ | ||
3 | ** Tag methods | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | #include <stdio.h> | ||
9 | #include <string.h> | ||
10 | |||
11 | #include "lauxlib.h" | ||
12 | #include "ldo.h" | ||
13 | #include "lmem.h" | ||
14 | #include "lobject.h" | ||
15 | #include "ltm.h" | ||
16 | |||
17 | static struct IM init_IM[NUM_TYPES] = { | ||
18 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
19 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
20 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
21 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
22 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
23 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
24 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
25 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
26 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
27 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
28 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
29 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
30 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
31 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
32 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
33 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
34 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
35 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
36 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
37 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
38 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
39 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
40 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
41 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
42 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
43 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
44 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
45 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
46 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
47 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
48 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
49 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
50 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
51 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
52 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
53 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
54 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
55 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
56 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
57 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
58 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
59 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
60 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
61 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
62 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
63 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
64 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
65 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
66 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
67 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
68 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
69 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
70 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
71 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
72 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
73 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
74 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
75 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
76 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
77 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}}, | ||
78 | {{{LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
79 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
80 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
81 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
82 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, | ||
83 | {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}}} | ||
84 | }; | ||
85 | |||
86 | |||
87 | |||
88 | |||
89 | char *luaT_eventname[] = { /* ORDER IM */ | ||
90 | "gettable", "settable", "index", "getglobal", "setglobal", "add", | ||
91 | "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge", | ||
92 | "concat", "gc", "function", | ||
93 | NULL | ||
94 | }; | ||
95 | |||
96 | |||
97 | static int luaI_checkevent (char *name, char *list[]) | ||
98 | { | ||
99 | int e = luaO_findstring(name, list); | ||
100 | if (e < 0) | ||
101 | luaL_verror("`%.50s' is not a valid event name", name); | ||
102 | return e; | ||
103 | } | ||
104 | |||
105 | |||
106 | struct IM *luaT_IMtable = init_IM; | ||
107 | |||
108 | static int IMtable_size = NUM_TYPES; | ||
109 | |||
110 | static int last_tag = -(NUM_TYPES-1); | ||
111 | |||
112 | |||
113 | /* events in LUA_T_LINE are all allowed, since this is used as a | ||
114 | * 'placeholder' for "default" fallbacks | ||
115 | */ | ||
116 | static char validevents[NUM_TYPES][IM_N] = { /* ORDER LUA_T, ORDER IM */ | ||
117 | {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */ | ||
118 | {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_LINE */ | ||
119 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_CMARK */ | ||
120 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_MARK */ | ||
121 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */ | ||
122 | {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_FUNCTION */ | ||
123 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_PROTO */ | ||
124 | {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */ | ||
125 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */ | ||
126 | {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */ | ||
127 | {1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */ | ||
128 | }; | ||
129 | |||
130 | static int validevent (lua_Type t, int e) | ||
131 | { /* ORDER LUA_T */ | ||
132 | return (t < LUA_T_NIL) ? 1 : validevents[-t][e]; | ||
133 | } | ||
134 | |||
135 | |||
136 | static void init_entry (int tag) | ||
137 | { | ||
138 | int i; | ||
139 | for (i=0; i<IM_N; i++) | ||
140 | ttype(luaT_getim(tag, i)) = LUA_T_NIL; | ||
141 | } | ||
142 | |||
143 | int lua_newtag (void) | ||
144 | { | ||
145 | --last_tag; | ||
146 | if ((-last_tag) >= IMtable_size) { | ||
147 | if (luaT_IMtable == init_IM) { /* fist time? */ | ||
148 | IMtable_size *= 2; | ||
149 | luaT_IMtable = luaM_newvector(IMtable_size, struct IM); | ||
150 | memcpy(luaT_IMtable, init_IM, sizeof(init_IM)); | ||
151 | } | ||
152 | else | ||
153 | IMtable_size = luaM_growvector(&luaT_IMtable, IMtable_size, | ||
154 | struct IM, memEM, MAX_INT); | ||
155 | } | ||
156 | init_entry(last_tag); | ||
157 | return last_tag; | ||
158 | } | ||
159 | |||
160 | |||
161 | static void checktag (int tag) | ||
162 | { /* ORDER LUA_T */ | ||
163 | if (!(last_tag <= tag && tag <= 0)) | ||
164 | luaL_verror("%d is not a valid tag", tag); | ||
165 | } | ||
166 | |||
167 | void luaT_realtag (int tag) | ||
168 | { | ||
169 | if (!(last_tag <= tag && tag < LUA_T_NIL)) | ||
170 | luaL_verror("tag %d is not result of `newtag'", tag); | ||
171 | } | ||
172 | |||
173 | |||
174 | |||
175 | int luaT_efectivetag (TObject *o) | ||
176 | { | ||
177 | lua_Type t = ttype(o); | ||
178 | if (t == LUA_T_USERDATA) { | ||
179 | int tag = o->value.ts->tag; | ||
180 | return (tag >= 0) ? LUA_T_USERDATA : tag; | ||
181 | } | ||
182 | else if (t == LUA_T_ARRAY) | ||
183 | return o->value.a->htag; | ||
184 | else return t; | ||
185 | } | ||
186 | |||
187 | |||
188 | TObject *luaT_gettagmethod (int t, char *event) | ||
189 | { | ||
190 | int e = luaI_checkevent(event, luaT_eventname); | ||
191 | checktag(t); | ||
192 | if (validevent(t, e)) | ||
193 | return luaT_getim(t,e); | ||
194 | else | ||
195 | return luaT_getim(LUA_T_CMARK, IM_GETTABLE); /* always nil */ | ||
196 | } | ||
197 | |||
198 | |||
199 | void luaT_settagmethod (int t, char *event, TObject *func) | ||
200 | { | ||
201 | TObject temp = *func; | ||
202 | int e = luaI_checkevent(event, luaT_eventname); | ||
203 | checktag(t); | ||
204 | if (!validevent(t, e)) | ||
205 | luaL_verror("settagmethod: cannot change internal method `%s' for tag %d", | ||
206 | luaT_eventname[e], t); | ||
207 | *func = *luaT_getim(t,e); | ||
208 | *luaT_getim(t, e) = temp; | ||
209 | } | ||
210 | |||
211 | |||
212 | char *luaT_travtagmethods (int (*fn)(TObject *)) | ||
213 | { | ||
214 | int e; | ||
215 | if (fn(&luaD_errorim)) | ||
216 | return "error"; | ||
217 | for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */ | ||
218 | int t; | ||
219 | for (t=0; t>=last_tag; t--) | ||
220 | if (fn(luaT_getim(t,e))) | ||
221 | return luaT_eventname[e]; | ||
222 | } | ||
223 | return NULL; | ||
224 | } | ||
225 | |||
226 | |||
227 | /* | ||
228 | * =================================================================== | ||
229 | * compatibility with old fallback system | ||
230 | */ | ||
231 | #if LUA_COMPAT2_5 | ||
232 | |||
233 | #include "lapi.h" | ||
234 | |||
235 | static void errorFB (void) | ||
236 | { | ||
237 | lua_Object o = lua_getparam(1); | ||
238 | if (lua_isstring(o)) | ||
239 | fprintf(stderr, "lua: %s\n", lua_getstring(o)); | ||
240 | else | ||
241 | fprintf(stderr, "lua: unknown error\n"); | ||
242 | } | ||
243 | |||
244 | |||
245 | static void nilFB (void) { } | ||
246 | |||
247 | |||
248 | static void typeFB (void) | ||
249 | { | ||
250 | lua_error("unexpected type"); | ||
251 | } | ||
252 | |||
253 | |||
254 | static void fillvalids (IMS e, TObject *func) | ||
255 | { | ||
256 | int t; | ||
257 | for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++) | ||
258 | if (validevent(t, e)) | ||
259 | *luaT_getim(t, e) = *func; | ||
260 | } | ||
261 | |||
262 | |||
263 | void luaT_setfallback (void) | ||
264 | { | ||
265 | static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; | ||
266 | TObject oldfunc; | ||
267 | lua_CFunction replace; | ||
268 | char *name = luaL_check_string(1); | ||
269 | lua_Object func = lua_getparam(2); | ||
270 | luaL_arg_check(lua_isfunction(func), 2, "function expected"); | ||
271 | switch (luaO_findstring(name, oldnames)) { | ||
272 | case 0: /* old error fallback */ | ||
273 | oldfunc = luaD_errorim; | ||
274 | luaD_errorim = *luaA_Address(func); | ||
275 | replace = errorFB; | ||
276 | break; | ||
277 | case 1: /* old getglobal fallback */ | ||
278 | oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); | ||
279 | *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); | ||
280 | replace = nilFB; | ||
281 | break; | ||
282 | case 2: { /* old arith fallback */ | ||
283 | int i; | ||
284 | oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW); | ||
285 | for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ | ||
286 | fillvalids(i, luaA_Address(func)); | ||
287 | replace = typeFB; | ||
288 | break; | ||
289 | } | ||
290 | case 3: { /* old order fallback */ | ||
291 | int i; | ||
292 | oldfunc = *luaT_getim(LUA_T_LINE, IM_LT); | ||
293 | for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ | ||
294 | fillvalids(i, luaA_Address(func)); | ||
295 | replace = typeFB; | ||
296 | break; | ||
297 | } | ||
298 | default: { | ||
299 | int e; | ||
300 | if ((e = luaO_findstring(name, luaT_eventname)) >= 0) { | ||
301 | oldfunc = *luaT_getim(LUA_T_LINE, e); | ||
302 | fillvalids(e, luaA_Address(func)); | ||
303 | replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; | ||
304 | } | ||
305 | else { | ||
306 | luaL_verror("`%.50s' is not a valid fallback name", name); | ||
307 | replace = NULL; /* to avoid warnings */ | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | if (oldfunc.ttype != LUA_T_NIL) | ||
312 | luaA_pushobject(&oldfunc); | ||
313 | else | ||
314 | lua_pushcfunction(replace); | ||
315 | } | ||
316 | #endif | ||
317 | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | ** $Id: $ | ||
3 | ** Tag methods | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | #ifndef ltm_h | ||
8 | #define ltm_h | ||
9 | |||
10 | |||
11 | #include "lobject.h" | ||
12 | |||
13 | /* | ||
14 | * WARNING: if you change the order of this enumeration, | ||
15 | * grep "ORDER IM" | ||
16 | */ | ||
17 | typedef enum { | ||
18 | IM_GETTABLE = 0, | ||
19 | IM_SETTABLE, | ||
20 | IM_INDEX, | ||
21 | IM_GETGLOBAL, | ||
22 | IM_SETGLOBAL, | ||
23 | IM_ADD, | ||
24 | IM_SUB, | ||
25 | IM_MUL, | ||
26 | IM_DIV, | ||
27 | IM_POW, | ||
28 | IM_UNM, | ||
29 | IM_LT, | ||
30 | IM_LE, | ||
31 | IM_GT, | ||
32 | IM_GE, | ||
33 | IM_CONCAT, | ||
34 | IM_GC, | ||
35 | IM_FUNCTION | ||
36 | } IMS; | ||
37 | |||
38 | #define IM_N 18 | ||
39 | |||
40 | |||
41 | extern struct IM { | ||
42 | TObject int_method[IM_N]; | ||
43 | } *luaT_IMtable; | ||
44 | |||
45 | |||
46 | #define luaT_getim(tag,event) (&luaT_IMtable[-(tag)].int_method[event]) | ||
47 | #define luaT_getimbyObj(o,e) (luaT_getim(luaT_efectivetag(o),(e))) | ||
48 | |||
49 | extern char *luaT_eventname[]; | ||
50 | |||
51 | |||
52 | void luaT_settag (int tag, TObject *o); | ||
53 | void luaT_realtag (int tag); | ||
54 | int luaT_efectivetag (TObject *o); | ||
55 | void luaT_settagmethod (int t, char *event, TObject *func); | ||
56 | TObject *luaT_gettagmethod (int t, char *event); | ||
57 | char *luaT_travtagmethods (int (*fn)(TObject *)); | ||
58 | |||
59 | void luaT_setfallback (void); /* only if LUA_COMPAT2_5 */ | ||
60 | |||
61 | #endif | ||