aboutsummaryrefslogtreecommitdiff
path: root/opcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1994-11-04 08:47:49 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1994-11-04 08:47:49 -0200
commitc635044f2f0fc6a3cc19b720668b8bd8f61b5134 (patch)
treeb62f6a3826dc45a833cffcc09a93f38ad1e0c8d5 /opcode.c
parent3db06a95a388c2e0922fd138434321240a4eb075 (diff)
downloadlua-c635044f2f0fc6a3cc19b720668b8bd8f61b5134.tar.gz
lua-c635044f2f0fc6a3cc19b720668b8bd8f61b5134.tar.bz2
lua-c635044f2f0fc6a3cc19b720668b8bd8f61b5134.zip
creation of function do_protectedrun, that executes lua code enclosed
in a setjmp, with error recovery. Elimination of functions lua_isnil, etc.
Diffstat (limited to 'opcode.c')
-rw-r--r--opcode.c316
1 files changed, 96 insertions, 220 deletions
diff --git a/opcode.c b/opcode.c
index 268fe18f..298b172f 100644
--- a/opcode.c
+++ b/opcode.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_opcode="$Id: opcode.c,v 2.12 1994/11/01 18:25:20 roberto Exp roberto $"; 6char *rcs_opcode="$Id: opcode.c,v 3.1 1994/11/02 20:30:53 roberto Exp roberto $";
7 7
8#include <stdio.h> 8#include <stdio.h>
9#include <stdlib.h> 9#include <stdlib.h>
@@ -30,27 +30,36 @@ static Long maxstack;
30static Object *stack=NULL; 30static Object *stack=NULL;
31static Object *top; 31static Object *top;
32 32
33static int CBase; /* when Lua calls C or C calls Lua, points to the */ 33
34 /* first slot after the last parameter. */ 34static int CBase = 0; /* when Lua calls C or C calls Lua, points to the */
35 /* first slot after the last parameter. */
35static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ 36static int CnResults = 0; /* when Lua calls C, has the number of parameters; */
36 /* when C calls Lua, has the number of results. */ 37 /* when C calls Lua, has the number of results. */
38
39static jmp_buf *errorJmp = NULL; /* current error recover point */
37 40
38static jmp_buf *errorJmp;
39 41
40static int lua_execute (Byte *pc, int base); 42static int lua_execute (Byte *pc, int base);
41 43
42 44
45static void lua_message (char *s)
46{
47 fprintf (stderr, "lua: %s\n", s);
48}
43 49
44/* 50/*
45** Reports an error, and jumps up to the available recover label 51** Reports an error, and jumps up to the available recover label
46*/ 52*/
47void lua_error (char *s) 53void lua_error (char *s)
48{ 54{
49 fprintf (stderr, "lua: %s\n", s); 55 lua_message(s);
50 if (errorJmp) 56 if (errorJmp)
51 longjmp(*errorJmp, 1); 57 longjmp(*errorJmp, 1);
52 else 58 else
59 {
60 fprintf (stderr, "lua: exit(1). Unable to recover\n");
53 exit(1); 61 exit(1);
62 }
54} 63}
55 64
56 65
@@ -73,7 +82,7 @@ static void lua_initstack (void)
73static void lua_checkstack (Word n) 82static void lua_checkstack (Word n)
74{ 83{
75 if (stack == NULL) 84 if (stack == NULL)
76 return lua_initstack(); 85 lua_initstack();
77 if (n > maxstack) 86 if (n > maxstack)
78 { 87 {
79 int t = top-stack; 88 int t = top-stack;
@@ -99,12 +108,6 @@ static char *lua_strconc (char *l, char *r)
99 return strcat(strcpy(buffer,l),r); 108 return strcat(strcpy(buffer,l),r);
100} 109}
101 110
102static int ToReal (char* s, float* f)
103{
104 char c;
105 float t;
106 if (sscanf(s,"%f %c",&t,&c) == 1) { *f=t; return 1; } else return 0;
107}
108 111
109/* 112/*
110** Convert, if possible, to a number object. 113** Convert, if possible, to a number object.
@@ -112,31 +115,18 @@ static int ToReal (char* s, float* f)
112*/ 115*/
113static int lua_tonumber (Object *obj) 116static int lua_tonumber (Object *obj)
114{ 117{
118 char c;
119 float t;
115 if (tag(obj) != LUA_T_STRING) 120 if (tag(obj) != LUA_T_STRING)
116 return 1;; 121 return 1;
117 if (!ToReal(svalue(obj), &nvalue(obj))) 122 else if (sscanf(svalue(obj), "%f %c",&t,&c) == 1)
118 return 2;
119 tag(obj) = LUA_T_NUMBER;
120 return 0;
121}
122
123/*
124** Test if it is possible to convert an object to a number object.
125** If possible, return the converted object, otherwise return nil object.
126*/
127static Object *lua_convtonumber (Object *obj)
128{
129 static Object cvt;
130 if (tag(obj) == LUA_T_NUMBER)
131 { 123 {
132 cvt = *obj; 124 nvalue(obj) = t;
133 return &cvt; 125 tag(obj) = LUA_T_NUMBER;
126 return 0;
134 } 127 }
135 if (tag(obj) == LUA_T_STRING && ToReal(svalue(obj), &nvalue(&cvt)))
136 tag(&cvt) = LUA_T_NUMBER;
137 else 128 else
138 tag(&cvt) = LUA_T_NIL; 129 return 2;
139 return &cvt;
140} 130}
141 131
142 132
@@ -182,7 +172,8 @@ static int callC (lua_CFunction func, int base)
182 int oldCnResults = CnResults; 172 int oldCnResults = CnResults;
183 int firstResult; 173 int firstResult;
184 CnResults = (top-stack) - base; 174 CnResults = (top-stack) - base;
185 CBase = base+CnResults; /* incorporate parameters on the stack */ 175 /* incorporate parameters on the stack */
176 CBase = base+CnResults;
186 (*func)(); 177 (*func)();
187 firstResult = CBase; 178 firstResult = CBase;
188 CBase = oldBase; 179 CBase = oldBase;
@@ -221,22 +212,17 @@ static void do_call (Object *func, int base, int nResults, int whereRes)
221 212
222 213
223/* 214/*
224** Function to index the values on the top 215** Function to index a table. Receives the table at top-2 and the index
216** at top-1. Remove them from stack and push the result.
225*/ 217*/
226int lua_pushsubscript (void) 218static void pushsubscript (void)
227{ 219{
228 --top; 220 Object *h;
229 if (tag(top-1) != LUA_T_ARRAY) 221 if (tag(top-2) != LUA_T_ARRAY)
230 { 222 lua_reportbug ("indexed expression not a table");
231 lua_reportbug ("indexed expression not a table"); 223 h = lua_hashget (avalue(top-2), top-1);
232 return 1; 224 --top;
233 }
234 {
235 Object *h = lua_hashget (avalue(top-1), top);
236 if (h == NULL) return 1;
237 *(top-1) = *h; 225 *(top-1) = *h;
238 }
239 return 0;
240} 226}
241 227
242 228
@@ -272,89 +258,89 @@ void lua_travstack (void (*fn)(Object *))
272 258
273 259
274/* 260/*
275** Executes a main procedure. Uses as Base the top of the stack, as it 261** Execute a protected call. If function is null compiles the pre-set input.
276** uses no parameters and left no results. 262** Leave nResults on the stack.
277*/ 263*/
278static void do_main (Byte *main) 264static int do_protectedrun (Object *function, int nResults)
279{
280 if (main)
281 {
282 Object f;
283 tag(&f) = LUA_T_FUNCTION; bvalue(&f) = main;
284 do_call(&f, top-stack, 0, top-stack);
285 free(main);
286 }
287}
288
289
290/*
291** Open file, generate opcode and execute global statement. Return 0 on
292** success or 1 on error.
293*/
294int lua_dofile (char *filename)
295{ 265{
266 Object f;
296 jmp_buf myErrorJmp; 267 jmp_buf myErrorJmp;
297 int status; 268 int status;
269 int oldCBase = CBase;
298 jmp_buf *oldErr = errorJmp; 270 jmp_buf *oldErr = errorJmp;
299 errorJmp = &myErrorJmp; 271 errorJmp = &myErrorJmp;
300 if (setjmp(myErrorJmp) == 0) 272 if (setjmp(myErrorJmp) == 0)
301 { 273 {
302 lua_openfile (filename); 274 if (function == NULL)
303 do_main(lua_parse()); 275 {
276 function = &f;
277 tag(function) = LUA_T_FUNCTION;
278 bvalue(function) = lua_parse();
279 }
280 do_call(function, CBase, nResults, CBase);
281 CnResults = (top-stack) - CBase; /* number of results */
282 CBase += CnResults; /* incorporate results on the stack */
304 status = 0; 283 status = 0;
305 } 284 }
306 else 285 else
286 {
287 CBase = oldCBase;
288 top = stack+CBase;
307 status = 1; 289 status = 1;
308 lua_closefile(); 290 }
309 errorJmp = oldErr; 291 errorJmp = oldErr;
310 return status; 292 return status;
311} 293}
312 294
313/* 295/*
314** Generate opcode stored on string and execute global statement. Return 0 on 296** Execute the given lua function. Return 0 on success or 1 on error.
297*/
298int lua_callfunction (Object *function)
299{
300 if (function == NULL)
301 return 1;
302 else
303 return do_protectedrun (function, MULT_RET);
304}
305
306
307/*
308** Open file, generate opcode and execute global statement. Return 0 on
315** success or 1 on error. 309** success or 1 on error.
316*/ 310*/
317int lua_dostring (char *string) 311int lua_dofile (char *filename)
318{ 312{
319 jmp_buf myErrorJmp;
320 int status; 313 int status;
321 jmp_buf *oldErr = errorJmp; 314 char *message = lua_openfile (filename);
322 errorJmp = &myErrorJmp; 315 if (message)
323 if (setjmp(myErrorJmp) == 0)
324 { 316 {
325 lua_openstring(string); 317 lua_message(message);
326 do_main(lua_parse()); 318 return 1;
327 status = 0;
328 } 319 }
329 else 320 status = do_protectedrun(NULL, 0);
330 status = 1; 321 lua_closefile();
331 lua_closestring();
332 errorJmp = oldErr;
333 return status; 322 return status;
334} 323}
335 324
336/* 325/*
337** Execute the given lua function. Return 0 on success or 1 on error. 326** Generate opcode stored on string and execute global statement. Return 0 on
327** success or 1 on error.
338*/ 328*/
339int lua_callfunction (Object *function) 329int lua_dostring (char *string)
340{ 330{
341 jmp_buf myErrorJmp;
342 int status; 331 int status;
343 jmp_buf *oldErr = errorJmp; 332 char *message = lua_openstring(string);
344 errorJmp = &myErrorJmp; 333 if (message)
345 if (setjmp(myErrorJmp) == 0)
346 { 334 {
347 do_call(function, CBase, MULT_RET, CBase); 335 lua_message(message);
348 CnResults = (top-stack) - CBase; /* number of results */ 336 return 1;
349 CBase += CnResults; /* incorporate results on the stack */
350 status = 0;
351 } 337 }
352 else 338 status = do_protectedrun(NULL, 0);
353 status = 1; 339 lua_closestring();
354 errorJmp = oldErr;
355 return status; 340 return status;
356} 341}
357 342
343
358/* 344/*
359** Get a parameter, returning the object handle or NULL on error. 345** Get a parameter, returning the object handle or NULL on error.
360** 'number' must be 1 to get the first parameter. 346** 'number' must be 1 to get the first parameter.
@@ -426,42 +412,6 @@ void *lua_gettable (Object *object)
426} 412}
427 413
428/* 414/*
429** Given an object handle and a field name, return its field object.
430** On error, return NULL.
431*/
432Object *lua_getfield (Object *object, char *field)
433{
434 if (object == NULL) return NULL;
435 if (tag(object) != LUA_T_ARRAY)
436 return NULL;
437 else
438 {
439 Object ref;
440 tag(&ref) = LUA_T_STRING;
441 svalue(&ref) = lua_constant[lua_findconstant(field)];
442 return (lua_hashget(avalue(object), &ref));
443 }
444}
445
446/*
447** Given an object handle and an index, return its indexed object.
448** On error, return NULL.
449*/
450Object *lua_getindexed (Object *object, float index)
451{
452 if (object == NULL) return NULL;
453 if (tag(object) != LUA_T_ARRAY)
454 return NULL;
455 else
456 {
457 Object ref;
458 tag(&ref) = LUA_T_NUMBER;
459 nvalue(&ref) = index;
460 return (lua_hashget(avalue(object), &ref));
461 }
462}
463
464/*
465** Get a global object. Return the object handle or NULL on error. 415** Get a global object. Return the object handle or NULL on error.
466*/ 416*/
467Object *lua_getglobal (char *name) 417Object *lua_getglobal (char *name)
@@ -550,7 +500,7 @@ int lua_storeglobal (char *name)
550{ 500{
551 int n = lua_findsymbol (name); 501 int n = lua_findsymbol (name);
552 if (n < 0) return 1; 502 if (n < 0) return 1;
553 if (tag(top-1) == LUA_T_MARK) return 1; 503 if (top-stack <= CBase) return 1;
554 s_object(n) = *(--top); 504 s_object(n) = *(--top);
555 return 0; 505 return 0;
556} 506}
@@ -598,74 +548,15 @@ int lua_storeindexed (lua_Object object, float index)
598} 548}
599 549
600 550
601/* 551int lua_type (lua_Object o)
602** Given an object handle, return if it is nil.
603*/
604int lua_isnil (Object *object)
605{ 552{
606 return (object != NULL && tag(object) == LUA_T_NIL); 553 if (o == NULL)
607} 554 return LUA_T_NIL;
608 555 else
609/* 556 return tag(o);
610** Given an object handle, return if it is a number one.
611*/
612int lua_isnumber (Object *object)
613{
614 return (object != NULL && tag(object) == LUA_T_NUMBER);
615}
616
617/*
618** Given an object handle, return if it is a string one.
619*/
620int lua_isstring (Object *object)
621{
622 return (object != NULL && tag(object) == LUA_T_STRING);
623}
624
625/*
626** Given an object handle, return if it is an array one.
627*/
628int lua_istable (Object *object)
629{
630 return (object != NULL && tag(object) == LUA_T_ARRAY);
631}
632
633/*
634** Given an object handle, return if it is a lua function.
635*/
636int lua_isfunction (Object *object)
637{
638 return (object != NULL && tag(object) == LUA_T_FUNCTION);
639}
640
641/*
642** Given an object handle, return if it is a cfunction one.
643*/
644int lua_iscfunction (Object *object)
645{
646 return (object != NULL && tag(object) == LUA_T_CFUNCTION);
647}
648
649/*
650** Given an object handle, return if it is an user data one.
651*/
652int lua_isuserdata (Object *object)
653{
654 return (object != NULL && tag(object) == LUA_T_USERDATA);
655}
656
657
658/*
659** Internal function: convert an object to a number
660*/
661void lua_obj2number (void)
662{
663 Object *o = lua_getparam(1);
664 lua_pushobject (lua_convtonumber(o));
665} 557}
666 558
667 559
668
669/* 560/*
670** Execute the given opcode, until a RET. Parameters are between 561** Execute the given opcode, until a RET. Parameters are between
671** [stack+base,top). Returns n such that the the results are between 562** [stack+base,top). Returns n such that the the results are between
@@ -674,8 +565,7 @@ void lua_obj2number (void)
674static int lua_execute (Byte *pc, int base) 565static int lua_execute (Byte *pc, int base)
675{ 566{
676 lua_debugline = 0; /* reset debug flag */ 567 lua_debugline = 0; /* reset debug flag */
677 if (stack == NULL) 568 lua_checkstack(STACKGAP+MAX_TEMPS+base);
678 lua_initstack();
679 while (1) 569 while (1)
680 { 570 {
681 OpCode opcode; 571 OpCode opcode;
@@ -737,16 +627,13 @@ static int lua_execute (Byte *pc, int base)
737 break; 627 break;
738 628
739 case PUSHINDEXED: 629 case PUSHINDEXED:
740 { 630 pushsubscript();
741 int s = lua_pushsubscript(); 631 break;
742 if (s == 1) return 1;
743 }
744 break;
745 632
746 case PUSHSELF: 633 case PUSHSELF:
747 { 634 {
748 Object receiver = *(top-2); 635 Object receiver = *(top-2);
749 if (lua_pushsubscript() == 1) return 1; 636 pushsubscript();
750 *(top++) = receiver; 637 *(top++) = receiver;
751 break; 638 break;
752 } 639 }
@@ -779,10 +666,7 @@ static int lua_execute (Byte *pc, int base)
779 { 666 {
780 int n = *pc++; 667 int n = *pc++;
781 if (tag(top-3-n) != LUA_T_ARRAY) 668 if (tag(top-3-n) != LUA_T_ARRAY)
782 { 669 lua_reportbug ("indexed expression not a table");
783 lua_reportbug ("indexed expression not a table");
784 return 1;
785 }
786 { 670 {
787 Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); 671 Object *h = lua_hashdefine (avalue(top-3-n), top-2-n);
788 if (h == NULL) return 1; 672 if (h == NULL) return 1;
@@ -802,10 +686,7 @@ static int lua_execute (Byte *pc, int base)
802 n = *(pc++); 686 n = *(pc++);
803 arr = top-n-1; 687 arr = top-n-1;
804 if (tag(arr) != LUA_T_ARRAY) 688 if (tag(arr) != LUA_T_ARRAY)
805 { 689 lua_reportbug ("internal error - table expected");
806 lua_reportbug ("internal error - table expected");
807 return 1;
808 }
809 while (n) 690 while (n)
810 { 691 {
811 tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; 692 tag(top) = LUA_T_NUMBER; nvalue(top) = n+m;
@@ -821,10 +702,7 @@ static int lua_execute (Byte *pc, int base)
821 int n = *(pc++); 702 int n = *(pc++);
822 Object *arr = top-n-1; 703 Object *arr = top-n-1;
823 if (tag(arr) != LUA_T_ARRAY) 704 if (tag(arr) != LUA_T_ARRAY)
824 { 705 lua_reportbug ("internal error - table expected");
825 lua_reportbug ("internal error - table expected");
826 return 1;
827 }
828 while (n) 706 while (n)
829 { 707 {
830 CodeWord code; 708 CodeWord code;
@@ -851,8 +729,6 @@ static int lua_execute (Byte *pc, int base)
851 get_word(size,pc); 729 get_word(size,pc);
852 top++; 730 top++;
853 avalue(top-1) = lua_createarray(size.w); 731 avalue(top-1) = lua_createarray(size.w);
854 if (avalue(top-1) == NULL)
855 return 1;
856 tag(top-1) = LUA_T_ARRAY; 732 tag(top-1) = LUA_T_ARRAY;
857 } 733 }
858 break; 734 break;
@@ -870,7 +746,7 @@ static int lua_execute (Byte *pc, int base)
870 switch (tag(l)) 746 switch (tag(l))
871 { 747 {
872 case LUA_T_NIL: 748 case LUA_T_NIL:
873 res = 0; break; 749 res = 1; break;
874 case LUA_T_NUMBER: 750 case LUA_T_NUMBER:
875 res = (nvalue(l) == nvalue(r)); break; 751 res = (nvalue(l) == nvalue(r)); break;
876 case LUA_T_ARRAY: 752 case LUA_T_ARRAY: