diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-02 18:30:53 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1994-11-02 18:30:53 -0200 |
commit | fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022 (patch) | |
tree | 030c6dd803fff11ae0c368e90b78a9fef2b8b731 /opcode.c | |
parent | ae77864844d6b933eb8be68694cbb8498af165dc (diff) | |
download | lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.tar.gz lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.tar.bz2 lua-fbf887ec2be8b293d6f3ffc88b42c5a9e87bf022.zip |
new way to call functions, plus several small changes. This is
a temporary version!
Diffstat (limited to 'opcode.c')
-rw-r--r-- | opcode.c | 1298 |
1 files changed, 633 insertions, 665 deletions
@@ -3,11 +3,12 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 2.11 1994/11/01 17:54:31 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 2.12 1994/11/01 18:25:20 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <stdio.h> | 8 | #include <stdio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | #include <string.h> | 10 | #include <string.h> |
11 | #include <setjmp.h> | ||
11 | #include <math.h> | 12 | #include <math.h> |
12 | #ifdef __GNUC__ | 13 | #ifdef __GNUC__ |
13 | #include <floatingpoint.h> | 14 | #include <floatingpoint.h> |
@@ -19,57 +20,69 @@ char *rcs_opcode="$Id: opcode.c,v 2.11 1994/11/01 17:54:31 roberto Exp roberto $ | |||
19 | #include "table.h" | 20 | #include "table.h" |
20 | #include "lua.h" | 21 | #include "lua.h" |
21 | 22 | ||
22 | #define tonumber(o) ((tag(o) != T_NUMBER) && (lua_tonumber(o) != 0)) | 23 | #define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) |
23 | #define tostring(o) ((tag(o) != T_STRING) && (lua_tostring(o) != 0)) | 24 | #define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) |
24 | 25 | ||
25 | 26 | ||
26 | #define STACK_BUFFER (STACKGAP+128) | 27 | #define STACK_BUFFER (STACKGAP+128) |
27 | 28 | ||
28 | static Long maxstack; | 29 | static Long maxstack; |
29 | static Object *stack=NULL; | 30 | static Object *stack=NULL; |
30 | static Object *top, *base; | 31 | static Object *top; |
32 | |||
33 | static int CBase; /* when Lua calls C or C calls Lua, points to the */ | ||
34 | /* first slot after the last parameter. */ | ||
35 | static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ | ||
36 | /* when C calls Lua, has the number of results. */ | ||
37 | |||
38 | static jmp_buf *errorJmp; | ||
39 | |||
40 | static int lua_execute (Byte *pc, int base); | ||
41 | |||
42 | |||
43 | |||
44 | /* | ||
45 | ** Reports an error, and jumps up to the available recover label | ||
46 | */ | ||
47 | void lua_error (char *s) | ||
48 | { | ||
49 | fprintf (stderr, "lua: %s\n", s); | ||
50 | if (errorJmp) | ||
51 | longjmp(*errorJmp, 1); | ||
52 | else | ||
53 | exit(1); | ||
54 | } | ||
31 | 55 | ||
32 | 56 | ||
33 | /* | 57 | /* |
34 | ** Init stack | 58 | ** Init stack |
35 | */ | 59 | */ |
36 | static int lua_initstack (void) | 60 | static void lua_initstack (void) |
37 | { | 61 | { |
38 | maxstack = STACK_BUFFER; | 62 | maxstack = STACK_BUFFER; |
39 | stack = (Object *)calloc(maxstack, sizeof(Object)); | 63 | stack = (Object *)calloc(maxstack, sizeof(Object)); |
40 | if (stack == NULL) | 64 | if (stack == NULL) |
41 | { | 65 | lua_error("stack - not enough memory"); |
42 | lua_error("stack - not enough memory"); | 66 | top = stack; |
43 | return 1; | ||
44 | } | ||
45 | tag(stack) = T_MARK; | ||
46 | top = base = stack+1; | ||
47 | return 0; | ||
48 | } | 67 | } |
49 | 68 | ||
50 | 69 | ||
51 | /* | 70 | /* |
52 | ** Check stack overflow and, if necessary, realloc vector | 71 | ** Check stack overflow and, if necessary, realloc vector |
53 | */ | 72 | */ |
54 | static int lua_checkstack (Word n) | 73 | static void lua_checkstack (Word n) |
55 | { | 74 | { |
56 | if (stack == NULL) | 75 | if (stack == NULL) |
57 | return lua_initstack(); | 76 | return lua_initstack(); |
58 | if (n > maxstack) | 77 | if (n > maxstack) |
59 | { | 78 | { |
60 | Word t = top-stack; | 79 | int t = top-stack; |
61 | Word b = base-stack; | ||
62 | maxstack *= 2; | 80 | maxstack *= 2; |
63 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); | 81 | stack = (Object *)realloc(stack, maxstack*sizeof(Object)); |
64 | if (stack == NULL) | 82 | if (stack == NULL) |
65 | { | 83 | lua_error("stack - not enough memory"); |
66 | lua_error("stack - not enough memory"); | ||
67 | return 1; | ||
68 | } | ||
69 | top = stack + t; | 84 | top = stack + t; |
70 | base = stack + b; | ||
71 | } | 85 | } |
72 | return 0; | ||
73 | } | 86 | } |
74 | 87 | ||
75 | 88 | ||
@@ -82,10 +95,7 @@ static char *lua_strconc (char *l, char *r) | |||
82 | static char buffer[1024]; | 95 | static char buffer[1024]; |
83 | int n = strlen(l)+strlen(r)+1; | 96 | int n = strlen(l)+strlen(r)+1; |
84 | if (n > 1024) | 97 | if (n > 1024) |
85 | { | 98 | lua_error ("string too large"); |
86 | lua_error ("string too large"); | ||
87 | return NULL; | ||
88 | } | ||
89 | return strcat(strcpy(buffer,l),r); | 99 | return strcat(strcpy(buffer,l),r); |
90 | } | 100 | } |
91 | 101 | ||
@@ -99,59 +109,46 @@ static int ToReal (char* s, float* f) | |||
99 | /* | 109 | /* |
100 | ** Convert, if possible, to a number object. | 110 | ** Convert, if possible, to a number object. |
101 | ** Return 0 if success, not 0 if error. | 111 | ** Return 0 if success, not 0 if error. |
102 | */ | 112 | */ |
103 | static int lua_tonumber (Object *obj) | 113 | static int lua_tonumber (Object *obj) |
104 | { | 114 | { |
105 | if (tag(obj) != T_STRING) | 115 | if (tag(obj) != LUA_T_STRING) |
106 | { | 116 | return 1;; |
107 | lua_reportbug ("unexpected type at conversion to number"); | ||
108 | return 1; | ||
109 | } | ||
110 | if (!ToReal(svalue(obj), &nvalue(obj))) | 117 | if (!ToReal(svalue(obj), &nvalue(obj))) |
111 | { | 118 | return 2; |
112 | lua_reportbug ("string to number convertion failed"); | 119 | tag(obj) = LUA_T_NUMBER; |
113 | return 2; | ||
114 | } | ||
115 | tag(obj) = T_NUMBER; | ||
116 | return 0; | 120 | return 0; |
117 | } | 121 | } |
118 | 122 | ||
119 | /* | 123 | /* |
120 | ** Test if it is possible to convert an object to a number object. | 124 | ** Test if it is possible to convert an object to a number object. |
121 | ** If possible, return the converted object, otherwise return nil object. | 125 | ** If possible, return the converted object, otherwise return nil object. |
122 | */ | 126 | */ |
123 | static Object *lua_convtonumber (Object *obj) | 127 | static Object *lua_convtonumber (Object *obj) |
124 | { | 128 | { |
125 | static Object cvt; | 129 | static Object cvt; |
126 | 130 | if (tag(obj) == LUA_T_NUMBER) | |
127 | if (tag(obj) == T_NUMBER) | ||
128 | { | 131 | { |
129 | cvt = *obj; | 132 | cvt = *obj; |
130 | return &cvt; | 133 | return &cvt; |
131 | } | 134 | } |
132 | 135 | if (tag(obj) == LUA_T_STRING && ToReal(svalue(obj), &nvalue(&cvt))) | |
133 | if (tag(obj) == T_STRING && ToReal(svalue(obj), &nvalue(&cvt))) | 136 | tag(&cvt) = LUA_T_NUMBER; |
134 | tag(&cvt) = T_NUMBER; | 137 | else |
135 | else | 138 | tag(&cvt) = LUA_T_NIL; |
136 | tag(&cvt) = T_NIL; | ||
137 | |||
138 | return &cvt; | 139 | return &cvt; |
139 | } | 140 | } |
140 | 141 | ||
141 | 142 | ||
142 | |||
143 | /* | 143 | /* |
144 | ** Convert, if possible, to a string tag | 144 | ** Convert, if possible, to a string tag |
145 | ** Return 0 in success or not 0 on error. | 145 | ** Return 0 in success or not 0 on error. |
146 | */ | 146 | */ |
147 | static int lua_tostring (Object *obj) | 147 | static int lua_tostring (Object *obj) |
148 | { | 148 | { |
149 | static char s[256]; | 149 | static char s[256]; |
150 | if (tag(obj) != T_NUMBER) | 150 | if (tag(obj) != LUA_T_NUMBER) |
151 | { | 151 | lua_reportbug ("unexpected type at conversion to string"); |
152 | lua_reportbug ("unexpected type at conversion to string"); | ||
153 | return 1; | ||
154 | } | ||
155 | if ((int) nvalue(obj) == nvalue(obj)) | 152 | if ((int) nvalue(obj) == nvalue(obj)) |
156 | sprintf (s, "%d", (int) nvalue(obj)); | 153 | sprintf (s, "%d", (int) nvalue(obj)); |
157 | else | 154 | else |
@@ -159,487 +156,67 @@ static int lua_tostring (Object *obj) | |||
159 | svalue(obj) = lua_createstring(s); | 156 | svalue(obj) = lua_createstring(s); |
160 | if (svalue(obj) == NULL) | 157 | if (svalue(obj) == NULL) |
161 | return 1; | 158 | return 1; |
162 | tag(obj) = T_STRING; | 159 | tag(obj) = LUA_T_STRING; |
163 | return 0; | 160 | return 0; |
164 | } | 161 | } |
165 | 162 | ||
166 | 163 | ||
167 | /* | 164 | /* |
168 | ** Execute the given opcode. Return 0 in success or 1 on error. | 165 | ** Adjust stack. Set top to the given value, pushing NILs if needed. |
169 | */ | 166 | */ |
170 | int lua_execute (Byte *pc) | 167 | static void adjust_top (Object *newtop) |
171 | { | 168 | { |
172 | Word oldbase; | 169 | while (top < newtop) tag(top++) = LUA_T_NIL; |
173 | 170 | top = newtop; /* top could be bigger than newtop */ | |
174 | if (stack == NULL) | 171 | } |
175 | lua_initstack(); | ||
176 | |||
177 | oldbase = base-stack; | ||
178 | base = top; | ||
179 | while (1) | ||
180 | { | ||
181 | OpCode opcode; | ||
182 | switch (opcode = (OpCode)*pc++) | ||
183 | { | ||
184 | case PUSHNIL: tag(top++) = T_NIL; break; | ||
185 | |||
186 | case PUSH0: tag(top) = T_NUMBER; nvalue(top++) = 0; break; | ||
187 | case PUSH1: tag(top) = T_NUMBER; nvalue(top++) = 1; break; | ||
188 | case PUSH2: tag(top) = T_NUMBER; nvalue(top++) = 2; break; | ||
189 | |||
190 | case PUSHBYTE: tag(top) = T_NUMBER; nvalue(top++) = *pc++; break; | ||
191 | |||
192 | case PUSHWORD: | ||
193 | { | ||
194 | CodeWord code; | ||
195 | get_word(code,pc); | ||
196 | tag(top) = T_NUMBER; nvalue(top++) = code.w; | ||
197 | } | ||
198 | break; | ||
199 | |||
200 | case PUSHFLOAT: | ||
201 | { | ||
202 | CodeFloat code; | ||
203 | get_float(code,pc); | ||
204 | tag(top) = T_NUMBER; nvalue(top++) = code.f; | ||
205 | } | ||
206 | break; | ||
207 | 172 | ||
208 | case PUSHSTRING: | ||
209 | { | ||
210 | CodeWord code; | ||
211 | get_word(code,pc); | ||
212 | tag(top) = T_STRING; svalue(top++) = lua_constant[code.w]; | ||
213 | } | ||
214 | break; | ||
215 | 173 | ||
216 | case PUSHFUNCTION: | 174 | /* |
217 | { | 175 | ** Call a C function. CBase will point to the top of the stack, |
218 | CodeCode code; | 176 | ** and CnResults is the number of parameters. Returns an index |
219 | get_code(code,pc); | 177 | ** to the first result from C. |
220 | tag(top) = T_FUNCTION; bvalue(top++) = code.b; | 178 | */ |
221 | } | 179 | static int callC (lua_CFunction func, int base) |
222 | break; | 180 | { |
223 | 181 | int oldBase = CBase; | |
224 | case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: | 182 | int oldCnResults = CnResults; |
225 | case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: | 183 | int firstResult; |
226 | case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: | 184 | CnResults = (top-stack) - base; |
227 | case PUSHLOCAL9: *top++ = *(base + (int)(opcode-PUSHLOCAL0)); break; | 185 | CBase = base+CnResults; /* incorporate parameters on the stack */ |
228 | 186 | (*func)(); | |
229 | case PUSHLOCAL: *top++ = *(base + (*pc++)); break; | 187 | firstResult = CBase; |
230 | 188 | CBase = oldBase; | |
231 | case PUSHGLOBAL: | 189 | CnResults = oldCnResults; |
232 | { | 190 | return firstResult; |
233 | CodeWord code; | 191 | } |
234 | get_word(code,pc); | ||
235 | *top++ = s_object(code.w); | ||
236 | } | ||
237 | break; | ||
238 | |||
239 | case PUSHINDEXED: | ||
240 | { | ||
241 | int s = lua_pushsubscript(); | ||
242 | if (s == 1) return 1; | ||
243 | } | ||
244 | break; | ||
245 | |||
246 | case PUSHMARK: tag(top++) = T_MARK; break; | ||
247 | case PUSHMARKMET: | ||
248 | { | ||
249 | Object receiver = *(top-2); | ||
250 | if (lua_pushsubscript() == 1) return 1; | ||
251 | tag(top++) = T_MARK; | ||
252 | *(top++) = receiver; | ||
253 | break; | ||
254 | } | ||
255 | |||
256 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: | ||
257 | case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: | ||
258 | case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: | ||
259 | case STORELOCAL9: *(base + (int)(opcode-STORELOCAL0)) = *(--top); break; | ||
260 | |||
261 | case STORELOCAL: *(base + (*pc++)) = *(--top); break; | ||
262 | |||
263 | case STOREGLOBAL: | ||
264 | { | ||
265 | CodeWord code; | ||
266 | get_word(code,pc); | ||
267 | s_object(code.w) = *(--top); | ||
268 | } | ||
269 | break; | ||
270 | |||
271 | case STOREINDEXED0: | ||
272 | { | ||
273 | int s = lua_storesubscript(); | ||
274 | if (s == 1) return 1; | ||
275 | } | ||
276 | break; | ||
277 | |||
278 | case STOREINDEXED: | ||
279 | { | ||
280 | int n = *pc++; | ||
281 | if (tag(top-3-n) != T_ARRAY) | ||
282 | { | ||
283 | lua_reportbug ("indexed expression not a table"); | ||
284 | return 1; | ||
285 | } | ||
286 | { | ||
287 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | ||
288 | if (h == NULL) return 1; | ||
289 | *h = *(top-1); | ||
290 | } | ||
291 | top--; | ||
292 | } | ||
293 | break; | ||
294 | |||
295 | case STORELIST0: | ||
296 | case STORELIST: | ||
297 | { | ||
298 | int m, n; | ||
299 | Object *arr; | ||
300 | if (opcode == STORELIST0) m = 0; | ||
301 | else m = *(pc++) * FIELDS_PER_FLUSH; | ||
302 | n = *(pc++); | ||
303 | arr = top-n-1; | ||
304 | if (tag(arr) != T_ARRAY) | ||
305 | { | ||
306 | lua_reportbug ("internal error - table expected"); | ||
307 | return 1; | ||
308 | } | ||
309 | while (n) | ||
310 | { | ||
311 | tag(top) = T_NUMBER; nvalue(top) = n+m; | ||
312 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
313 | top--; | ||
314 | n--; | ||
315 | } | ||
316 | } | ||
317 | break; | ||
318 | |||
319 | case STORERECORD: | ||
320 | { | ||
321 | int n = *(pc++); | ||
322 | Object *arr = top-n-1; | ||
323 | if (tag(arr) != T_ARRAY) | ||
324 | { | ||
325 | lua_reportbug ("internal error - table expected"); | ||
326 | return 1; | ||
327 | } | ||
328 | while (n) | ||
329 | { | ||
330 | CodeWord code; | ||
331 | get_word(code,pc); | ||
332 | tag(top) = T_STRING; svalue(top) = lua_constant[code.w]; | ||
333 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
334 | top--; | ||
335 | n--; | ||
336 | } | ||
337 | } | ||
338 | break; | ||
339 | |||
340 | case ADJUST: | ||
341 | { | ||
342 | Object *newtop = base + *(pc++); | ||
343 | while (top < newtop) tag(top++) = T_NIL; | ||
344 | top = newtop; /* top could be bigger than newtop */ | ||
345 | } | ||
346 | break; | ||
347 | |||
348 | case CREATEARRAY: | ||
349 | { | ||
350 | CodeWord size; | ||
351 | get_word(size,pc); | ||
352 | top++; | ||
353 | avalue(top-1) = lua_createarray(size.w); | ||
354 | if (avalue(top-1) == NULL) | ||
355 | return 1; | ||
356 | tag(top-1) = T_ARRAY; | ||
357 | } | ||
358 | break; | ||
359 | |||
360 | case EQOP: | ||
361 | { | ||
362 | Object *l = top-2; | ||
363 | Object *r = top-1; | ||
364 | --top; | ||
365 | if (tag(l) != tag(r)) | ||
366 | tag(top-1) = T_NIL; | ||
367 | else | ||
368 | { | ||
369 | switch (tag(l)) | ||
370 | { | ||
371 | case T_NIL: tag(top-1) = T_NUMBER; break; | ||
372 | case T_NUMBER: tag(top-1) = (nvalue(l) == nvalue(r)) ? T_NUMBER : T_NIL; break; | ||
373 | case T_ARRAY: tag(top-1) = (avalue(l) == avalue(r)) ? T_NUMBER : T_NIL; break; | ||
374 | case T_FUNCTION: tag(top-1) = (bvalue(l) == bvalue(r)) ? T_NUMBER : T_NIL; break; | ||
375 | case T_CFUNCTION: tag(top-1) = (fvalue(l) == fvalue(r)) ? T_NUMBER : T_NIL; break; | ||
376 | case T_USERDATA: tag(top-1) = (uvalue(l) == uvalue(r)) ? T_NUMBER : T_NIL; break; | ||
377 | case T_STRING: tag(top-1) = (strcmp (svalue(l), svalue(r)) == 0) ? T_NUMBER : T_NIL; break; | ||
378 | case T_MARK: return 1; | ||
379 | } | ||
380 | } | ||
381 | nvalue(top-1) = 1; | ||
382 | } | ||
383 | break; | ||
384 | |||
385 | case LTOP: | ||
386 | { | ||
387 | Object *l = top-2; | ||
388 | Object *r = top-1; | ||
389 | --top; | ||
390 | if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | ||
391 | tag(top-1) = (nvalue(l) < nvalue(r)) ? T_NUMBER : T_NIL; | ||
392 | else | ||
393 | { | ||
394 | if (tostring(l) || tostring(r)) | ||
395 | return 1; | ||
396 | tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? T_NUMBER : T_NIL; | ||
397 | } | ||
398 | nvalue(top-1) = 1; | ||
399 | } | ||
400 | break; | ||
401 | |||
402 | case LEOP: | ||
403 | { | ||
404 | Object *l = top-2; | ||
405 | Object *r = top-1; | ||
406 | --top; | ||
407 | if (tag(l) == T_NUMBER && tag(r) == T_NUMBER) | ||
408 | tag(top-1) = (nvalue(l) <= nvalue(r)) ? T_NUMBER : T_NIL; | ||
409 | else | ||
410 | { | ||
411 | if (tostring(l) || tostring(r)) | ||
412 | return 1; | ||
413 | tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? T_NUMBER : T_NIL; | ||
414 | } | ||
415 | nvalue(top-1) = 1; | ||
416 | } | ||
417 | break; | ||
418 | |||
419 | case ADDOP: | ||
420 | { | ||
421 | Object *l = top-2; | ||
422 | Object *r = top-1; | ||
423 | if (tonumber(r) || tonumber(l)) | ||
424 | return 1; | ||
425 | nvalue(l) += nvalue(r); | ||
426 | --top; | ||
427 | } | ||
428 | break; | ||
429 | |||
430 | case SUBOP: | ||
431 | { | ||
432 | Object *l = top-2; | ||
433 | Object *r = top-1; | ||
434 | if (tonumber(r) || tonumber(l)) | ||
435 | return 1; | ||
436 | nvalue(l) -= nvalue(r); | ||
437 | --top; | ||
438 | } | ||
439 | break; | ||
440 | |||
441 | case MULTOP: | ||
442 | { | ||
443 | Object *l = top-2; | ||
444 | Object *r = top-1; | ||
445 | if (tonumber(r) || tonumber(l)) | ||
446 | return 1; | ||
447 | nvalue(l) *= nvalue(r); | ||
448 | --top; | ||
449 | } | ||
450 | break; | ||
451 | |||
452 | case DIVOP: | ||
453 | { | ||
454 | Object *l = top-2; | ||
455 | Object *r = top-1; | ||
456 | if (tonumber(r) || tonumber(l)) | ||
457 | return 1; | ||
458 | nvalue(l) /= nvalue(r); | ||
459 | --top; | ||
460 | } | ||
461 | break; | ||
462 | |||
463 | case POWOP: | ||
464 | { | ||
465 | Object *l = top-2; | ||
466 | Object *r = top-1; | ||
467 | if (tonumber(r) || tonumber(l)) | ||
468 | return 1; | ||
469 | nvalue(l) = pow(nvalue(l), nvalue(r)); | ||
470 | --top; | ||
471 | } | ||
472 | break; | ||
473 | |||
474 | case CONCOP: | ||
475 | { | ||
476 | Object *l = top-2; | ||
477 | Object *r = top-1; | ||
478 | if (tostring(r) || tostring(l)) | ||
479 | return 1; | ||
480 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | ||
481 | if (svalue(l) == NULL) | ||
482 | return 1; | ||
483 | --top; | ||
484 | } | ||
485 | break; | ||
486 | |||
487 | case MINUSOP: | ||
488 | if (tonumber(top-1)) | ||
489 | return 1; | ||
490 | nvalue(top-1) = - nvalue(top-1); | ||
491 | break; | ||
492 | |||
493 | case NOTOP: | ||
494 | tag(top-1) = tag(top-1) == T_NIL ? T_NUMBER : T_NIL; | ||
495 | break; | ||
496 | |||
497 | case ONTJMP: | ||
498 | { | ||
499 | CodeWord code; | ||
500 | get_word(code,pc); | ||
501 | if (tag(top-1) != T_NIL) pc += code.w; | ||
502 | } | ||
503 | break; | ||
504 | |||
505 | case ONFJMP: | ||
506 | { | ||
507 | CodeWord code; | ||
508 | get_word(code,pc); | ||
509 | if (tag(top-1) == T_NIL) pc += code.w; | ||
510 | } | ||
511 | break; | ||
512 | |||
513 | case JMP: | ||
514 | { | ||
515 | CodeWord code; | ||
516 | get_word(code,pc); | ||
517 | pc += code.w; | ||
518 | } | ||
519 | break; | ||
520 | |||
521 | case UPJMP: | ||
522 | { | ||
523 | CodeWord code; | ||
524 | get_word(code,pc); | ||
525 | pc -= code.w; | ||
526 | } | ||
527 | break; | ||
528 | |||
529 | case IFFJMP: | ||
530 | { | ||
531 | CodeWord code; | ||
532 | get_word(code,pc); | ||
533 | top--; | ||
534 | if (tag(top) == T_NIL) pc += code.w; | ||
535 | } | ||
536 | break; | ||
537 | 192 | ||
538 | case IFFUPJMP: | ||
539 | { | ||
540 | CodeWord code; | ||
541 | get_word(code,pc); | ||
542 | top--; | ||
543 | if (tag(top) == T_NIL) pc -= code.w; | ||
544 | } | ||
545 | break; | ||
546 | 193 | ||
547 | case POP: --top; break; | 194 | /* |
548 | 195 | ** Call a function (C or Lua). The parameters must be on the stack, | |
549 | case CALLFUNC: | 196 | ** between [stack+base,top). When returns, the results are on the stack, |
550 | { | 197 | ** between [stack+whereRes,top). The number of results is nResults, unless |
551 | Byte *newpc; | 198 | ** nResults=MULT_RET. |
552 | Object *b = top-1; | 199 | */ |
553 | while (tag(b) != T_MARK) b--; | 200 | static void do_call (Object *func, int base, int nResults, int whereRes) |
554 | if (tag(b-1) == T_FUNCTION) | 201 | { |
555 | { | 202 | int firstResult; |
556 | lua_debugline = 0; /* always reset debug flag */ | 203 | if (tag(func) == LUA_T_CFUNCTION) |
557 | newpc = bvalue(b-1); | 204 | firstResult = callC(fvalue(func), base); |
558 | bvalue(b-1) = pc; /* store return code */ | 205 | else if (tag(func) == LUA_T_FUNCTION) |
559 | nvalue(b) = (base-stack); /* store base value */ | 206 | firstResult = lua_execute(bvalue(func), base); |
560 | base = b+1; | 207 | else |
561 | pc = newpc; | 208 | lua_reportbug ("call expression not a function"); |
562 | if (lua_checkstack(STACKGAP+(base-stack))) | 209 | /* adjust the number of results */ |
563 | return 1; | 210 | if (nResults != MULT_RET && top - (stack+firstResult) != nResults) |
564 | } | 211 | adjust_top(stack+firstResult+nResults); |
565 | else if (tag(b-1) == T_CFUNCTION) | 212 | /* move results to the given position */ |
566 | { | 213 | if (firstResult != whereRes) |
567 | int nparam; | 214 | { |
568 | lua_debugline = 0; /* always reset debug flag */ | 215 | int i = top - (stack+firstResult); /* number of results */ |
569 | nvalue(b) = (base-stack); /* store base value */ | 216 | top -= firstResult-whereRes; |
570 | base = b+1; | 217 | while (i--) |
571 | nparam = top-base; /* number of parameters */ | 218 | *(stack+whereRes+i) = *(stack+firstResult+i); |
572 | (fvalue(b-1))(); /* call C function */ | ||
573 | |||
574 | /* shift returned values */ | ||
575 | { | ||
576 | int i; | ||
577 | int nretval = top - base - nparam; | ||
578 | top = base - 2; | ||
579 | base = stack + (int) nvalue(base-1); | ||
580 | for (i=0; i<nretval; i++) | ||
581 | { | ||
582 | *top = *(top+nparam+2); | ||
583 | ++top; | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | else | ||
588 | { | ||
589 | lua_reportbug ("call expression not a function"); | ||
590 | return 1; | ||
591 | } | ||
592 | } | ||
593 | break; | ||
594 | |||
595 | case RETCODE: | ||
596 | { | ||
597 | int i; | ||
598 | int shift = *pc++; | ||
599 | int nretval = top - base - shift; | ||
600 | top = base - 2; | ||
601 | pc = bvalue(base-2); | ||
602 | base = stack + (int) nvalue(base-1); | ||
603 | for (i=0; i<nretval; i++) | ||
604 | { | ||
605 | *top = *(top+shift+2); | ||
606 | ++top; | ||
607 | } | ||
608 | } | ||
609 | break; | ||
610 | |||
611 | case HALT: | ||
612 | base = stack+oldbase; | ||
613 | return 0; /* success */ | ||
614 | |||
615 | case SETFUNCTION: | ||
616 | { | ||
617 | CodeCode file; | ||
618 | CodeWord func; | ||
619 | get_code(file,pc); | ||
620 | get_word(func,pc); | ||
621 | if (lua_pushfunction ((char *)file.b, func.w)) | ||
622 | return 1; | ||
623 | } | ||
624 | break; | ||
625 | |||
626 | case SETLINE: | ||
627 | { | ||
628 | CodeWord code; | ||
629 | get_word(code,pc); | ||
630 | lua_debugline = code.w; | ||
631 | } | ||
632 | break; | ||
633 | |||
634 | case RESET: | ||
635 | lua_popfunction (); | ||
636 | break; | ||
637 | |||
638 | default: | ||
639 | lua_error ("internal error - opcode didn't match"); | ||
640 | return 1; | ||
641 | } | 219 | } |
642 | } | ||
643 | } | 220 | } |
644 | 221 | ||
645 | 222 | ||
@@ -649,7 +226,7 @@ int lua_execute (Byte *pc) | |||
649 | int lua_pushsubscript (void) | 226 | int lua_pushsubscript (void) |
650 | { | 227 | { |
651 | --top; | 228 | --top; |
652 | if (tag(top-1) != T_ARRAY) | 229 | if (tag(top-1) != LUA_T_ARRAY) |
653 | { | 230 | { |
654 | lua_reportbug ("indexed expression not a table"); | 231 | lua_reportbug ("indexed expression not a table"); |
655 | return 1; | 232 | return 1; |
@@ -668,7 +245,7 @@ int lua_pushsubscript (void) | |||
668 | */ | 245 | */ |
669 | int lua_storesubscript (void) | 246 | int lua_storesubscript (void) |
670 | { | 247 | { |
671 | if (tag(top-3) != T_ARRAY) | 248 | if (tag(top-3) != LUA_T_ARRAY) |
672 | { | 249 | { |
673 | lua_reportbug ("indexed expression not a table"); | 250 | lua_reportbug ("indexed expression not a table"); |
674 | return 1; | 251 | return 1; |
@@ -693,61 +270,89 @@ void lua_travstack (void (*fn)(Object *)) | |||
693 | fn (o); | 270 | fn (o); |
694 | } | 271 | } |
695 | 272 | ||
273 | |||
696 | /* | 274 | /* |
697 | ** Open file, generate opcode and execute global statement. Return 0 on | 275 | ** Executes a main procedure. Uses as Base the top of the stack, as it |
698 | ** success or 1 on error. | 276 | ** uses no parameters and left no results. |
699 | */ | 277 | */ |
700 | int lua_dofile (char *filename) | 278 | static void do_main (Byte *main) |
701 | { | 279 | { |
702 | if (lua_openfile (filename)) return 1; | 280 | if (main) |
703 | if (lua_parse ()) { lua_closefile (); return 1; } | 281 | { |
704 | lua_closefile (); | 282 | Object f; |
705 | return 0; | 283 | tag(&f) = LUA_T_FUNCTION; bvalue(&f) = main; |
284 | do_call(&f, top-stack, 0, top-stack); | ||
285 | free(main); | ||
286 | } | ||
706 | } | 287 | } |
707 | 288 | ||
289 | |||
708 | /* | 290 | /* |
709 | ** Generate opcode stored on string and execute global statement. Return 0 on | 291 | ** Open file, generate opcode and execute global statement. Return 0 on |
710 | ** success or 1 on error. | 292 | ** success or 1 on error. |
711 | */ | 293 | */ |
712 | int lua_dostring (char *string) | 294 | int lua_dofile (char *filename) |
713 | { | 295 | { |
714 | if (lua_openstring (string)) return 1; | 296 | jmp_buf myErrorJmp; |
715 | if (lua_parse ()) return 1; | 297 | int status; |
716 | lua_closestring(); | 298 | jmp_buf *oldErr = errorJmp; |
717 | return 0; | 299 | errorJmp = &myErrorJmp; |
300 | if (setjmp(myErrorJmp) == 0) | ||
301 | { | ||
302 | lua_openfile (filename); | ||
303 | do_main(lua_parse()); | ||
304 | status = 0; | ||
305 | } | ||
306 | else | ||
307 | status = 1; | ||
308 | lua_closefile(); | ||
309 | errorJmp = oldErr; | ||
310 | return status; | ||
718 | } | 311 | } |
719 | 312 | ||
720 | /* | 313 | /* |
721 | ** Execute the given function. Return 0 on success or 1 on error. | 314 | ** Generate opcode stored on string and execute global statement. Return 0 on |
315 | ** success or 1 on error. | ||
722 | */ | 316 | */ |
723 | int lua_call (char *functionname, int nparam) | 317 | int lua_dostring (char *string) |
724 | { | 318 | { |
725 | static Byte startcode[] = {CALLFUNC, HALT}; | 319 | jmp_buf myErrorJmp; |
726 | int i; | 320 | int status; |
727 | Object func = s_object(lua_findsymbol(functionname)); | 321 | jmp_buf *oldErr = errorJmp; |
728 | if (tag(&func) != T_FUNCTION) return 1; | 322 | errorJmp = &myErrorJmp; |
729 | for (i=1; i<=nparam; i++) | 323 | if (setjmp(myErrorJmp) == 0) |
730 | *(top-i+2) = *(top-i); | 324 | { |
731 | top += 2; | 325 | lua_openstring(string); |
732 | tag(top-nparam-1) = T_MARK; | 326 | do_main(lua_parse()); |
733 | *(top-nparam-2) = func; | 327 | status = 0; |
734 | return (lua_execute (startcode)); | 328 | } |
329 | else | ||
330 | status = 1; | ||
331 | lua_closestring(); | ||
332 | errorJmp = oldErr; | ||
333 | return status; | ||
735 | } | 334 | } |
736 | 335 | ||
737 | /* | 336 | /* |
738 | ** Execute the given lua function. Return 0 on success or 1 on error. | 337 | ** Execute the given lua function. Return 0 on success or 1 on error. |
739 | */ | 338 | */ |
740 | int lua_callfunction (Object *function, int nparam) | 339 | int lua_callfunction (Object *function) |
741 | { | 340 | { |
742 | static Byte startcode[] = {CALLFUNC, HALT}; | 341 | jmp_buf myErrorJmp; |
743 | int i; | 342 | int status; |
744 | if (tag(function) != T_FUNCTION) return 1; | 343 | jmp_buf *oldErr = errorJmp; |
745 | for (i=1; i<=nparam; i++) | 344 | errorJmp = &myErrorJmp; |
746 | *(top-i+2) = *(top-i); | 345 | if (setjmp(myErrorJmp) == 0) |
747 | top += 2; | 346 | { |
748 | tag(top-nparam-1) = T_MARK; | 347 | do_call(function, CBase, MULT_RET, CBase); |
749 | *(top-nparam-2) = *function; | 348 | CnResults = (top-stack) - CBase; /* number of results */ |
750 | return (lua_execute (startcode)); | 349 | CBase += CnResults; /* incorporate results on the stack */ |
350 | status = 0; | ||
351 | } | ||
352 | else | ||
353 | status = 1; | ||
354 | errorJmp = oldErr; | ||
355 | return status; | ||
751 | } | 356 | } |
752 | 357 | ||
753 | /* | 358 | /* |
@@ -756,8 +361,8 @@ int lua_callfunction (Object *function, int nparam) | |||
756 | */ | 361 | */ |
757 | Object *lua_getparam (int number) | 362 | Object *lua_getparam (int number) |
758 | { | 363 | { |
759 | if (number <= 0 || number > top-base) return NULL; | 364 | if (number <= 0 || number > CnResults) return NULL; |
760 | return (base+number-1); | 365 | return (stack+(CBase-CnResults+number-1)); |
761 | } | 366 | } |
762 | 367 | ||
763 | /* | 368 | /* |
@@ -765,7 +370,7 @@ Object *lua_getparam (int number) | |||
765 | */ | 370 | */ |
766 | real lua_getnumber (Object *object) | 371 | real lua_getnumber (Object *object) |
767 | { | 372 | { |
768 | if (object == NULL || tag(object) == T_NIL) return 0.0; | 373 | if (object == NULL || tag(object) == LUA_T_NIL) return 0.0; |
769 | if (tonumber (object)) return 0.0; | 374 | if (tonumber (object)) return 0.0; |
770 | else return (nvalue(object)); | 375 | else return (nvalue(object)); |
771 | } | 376 | } |
@@ -775,7 +380,7 @@ real lua_getnumber (Object *object) | |||
775 | */ | 380 | */ |
776 | char *lua_getstring (Object *object) | 381 | char *lua_getstring (Object *object) |
777 | { | 382 | { |
778 | if (object == NULL || tag(object) == T_NIL) return NULL; | 383 | if (object == NULL || tag(object) == LUA_T_NIL) return NULL; |
779 | if (tostring (object)) return NULL; | 384 | if (tostring (object)) return NULL; |
780 | else return (svalue(object)); | 385 | else return (svalue(object)); |
781 | } | 386 | } |
@@ -785,7 +390,7 @@ char *lua_getstring (Object *object) | |||
785 | */ | 390 | */ |
786 | char *lua_copystring (Object *object) | 391 | char *lua_copystring (Object *object) |
787 | { | 392 | { |
788 | if (object == NULL || tag(object) == T_NIL) return NULL; | 393 | if (object == NULL || tag(object) == LUA_T_NIL) return NULL; |
789 | if (tostring (object)) return NULL; | 394 | if (tostring (object)) return NULL; |
790 | else return (strdup(svalue(object))); | 395 | else return (strdup(svalue(object))); |
791 | } | 396 | } |
@@ -796,7 +401,7 @@ char *lua_copystring (Object *object) | |||
796 | lua_CFunction lua_getcfunction (Object *object) | 401 | lua_CFunction lua_getcfunction (Object *object) |
797 | { | 402 | { |
798 | if (object == NULL) return NULL; | 403 | if (object == NULL) return NULL; |
799 | if (tag(object) != T_CFUNCTION) return NULL; | 404 | if (tag(object) != LUA_T_CFUNCTION) return NULL; |
800 | else return (fvalue(object)); | 405 | else return (fvalue(object)); |
801 | } | 406 | } |
802 | 407 | ||
@@ -806,7 +411,7 @@ lua_CFunction lua_getcfunction (Object *object) | |||
806 | void *lua_getuserdata (Object *object) | 411 | void *lua_getuserdata (Object *object) |
807 | { | 412 | { |
808 | if (object == NULL) return NULL; | 413 | if (object == NULL) return NULL; |
809 | if (tag(object) != T_USERDATA) return NULL; | 414 | if (tag(object) != LUA_T_USERDATA) return NULL; |
810 | else return (uvalue(object)); | 415 | else return (uvalue(object)); |
811 | } | 416 | } |
812 | 417 | ||
@@ -816,7 +421,7 @@ void *lua_getuserdata (Object *object) | |||
816 | void *lua_gettable (Object *object) | 421 | void *lua_gettable (Object *object) |
817 | { | 422 | { |
818 | if (object == NULL) return NULL; | 423 | if (object == NULL) return NULL; |
819 | if (tag(object) != T_ARRAY) return NULL; | 424 | if (tag(object) != LUA_T_ARRAY) return NULL; |
820 | else return (avalue(object)); | 425 | else return (avalue(object)); |
821 | } | 426 | } |
822 | 427 | ||
@@ -827,12 +432,12 @@ void *lua_gettable (Object *object) | |||
827 | Object *lua_getfield (Object *object, char *field) | 432 | Object *lua_getfield (Object *object, char *field) |
828 | { | 433 | { |
829 | if (object == NULL) return NULL; | 434 | if (object == NULL) return NULL; |
830 | if (tag(object) != T_ARRAY) | 435 | if (tag(object) != LUA_T_ARRAY) |
831 | return NULL; | 436 | return NULL; |
832 | else | 437 | else |
833 | { | 438 | { |
834 | Object ref; | 439 | Object ref; |
835 | tag(&ref) = T_STRING; | 440 | tag(&ref) = LUA_T_STRING; |
836 | svalue(&ref) = lua_constant[lua_findconstant(field)]; | 441 | svalue(&ref) = lua_constant[lua_findconstant(field)]; |
837 | return (lua_hashget(avalue(object), &ref)); | 442 | return (lua_hashget(avalue(object), &ref)); |
838 | } | 443 | } |
@@ -845,12 +450,12 @@ Object *lua_getfield (Object *object, char *field) | |||
845 | Object *lua_getindexed (Object *object, float index) | 450 | Object *lua_getindexed (Object *object, float index) |
846 | { | 451 | { |
847 | if (object == NULL) return NULL; | 452 | if (object == NULL) return NULL; |
848 | if (tag(object) != T_ARRAY) | 453 | if (tag(object) != LUA_T_ARRAY) |
849 | return NULL; | 454 | return NULL; |
850 | else | 455 | else |
851 | { | 456 | { |
852 | Object ref; | 457 | Object ref; |
853 | tag(&ref) = T_NUMBER; | 458 | tag(&ref) = LUA_T_NUMBER; |
854 | nvalue(&ref) = index; | 459 | nvalue(&ref) = index; |
855 | return (lua_hashget(avalue(object), &ref)); | 460 | return (lua_hashget(avalue(object), &ref)); |
856 | } | 461 | } |
@@ -867,23 +472,12 @@ Object *lua_getglobal (char *name) | |||
867 | } | 472 | } |
868 | 473 | ||
869 | /* | 474 | /* |
870 | ** Pop and return an object | ||
871 | */ | ||
872 | Object *lua_pop (void) | ||
873 | { | ||
874 | if (top <= base) return NULL; | ||
875 | top--; | ||
876 | return top; | ||
877 | } | ||
878 | |||
879 | /* | ||
880 | ** Push a nil object | 475 | ** Push a nil object |
881 | */ | 476 | */ |
882 | int lua_pushnil (void) | 477 | int lua_pushnil (void) |
883 | { | 478 | { |
884 | if (lua_checkstack(top-stack+1) == 1) | 479 | lua_checkstack(top-stack+1); |
885 | return 1; | 480 | tag(top++) = LUA_T_NIL; |
886 | tag(top++) = T_NIL; | ||
887 | return 0; | 481 | return 0; |
888 | } | 482 | } |
889 | 483 | ||
@@ -892,9 +486,8 @@ int lua_pushnil (void) | |||
892 | */ | 486 | */ |
893 | int lua_pushnumber (real n) | 487 | int lua_pushnumber (real n) |
894 | { | 488 | { |
895 | if (lua_checkstack(top-stack+1) == 1) | 489 | lua_checkstack(top-stack+1); |
896 | return 1; | 490 | tag(top) = LUA_T_NUMBER; nvalue(top++) = n; |
897 | tag(top) = T_NUMBER; nvalue(top++) = n; | ||
898 | return 0; | 491 | return 0; |
899 | } | 492 | } |
900 | 493 | ||
@@ -903,9 +496,8 @@ int lua_pushnumber (real n) | |||
903 | */ | 496 | */ |
904 | int lua_pushstring (char *s) | 497 | int lua_pushstring (char *s) |
905 | { | 498 | { |
906 | if (lua_checkstack(top-stack+1) == 1) | 499 | lua_checkstack(top-stack+1); |
907 | return 1; | 500 | tag(top) = LUA_T_STRING; |
908 | tag(top) = T_STRING; | ||
909 | svalue(top++) = lua_createstring(s); | 501 | svalue(top++) = lua_createstring(s); |
910 | return 0; | 502 | return 0; |
911 | } | 503 | } |
@@ -915,9 +507,8 @@ int lua_pushstring (char *s) | |||
915 | */ | 507 | */ |
916 | int lua_pushcfunction (lua_CFunction fn) | 508 | int lua_pushcfunction (lua_CFunction fn) |
917 | { | 509 | { |
918 | if (lua_checkstack(top-stack+1) == 1) | 510 | lua_checkstack(top-stack+1); |
919 | return 1; | 511 | tag(top) = LUA_T_CFUNCTION; fvalue(top++) = fn; |
920 | tag(top) = T_CFUNCTION; fvalue(top++) = fn; | ||
921 | return 0; | 512 | return 0; |
922 | } | 513 | } |
923 | 514 | ||
@@ -926,9 +517,8 @@ int lua_pushcfunction (lua_CFunction fn) | |||
926 | */ | 517 | */ |
927 | int lua_pushuserdata (void *u) | 518 | int lua_pushuserdata (void *u) |
928 | { | 519 | { |
929 | if (lua_checkstack(top-stack+1) == 1) | 520 | lua_checkstack(top-stack+1); |
930 | return 1; | 521 | tag(top) = LUA_T_USERDATA; uvalue(top++) = u; |
931 | tag(top) = T_USERDATA; uvalue(top++) = u; | ||
932 | return 0; | 522 | return 0; |
933 | } | 523 | } |
934 | 524 | ||
@@ -937,9 +527,8 @@ int lua_pushuserdata (void *u) | |||
937 | */ | 527 | */ |
938 | int lua_pushtable (void *t) | 528 | int lua_pushtable (void *t) |
939 | { | 529 | { |
940 | if (lua_checkstack(top-stack+1) == 1) | 530 | lua_checkstack(top-stack+1); |
941 | return 1; | 531 | tag(top) = LUA_T_ARRAY; avalue(top++) = t; |
942 | tag(top) = T_ARRAY; avalue(top++) = t; | ||
943 | return 0; | 532 | return 0; |
944 | } | 533 | } |
945 | 534 | ||
@@ -948,21 +537,20 @@ int lua_pushtable (void *t) | |||
948 | */ | 537 | */ |
949 | int lua_pushobject (Object *o) | 538 | int lua_pushobject (Object *o) |
950 | { | 539 | { |
951 | if (lua_checkstack(top-stack+1) == 1) | 540 | lua_checkstack(top-stack+1); |
952 | return 1; | ||
953 | *top++ = *o; | 541 | *top++ = *o; |
954 | return 0; | 542 | return 0; |
955 | } | 543 | } |
956 | 544 | ||
957 | /* | 545 | /* |
958 | ** Store top of the stack at a global variable array field. | 546 | ** Store top of the stack at a global variable array field. |
959 | ** Return 1 on error, 0 on success. | 547 | ** Return 1 on error, 0 on success. |
960 | */ | 548 | */ |
961 | int lua_storeglobal (char *name) | 549 | int lua_storeglobal (char *name) |
962 | { | 550 | { |
963 | int n = lua_findsymbol (name); | 551 | int n = lua_findsymbol (name); |
964 | if (n < 0) return 1; | 552 | if (n < 0) return 1; |
965 | if (tag(top-1) == T_MARK) return 1; | 553 | if (tag(top-1) == LUA_T_MARK) return 1; |
966 | s_object(n) = *(--top); | 554 | s_object(n) = *(--top); |
967 | return 0; | 555 | return 0; |
968 | } | 556 | } |
@@ -973,16 +561,16 @@ int lua_storeglobal (char *name) | |||
973 | */ | 561 | */ |
974 | int lua_storefield (lua_Object object, char *field) | 562 | int lua_storefield (lua_Object object, char *field) |
975 | { | 563 | { |
976 | if (tag(object) != T_ARRAY) | 564 | if (tag(object) != LUA_T_ARRAY) |
977 | return 1; | 565 | return 1; |
978 | else | 566 | else |
979 | { | 567 | { |
980 | Object ref, *h; | 568 | Object ref, *h; |
981 | tag(&ref) = T_STRING; | 569 | tag(&ref) = LUA_T_STRING; |
982 | svalue(&ref) = lua_createstring(field); | 570 | svalue(&ref) = lua_createstring(field); |
983 | h = lua_hashdefine(avalue(object), &ref); | 571 | h = lua_hashdefine(avalue(object), &ref); |
984 | if (h == NULL) return 1; | 572 | if (h == NULL) return 1; |
985 | if (tag(top-1) == T_MARK) return 1; | 573 | if (tag(top-1) == LUA_T_MARK) return 1; |
986 | *h = *(--top); | 574 | *h = *(--top); |
987 | } | 575 | } |
988 | return 0; | 576 | return 0; |
@@ -994,16 +582,16 @@ int lua_storefield (lua_Object object, char *field) | |||
994 | */ | 582 | */ |
995 | int lua_storeindexed (lua_Object object, float index) | 583 | int lua_storeindexed (lua_Object object, float index) |
996 | { | 584 | { |
997 | if (tag(object) != T_ARRAY) | 585 | if (tag(object) != LUA_T_ARRAY) |
998 | return 1; | 586 | return 1; |
999 | else | 587 | else |
1000 | { | 588 | { |
1001 | Object ref, *h; | 589 | Object ref, *h; |
1002 | tag(&ref) = T_NUMBER; | 590 | tag(&ref) = LUA_T_NUMBER; |
1003 | nvalue(&ref) = index; | 591 | nvalue(&ref) = index; |
1004 | h = lua_hashdefine(avalue(object), &ref); | 592 | h = lua_hashdefine(avalue(object), &ref); |
1005 | if (h == NULL) return 1; | 593 | if (h == NULL) return 1; |
1006 | if (tag(top-1) == T_MARK) return 1; | 594 | if (tag(top-1) == LUA_T_MARK) return 1; |
1007 | *h = *(--top); | 595 | *h = *(--top); |
1008 | } | 596 | } |
1009 | return 0; | 597 | return 0; |
@@ -1015,7 +603,7 @@ int lua_storeindexed (lua_Object object, float index) | |||
1015 | */ | 603 | */ |
1016 | int lua_isnil (Object *object) | 604 | int lua_isnil (Object *object) |
1017 | { | 605 | { |
1018 | return (object != NULL && tag(object) == T_NIL); | 606 | return (object != NULL && tag(object) == LUA_T_NIL); |
1019 | } | 607 | } |
1020 | 608 | ||
1021 | /* | 609 | /* |
@@ -1023,7 +611,7 @@ int lua_isnil (Object *object) | |||
1023 | */ | 611 | */ |
1024 | int lua_isnumber (Object *object) | 612 | int lua_isnumber (Object *object) |
1025 | { | 613 | { |
1026 | return (object != NULL && tag(object) == T_NUMBER); | 614 | return (object != NULL && tag(object) == LUA_T_NUMBER); |
1027 | } | 615 | } |
1028 | 616 | ||
1029 | /* | 617 | /* |
@@ -1031,7 +619,7 @@ int lua_isnumber (Object *object) | |||
1031 | */ | 619 | */ |
1032 | int lua_isstring (Object *object) | 620 | int lua_isstring (Object *object) |
1033 | { | 621 | { |
1034 | return (object != NULL && tag(object) == T_STRING); | 622 | return (object != NULL && tag(object) == LUA_T_STRING); |
1035 | } | 623 | } |
1036 | 624 | ||
1037 | /* | 625 | /* |
@@ -1039,7 +627,7 @@ int lua_isstring (Object *object) | |||
1039 | */ | 627 | */ |
1040 | int lua_istable (Object *object) | 628 | int lua_istable (Object *object) |
1041 | { | 629 | { |
1042 | return (object != NULL && tag(object) == T_ARRAY); | 630 | return (object != NULL && tag(object) == LUA_T_ARRAY); |
1043 | } | 631 | } |
1044 | 632 | ||
1045 | /* | 633 | /* |
@@ -1047,15 +635,15 @@ int lua_istable (Object *object) | |||
1047 | */ | 635 | */ |
1048 | int lua_isfunction (Object *object) | 636 | int lua_isfunction (Object *object) |
1049 | { | 637 | { |
1050 | return (object != NULL && tag(object) == T_FUNCTION); | 638 | return (object != NULL && tag(object) == LUA_T_FUNCTION); |
1051 | } | 639 | } |
1052 | 640 | ||
1053 | /* | 641 | /* |
1054 | ** Given an object handle, return if it is a cfunction one. | 642 | ** Given an object handle, return if it is a cfunction one. |
1055 | */ | 643 | */ |
1056 | int lua_iscfunction (Object *object) | 644 | int lua_iscfunction (Object *object) |
1057 | { | 645 | { |
1058 | return (object != NULL && tag(object) == T_CFUNCTION); | 646 | return (object != NULL && tag(object) == LUA_T_CFUNCTION); |
1059 | } | 647 | } |
1060 | 648 | ||
1061 | /* | 649 | /* |
@@ -1063,21 +651,10 @@ int lua_iscfunction (Object *object) | |||
1063 | */ | 651 | */ |
1064 | int lua_isuserdata (Object *object) | 652 | int lua_isuserdata (Object *object) |
1065 | { | 653 | { |
1066 | return (object != NULL && tag(object) == T_USERDATA); | 654 | return (object != NULL && tag(object) == LUA_T_USERDATA); |
1067 | } | ||
1068 | |||
1069 | /* | ||
1070 | ** Internal function: return an object type. | ||
1071 | */ | ||
1072 | void lua_type (void) | ||
1073 | { | ||
1074 | Object *o = lua_getparam(1); | ||
1075 | |||
1076 | if (lua_constant == NULL) | ||
1077 | lua_initconstant(); | ||
1078 | lua_pushstring (lua_constant[tag(o)]); | ||
1079 | } | 655 | } |
1080 | 656 | ||
657 | |||
1081 | /* | 658 | /* |
1082 | ** Internal function: convert an object to a number | 659 | ** Internal function: convert an object to a number |
1083 | */ | 660 | */ |
@@ -1087,48 +664,439 @@ void lua_obj2number (void) | |||
1087 | lua_pushobject (lua_convtonumber(o)); | 664 | lua_pushobject (lua_convtonumber(o)); |
1088 | } | 665 | } |
1089 | 666 | ||
667 | |||
668 | |||
1090 | /* | 669 | /* |
1091 | ** Internal function: print object values | 670 | ** Execute the given opcode, until a RET. Parameters are between |
671 | ** [stack+base,top). Returns n such that the the results are between | ||
672 | ** [stack+n,top). | ||
1092 | */ | 673 | */ |
1093 | void lua_print (void) | 674 | static int lua_execute (Byte *pc, int base) |
1094 | { | 675 | { |
1095 | int i=1; | 676 | lua_debugline = 0; /* reset debug flag */ |
1096 | Object *obj; | 677 | if (stack == NULL) |
1097 | while ((obj=lua_getparam (i++)) != NULL) | 678 | lua_initstack(); |
679 | while (1) | ||
1098 | { | 680 | { |
1099 | if (lua_isnumber(obj)) printf("%g\n",lua_getnumber (obj)); | 681 | OpCode opcode; |
1100 | else if (lua_isstring(obj)) printf("%s\n",lua_getstring (obj)); | 682 | switch (opcode = (OpCode)*pc++) |
1101 | else if (lua_isfunction(obj)) printf("function: %p\n",bvalue(obj)); | 683 | { |
1102 | else if (lua_iscfunction(obj)) printf("cfunction: %p\n",lua_getcfunction (obj)); | 684 | case PUSHNIL: tag(top++) = LUA_T_NIL; break; |
1103 | else if (lua_isuserdata(obj)) printf("userdata: %p\n",lua_getuserdata (obj)); | ||
1104 | else if (lua_istable(obj)) printf("table: %p\n",obj); | ||
1105 | else if (lua_isnil(obj)) printf("nil\n"); | ||
1106 | else printf("invalid value to print\n"); | ||
1107 | } | ||
1108 | } | ||
1109 | 685 | ||
1110 | /* | 686 | case PUSH0: tag(top) = LUA_T_NUMBER; nvalue(top++) = 0; break; |
1111 | ** Internal function: do a file | 687 | case PUSH1: tag(top) = LUA_T_NUMBER; nvalue(top++) = 1; break; |
1112 | */ | 688 | case PUSH2: tag(top) = LUA_T_NUMBER; nvalue(top++) = 2; break; |
1113 | void lua_internaldofile (void) | ||
1114 | { | ||
1115 | lua_Object obj = lua_getparam (1); | ||
1116 | if (lua_isstring(obj) && !lua_dofile(lua_getstring(obj))) | ||
1117 | lua_pushnumber(1); | ||
1118 | else | ||
1119 | lua_pushnil(); | ||
1120 | } | ||
1121 | 689 | ||
1122 | /* | 690 | case PUSHBYTE: tag(top) = LUA_T_NUMBER; nvalue(top++) = *pc++; break; |
1123 | ** Internal function: do a string | 691 | |
1124 | */ | 692 | case PUSHWORD: |
1125 | void lua_internaldostring (void) | 693 | { |
1126 | { | 694 | CodeWord code; |
1127 | lua_Object obj = lua_getparam (1); | 695 | get_word(code,pc); |
1128 | if (lua_isstring(obj) && !lua_dostring(lua_getstring(obj))) | 696 | tag(top) = LUA_T_NUMBER; nvalue(top++) = code.w; |
1129 | lua_pushnumber(1); | 697 | } |
1130 | else | 698 | break; |
1131 | lua_pushnil(); | 699 | |
1132 | } | 700 | case PUSHFLOAT: |
701 | { | ||
702 | CodeFloat code; | ||
703 | get_float(code,pc); | ||
704 | tag(top) = LUA_T_NUMBER; nvalue(top++) = code.f; | ||
705 | } | ||
706 | break; | ||
707 | |||
708 | case PUSHSTRING: | ||
709 | { | ||
710 | CodeWord code; | ||
711 | get_word(code,pc); | ||
712 | tag(top) = LUA_T_STRING; svalue(top++) = lua_constant[code.w]; | ||
713 | } | ||
714 | break; | ||
715 | |||
716 | case PUSHFUNCTION: | ||
717 | { | ||
718 | CodeCode code; | ||
719 | get_code(code,pc); | ||
720 | tag(top) = LUA_T_FUNCTION; bvalue(top++) = code.b; | ||
721 | } | ||
722 | break; | ||
723 | |||
724 | case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: | ||
725 | case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: | ||
726 | case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: | ||
727 | case PUSHLOCAL9: *top++ = *((stack+base) + (int)(opcode-PUSHLOCAL0)); break; | ||
728 | |||
729 | case PUSHLOCAL: *top++ = *((stack+base) + (*pc++)); break; | ||
730 | |||
731 | case PUSHGLOBAL: | ||
732 | { | ||
733 | CodeWord code; | ||
734 | get_word(code,pc); | ||
735 | *top++ = s_object(code.w); | ||
736 | } | ||
737 | break; | ||
738 | |||
739 | case PUSHINDEXED: | ||
740 | { | ||
741 | int s = lua_pushsubscript(); | ||
742 | if (s == 1) return 1; | ||
743 | } | ||
744 | break; | ||
745 | |||
746 | case PUSHSELF: | ||
747 | { | ||
748 | Object receiver = *(top-2); | ||
749 | if (lua_pushsubscript() == 1) return 1; | ||
750 | *(top++) = receiver; | ||
751 | break; | ||
752 | } | ||
753 | |||
754 | case STORELOCAL0: case STORELOCAL1: case STORELOCAL2: | ||
755 | case STORELOCAL3: case STORELOCAL4: case STORELOCAL5: | ||
756 | case STORELOCAL6: case STORELOCAL7: case STORELOCAL8: | ||
757 | case STORELOCAL9: | ||
758 | *((stack+base) + (int)(opcode-STORELOCAL0)) = *(--top); | ||
759 | break; | ||
760 | |||
761 | case STORELOCAL: *((stack+base) + (*pc++)) = *(--top); break; | ||
762 | |||
763 | case STOREGLOBAL: | ||
764 | { | ||
765 | CodeWord code; | ||
766 | get_word(code,pc); | ||
767 | s_object(code.w) = *(--top); | ||
768 | } | ||
769 | break; | ||
770 | |||
771 | case STOREINDEXED0: | ||
772 | { | ||
773 | int s = lua_storesubscript(); | ||
774 | if (s == 1) return 1; | ||
775 | } | ||
776 | break; | ||
777 | |||
778 | case STOREINDEXED: | ||
779 | { | ||
780 | int n = *pc++; | ||
781 | if (tag(top-3-n) != LUA_T_ARRAY) | ||
782 | { | ||
783 | lua_reportbug ("indexed expression not a table"); | ||
784 | return 1; | ||
785 | } | ||
786 | { | ||
787 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | ||
788 | if (h == NULL) return 1; | ||
789 | *h = *(top-1); | ||
790 | } | ||
791 | top--; | ||
792 | } | ||
793 | break; | ||
794 | |||
795 | case STORELIST0: | ||
796 | case STORELIST: | ||
797 | { | ||
798 | int m, n; | ||
799 | Object *arr; | ||
800 | if (opcode == STORELIST0) m = 0; | ||
801 | else m = *(pc++) * FIELDS_PER_FLUSH; | ||
802 | n = *(pc++); | ||
803 | arr = top-n-1; | ||
804 | if (tag(arr) != LUA_T_ARRAY) | ||
805 | { | ||
806 | lua_reportbug ("internal error - table expected"); | ||
807 | return 1; | ||
808 | } | ||
809 | while (n) | ||
810 | { | ||
811 | tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; | ||
812 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
813 | top--; | ||
814 | n--; | ||
815 | } | ||
816 | } | ||
817 | break; | ||
818 | |||
819 | case STORERECORD: | ||
820 | { | ||
821 | int n = *(pc++); | ||
822 | Object *arr = top-n-1; | ||
823 | if (tag(arr) != LUA_T_ARRAY) | ||
824 | { | ||
825 | lua_reportbug ("internal error - table expected"); | ||
826 | return 1; | ||
827 | } | ||
828 | while (n) | ||
829 | { | ||
830 | CodeWord code; | ||
831 | get_word(code,pc); | ||
832 | tag(top) = LUA_T_STRING; svalue(top) = lua_constant[code.w]; | ||
833 | *(lua_hashdefine (avalue(arr), top)) = *(top-1); | ||
834 | top--; | ||
835 | n--; | ||
836 | } | ||
837 | } | ||
838 | break; | ||
839 | |||
840 | case ADJUST0: | ||
841 | adjust_top((stack+base)); | ||
842 | break; | ||
843 | |||
844 | case ADJUST: | ||
845 | adjust_top((stack+base) + *(pc++)); | ||
846 | break; | ||
847 | |||
848 | case CREATEARRAY: | ||
849 | { | ||
850 | CodeWord size; | ||
851 | get_word(size,pc); | ||
852 | top++; | ||
853 | avalue(top-1) = lua_createarray(size.w); | ||
854 | if (avalue(top-1) == NULL) | ||
855 | return 1; | ||
856 | tag(top-1) = LUA_T_ARRAY; | ||
857 | } | ||
858 | break; | ||
859 | |||
860 | case EQOP: | ||
861 | { | ||
862 | int res; | ||
863 | Object *l = top-2; | ||
864 | Object *r = top-1; | ||
865 | --top; | ||
866 | if (tag(l) != tag(r)) | ||
867 | res = 0; | ||
868 | else | ||
869 | { | ||
870 | switch (tag(l)) | ||
871 | { | ||
872 | case LUA_T_NIL: | ||
873 | res = 0; break; | ||
874 | case LUA_T_NUMBER: | ||
875 | res = (nvalue(l) == nvalue(r)); break; | ||
876 | case LUA_T_ARRAY: | ||
877 | res = (avalue(l) == avalue(r)); break; | ||
878 | case LUA_T_FUNCTION: | ||
879 | res = (bvalue(l) == bvalue(r)); break; | ||
880 | case LUA_T_CFUNCTION: | ||
881 | res = (fvalue(l) == fvalue(r)); break; | ||
882 | case LUA_T_STRING: | ||
883 | res = (strcmp (svalue(l), svalue(r)) == 0); break; | ||
884 | default: | ||
885 | res = (uvalue(l) == uvalue(r)); break; | ||
886 | } | ||
887 | } | ||
888 | tag(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; | ||
889 | nvalue(top-1) = 1; | ||
890 | } | ||
891 | break; | ||
892 | |||
893 | case LTOP: | ||
894 | { | ||
895 | Object *l = top-2; | ||
896 | Object *r = top-1; | ||
897 | --top; | ||
898 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
899 | tag(top-1) = (nvalue(l) < nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | ||
900 | else | ||
901 | { | ||
902 | if (tostring(l) || tostring(r)) | ||
903 | return 1; | ||
904 | tag(top-1) = (strcmp (svalue(l), svalue(r)) < 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
905 | } | ||
906 | nvalue(top-1) = 1; | ||
907 | } | ||
908 | break; | ||
909 | |||
910 | case LEOP: | ||
911 | { | ||
912 | Object *l = top-2; | ||
913 | Object *r = top-1; | ||
914 | --top; | ||
915 | if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) | ||
916 | tag(top-1) = (nvalue(l) <= nvalue(r)) ? LUA_T_NUMBER : LUA_T_NIL; | ||
917 | else | ||
918 | { | ||
919 | if (tostring(l) || tostring(r)) | ||
920 | return 1; | ||
921 | tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? LUA_T_NUMBER : LUA_T_NIL; | ||
922 | } | ||
923 | nvalue(top-1) = 1; | ||
924 | } | ||
925 | break; | ||
926 | |||
927 | case ADDOP: | ||
928 | { | ||
929 | Object *l = top-2; | ||
930 | Object *r = top-1; | ||
931 | if (tonumber(r) || tonumber(l)) | ||
932 | return 1; | ||
933 | nvalue(l) += nvalue(r); | ||
934 | --top; | ||
935 | } | ||
936 | break; | ||
937 | |||
938 | case SUBOP: | ||
939 | { | ||
940 | Object *l = top-2; | ||
941 | Object *r = top-1; | ||
942 | if (tonumber(r) || tonumber(l)) | ||
943 | return 1; | ||
944 | nvalue(l) -= nvalue(r); | ||
945 | --top; | ||
946 | } | ||
947 | break; | ||
1133 | 948 | ||
949 | case MULTOP: | ||
950 | { | ||
951 | Object *l = top-2; | ||
952 | Object *r = top-1; | ||
953 | if (tonumber(r) || tonumber(l)) | ||
954 | return 1; | ||
955 | nvalue(l) *= nvalue(r); | ||
956 | --top; | ||
957 | } | ||
958 | break; | ||
959 | |||
960 | case DIVOP: | ||
961 | { | ||
962 | Object *l = top-2; | ||
963 | Object *r = top-1; | ||
964 | if (tonumber(r) || tonumber(l)) | ||
965 | return 1; | ||
966 | nvalue(l) /= nvalue(r); | ||
967 | --top; | ||
968 | } | ||
969 | break; | ||
970 | |||
971 | case POWOP: | ||
972 | { | ||
973 | Object *l = top-2; | ||
974 | Object *r = top-1; | ||
975 | if (tonumber(r) || tonumber(l)) | ||
976 | return 1; | ||
977 | nvalue(l) = pow(nvalue(l), nvalue(r)); | ||
978 | --top; | ||
979 | } | ||
980 | break; | ||
981 | |||
982 | case CONCOP: | ||
983 | { | ||
984 | Object *l = top-2; | ||
985 | Object *r = top-1; | ||
986 | if (tostring(r) || tostring(l)) | ||
987 | return 1; | ||
988 | svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | ||
989 | if (svalue(l) == NULL) | ||
990 | return 1; | ||
991 | --top; | ||
992 | } | ||
993 | break; | ||
994 | |||
995 | case MINUSOP: | ||
996 | if (tonumber(top-1)) | ||
997 | return 1; | ||
998 | nvalue(top-1) = - nvalue(top-1); | ||
999 | break; | ||
1000 | |||
1001 | case NOTOP: | ||
1002 | tag(top-1) = tag(top-1) == LUA_T_NIL ? LUA_T_NUMBER : LUA_T_NIL; | ||
1003 | break; | ||
1004 | |||
1005 | case ONTJMP: | ||
1006 | { | ||
1007 | CodeWord code; | ||
1008 | get_word(code,pc); | ||
1009 | if (tag(top-1) != LUA_T_NIL) pc += code.w; | ||
1010 | } | ||
1011 | break; | ||
1012 | |||
1013 | case ONFJMP: | ||
1014 | { | ||
1015 | CodeWord code; | ||
1016 | get_word(code,pc); | ||
1017 | if (tag(top-1) == LUA_T_NIL) pc += code.w; | ||
1018 | } | ||
1019 | break; | ||
1020 | |||
1021 | case JMP: | ||
1022 | { | ||
1023 | CodeWord code; | ||
1024 | get_word(code,pc); | ||
1025 | pc += code.w; | ||
1026 | } | ||
1027 | break; | ||
1028 | |||
1029 | case UPJMP: | ||
1030 | { | ||
1031 | CodeWord code; | ||
1032 | get_word(code,pc); | ||
1033 | pc -= code.w; | ||
1034 | } | ||
1035 | break; | ||
1036 | |||
1037 | case IFFJMP: | ||
1038 | { | ||
1039 | CodeWord code; | ||
1040 | get_word(code,pc); | ||
1041 | top--; | ||
1042 | if (tag(top) == LUA_T_NIL) pc += code.w; | ||
1043 | } | ||
1044 | break; | ||
1045 | |||
1046 | case IFFUPJMP: | ||
1047 | { | ||
1048 | CodeWord code; | ||
1049 | get_word(code,pc); | ||
1050 | top--; | ||
1051 | if (tag(top) == LUA_T_NIL) pc -= code.w; | ||
1052 | } | ||
1053 | break; | ||
1054 | |||
1055 | case POP: --top; break; | ||
1056 | |||
1057 | case CALLFUNC: | ||
1058 | { | ||
1059 | int nParams = *(pc++); | ||
1060 | int nResults = *(pc++); | ||
1061 | Object *func = top-1-nParams; /* function is below parameters */ | ||
1062 | int newBase = (top-stack)-nParams; | ||
1063 | do_call(func, newBase, nResults, newBase-1); | ||
1064 | } | ||
1065 | break; | ||
1066 | |||
1067 | case RETCODE0: | ||
1068 | return base; | ||
1069 | |||
1070 | case RETCODE: | ||
1071 | return base+*pc; | ||
1072 | |||
1073 | case SETFUNCTION: | ||
1074 | { | ||
1075 | CodeCode file; | ||
1076 | CodeWord func; | ||
1077 | get_code(file,pc); | ||
1078 | get_word(func,pc); | ||
1079 | if (lua_pushfunction ((char *)file.b, func.w)) | ||
1080 | return 1; | ||
1081 | } | ||
1082 | break; | ||
1083 | |||
1084 | case SETLINE: | ||
1085 | { | ||
1086 | CodeWord code; | ||
1087 | get_word(code,pc); | ||
1088 | lua_debugline = code.w; | ||
1089 | } | ||
1090 | break; | ||
1091 | |||
1092 | case RESET: | ||
1093 | lua_popfunction (); | ||
1094 | break; | ||
1095 | |||
1096 | default: | ||
1097 | lua_error ("internal error - opcode doesn't match"); | ||
1098 | return 1; | ||
1099 | } | ||
1100 | } | ||
1101 | } | ||
1134 | 1102 | ||