aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opcode.c176
1 files changed, 101 insertions, 75 deletions
diff --git a/opcode.c b/opcode.c
index 78fabf25..1fb831c7 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 3.38 1995/05/16 17:23:58 roberto Exp $"; 6char *rcs_opcode="$Id: opcode.c,v 3.40 1995/10/04 14:20:26 roberto Exp roberto $";
7 7
8#include <setjmp.h> 8#include <setjmp.h>
9#include <stdlib.h> 9#include <stdlib.h>
@@ -54,7 +54,7 @@ static jmp_buf *errorJmp = NULL; /* current error recover point */
54 54
55 55
56static StkId lua_execute (Byte *pc, StkId base); 56static StkId lua_execute (Byte *pc, StkId base);
57static void do_call (Object *func, StkId base, int nResults, StkId whereRes); 57static void do_call (StkId base, int nResults);
58 58
59 59
60 60
@@ -64,32 +64,6 @@ Object *luaI_Address (lua_Object o)
64} 64}
65 65
66 66
67/*
68** Error messages
69*/
70
71
72static void lua_message (char *s)
73{
74 luaI_reportbug(s, 1);
75 do_call(&luaI_fallBacks[FB_ERROR].function, (top-stack)-1, 0, (top-stack)-1);
76}
77
78/*
79** Reports an error, and jumps up to the available recover label
80*/
81void lua_error (char *s)
82{
83 if (s) lua_message(s);
84 if (errorJmp)
85 longjmp(*errorJmp, 1);
86 else
87 {
88 fprintf (stderr, "lua: exit(1). Unable to recover\n");
89 exit(1);
90 }
91}
92
93 67
94/* 68/*
95** Init stack 69** Init stack
@@ -211,6 +185,17 @@ static void adjustC (int nParams)
211 adjust_top(CBase+nParams); 185 adjust_top(CBase+nParams);
212} 186}
213 187
188/*
189** Open a hole below "nelems" from the top.
190*/
191static void open_stack (int nelems)
192{
193 int i;
194 for (i=0; i<nelems; i++)
195 *(top-i) = *(top-i-1);
196 incr_top;
197}
198
214 199
215/* 200/*
216** Call a C function. CBase will point to the top of the stack, 201** Call a C function. CBase will point to the top of the stack,
@@ -233,49 +218,58 @@ static StkId callC (lua_CFunction func, StkId base)
233} 218}
234 219
235/* 220/*
221** Call the specified fallback, putting it on the stack below its arguments
222*/
223static void callFB (int fb)
224{
225 int nParams = luaI_fallBacks[fb].nParams;
226 open_stack(nParams);
227 *(top-nParams-1) = luaI_fallBacks[fb].function;
228 do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults);
229}
230
231/*
236** Call the fallback for invalid functions (see do_call) 232** Call the fallback for invalid functions (see do_call)
237*/ 233*/
238static void call_funcFB (Object *func, StkId base, int nResults, StkId whereRes) 234static void call_funcFB (StkId base, int nResults)
239{ 235{
240 StkId i; 236 open_stack((top-stack)-(base-1));
241 /* open space for first parameter (func) */ 237 stack[base-1] = luaI_fallBacks[FB_FUNCTION].function;
242 for (i=top-stack; i>base; i--) 238 do_call(base, nResults);
243 stack[i] = stack[i-1];
244 incr_top;
245 stack[base] = *func;
246 do_call(&luaI_fallBacks[FB_FUNCTION].function, base, nResults, whereRes);
247} 239}
248 240
249 241
250/* 242/*
251** Call a function (C or Lua). The parameters must be on the stack, 243** Call a function (C or Lua). The parameters must be on the stack,
252** between [stack+base,top). When returns, the results are on the stack, 244** between [stack+base,top). The function to be called is at stack+base-1.
253** between [stack+whereRes,top). The number of results is nResults, unless 245** When returns, the results are on the stack, between [stack+base-1,top).
254** nResults=MULT_RET. 246** The number of results is nResults, unless nResults=MULT_RET.
255*/ 247*/
256static void do_call (Object *func, StkId base, int nResults, StkId whereRes) 248static void do_call (StkId base, int nResults)
257{ 249{
258 StkId firstResult; 250 StkId firstResult;
251 Object *func = stack+base-1;
259 if (tag(func) == LUA_T_CFUNCTION) 252 if (tag(func) == LUA_T_CFUNCTION)
260 firstResult = callC(fvalue(func), base); 253 firstResult = callC(fvalue(func), base);
261 else if (tag(func) == LUA_T_FUNCTION) 254 else if (tag(func) == LUA_T_FUNCTION)
262 firstResult = lua_execute(func->value.tf->code, base); 255 firstResult = lua_execute(func->value.tf->code, base);
263 else 256 else
264 { /* func is not a function */ 257 { /* func is not a function */
265 call_funcFB(func, base, nResults, whereRes); 258 call_funcFB(base, nResults);
266 return; 259 return;
267 } 260 }
268 /* adjust the number of results */ 261 /* adjust the number of results */
269 if (nResults != MULT_RET && top - (stack+firstResult) != nResults) 262 if (nResults != MULT_RET && top - (stack+firstResult) != nResults)
270 adjust_top(firstResult+nResults); 263 adjust_top(firstResult+nResults);
271 /* move results to the given position */ 264 /* move results to base-1 (to erase parameters and function) */
272 if (firstResult != whereRes) 265 base--;
266 if (firstResult != base)
273 { 267 {
274 int i; 268 int i;
275 nResults = top - (stack+firstResult); /* actual number of results */ 269 nResults = top - (stack+firstResult); /* actual number of results */
276 for (i=0; i<nResults; i++) 270 for (i=0; i<nResults; i++)
277 *(stack+whereRes+i) = *(stack+firstResult+i); 271 *(stack+base+i) = *(stack+firstResult+i);
278 top -= firstResult-whereRes; 272 top -= firstResult-base;
279 } 273 }
280} 274}
281 275
@@ -287,12 +281,12 @@ static void do_call (Object *func, StkId base, int nResults, StkId whereRes)
287static void pushsubscript (void) 281static void pushsubscript (void)
288{ 282{
289 if (tag(top-2) != LUA_T_ARRAY) 283 if (tag(top-2) != LUA_T_ARRAY)
290 do_call(&luaI_fallBacks[FB_GETTABLE].function, (top-stack)-2, 1, (top-stack)-2); 284 callFB(FB_GETTABLE);
291 else 285 else
292 { 286 {
293 Object *h = lua_hashget(avalue(top-2), top-1); 287 Object *h = lua_hashget(avalue(top-2), top-1);
294 if (h == NULL || tag(h) == LUA_T_NIL) 288 if (h == NULL || tag(h) == LUA_T_NIL)
295 do_call(&luaI_fallBacks[FB_INDEX].function, (top-stack)-2, 1, (top-stack)-2); 289 callFB(FB_INDEX);
296 else 290 else
297 { 291 {
298 --top; 292 --top;
@@ -308,7 +302,7 @@ static void pushsubscript (void)
308static void storesubscript (void) 302static void storesubscript (void)
309{ 303{
310 if (tag(top-3) != LUA_T_ARRAY) 304 if (tag(top-3) != LUA_T_ARRAY)
311 do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); 305 callFB(FB_SETTABLE);
312 else 306 else
313 { 307 {
314 Object *h = lua_hashdefine (avalue(top-3), top-2); 308 Object *h = lua_hashdefine (avalue(top-3), top-2);
@@ -330,10 +324,36 @@ void lua_travstack (void (*fn)(Object *))
330 324
331 325
332/* 326/*
333** Execute a protected call. If function is null compiles the pre-set input. 327** Error messages
334** Leave nResults on the stack. 328*/
329
330static void lua_message (char *s)
331{
332 luaI_reportbug(s, 1);
333 callFB(FB_ERROR);
334}
335
336/*
337** Reports an error, and jumps up to the available recover label
338*/
339void lua_error (char *s)
340{
341 if (s) lua_message(s);
342 if (errorJmp)
343 longjmp(*errorJmp, 1);
344 else
345 {
346 fprintf (stderr, "lua: exit(1). Unable to recover\n");
347 exit(1);
348 }
349}
350
351
352/*
353** Execute a protected call. Assumes that function is at CBase and
354** parameters are on top of it. Leave nResults on the stack.
335*/ 355*/
336static int do_protectedrun (Object *function, int nResults) 356static int do_protectedrun (int nResults)
337{ 357{
338 jmp_buf myErrorJmp; 358 jmp_buf myErrorJmp;
339 int status; 359 int status;
@@ -342,13 +362,13 @@ static int do_protectedrun (Object *function, int nResults)
342 errorJmp = &myErrorJmp; 362 errorJmp = &myErrorJmp;
343 if (setjmp(myErrorJmp) == 0) 363 if (setjmp(myErrorJmp) == 0)
344 { 364 {
345 do_call(function, CBase, nResults, CBase); 365 do_call(CBase+1, nResults);
346 CnResults = (top-stack) - CBase; /* number of results */ 366 CnResults = (top-stack) - CBase; /* number of results */
347 CBase += CnResults; /* incorporate results on the stack */ 367 CBase += CnResults; /* incorporate results on the stack */
348 status = 0; 368 status = 0;
349 } 369 }
350 else 370 else
351 { 371 { /* an error occurred: restore CBase and top */
352 CBase = oldCBase; 372 CBase = oldCBase;
353 top = stack+CBase; 373 top = stack+CBase;
354 status = 1; 374 status = 1;
@@ -362,27 +382,26 @@ static int do_protectedmain (void)
362{ 382{
363 TFunc tf; 383 TFunc tf;
364 int status; 384 int status;
365 StkId oldCBase = CBase;
366 jmp_buf myErrorJmp; 385 jmp_buf myErrorJmp;
367 jmp_buf *oldErr = errorJmp; 386 jmp_buf *oldErr = errorJmp;
368 errorJmp = &myErrorJmp; 387 errorJmp = &myErrorJmp;
388 adjustC(1); /* one slot for the pseudo-function */
389 stack[CBase].tag = LUA_T_FUNCTION;
390 stack[CBase].value.tf = &tf;
369 tf.code = NULL; 391 tf.code = NULL;
370 if (setjmp(myErrorJmp) == 0) 392 if (setjmp(myErrorJmp) == 0)
371 { 393 {
372 Object f;
373 f.tag = LUA_T_FUNCTION;
374 f.value.tf = &tf;
375 lua_parse(&tf); 394 lua_parse(&tf);
376 do_call(&f, CBase, 0, CBase); 395 status = do_protectedrun(0);
377 status = 0;
378 } 396 }
379 else 397 else
398 {
380 status = 1; 399 status = 1;
400 adjustC(0); /* erase extra slot */
401 }
402 errorJmp = oldErr;
381 if (tf.code) 403 if (tf.code)
382 luaI_free(tf.code); 404 luaI_free(tf.code);
383 errorJmp = oldErr;
384 CBase = oldCBase;
385 top = stack+CBase;
386 return status; 405 return status;
387} 406}
388 407
@@ -395,14 +414,20 @@ int lua_callfunction (lua_Object function)
395 if (function == LUA_NOOBJECT) 414 if (function == LUA_NOOBJECT)
396 return 1; 415 return 1;
397 else 416 else
398 return do_protectedrun (Address(function), MULT_RET); 417 {
418 open_stack((top-stack)-CBase);
419 stack[CBase] = *Address(function);
420 return do_protectedrun (MULT_RET);
421 }
399} 422}
400 423
401 424
402int lua_call (char *funcname) 425int lua_call (char *funcname)
403{ 426{
404 Word n = luaI_findsymbolbyname(funcname); 427 Word n = luaI_findsymbolbyname(funcname);
405 return do_protectedrun(&s_object(n), MULT_RET); 428 open_stack((top-stack)-CBase);
429 stack[CBase] = s_object(n);
430 return do_protectedrun(MULT_RET);
406} 431}
407 432
408 433
@@ -448,11 +473,12 @@ int lua_dostring (char *string)
448*/ 473*/
449lua_Object lua_setfallback (char *name, lua_CFunction fallback) 474lua_Object lua_setfallback (char *name, lua_CFunction fallback)
450{ 475{
451 static Object func = {LUA_T_CFUNCTION, {luaI_setfallback}}; 476 adjustC(1); /* one slot for the pseudo-function */
452 adjustC(0); 477 stack[CBase].tag = LUA_T_CFUNCTION;
478 stack[CBase].value.f = luaI_setfallback;
453 lua_pushstring(name); 479 lua_pushstring(name);
454 lua_pushcfunction(fallback); 480 lua_pushcfunction(fallback);
455 do_protectedrun(&func, 1); 481 do_protectedrun(1);
456 return (Ref(top-1)); 482 return (Ref(top-1));
457} 483}
458 484
@@ -597,8 +623,9 @@ int lua_lock (void)
597} 623}
598 624
599 625
626
600/* 627/*
601** Get a global object. Return the object handle or NULL on error. 628** Get a global object.
602*/ 629*/
603lua_Object lua_getglobal (char *name) 630lua_Object lua_getglobal (char *name)
604{ 631{
@@ -708,14 +735,14 @@ void luaI_gcFB (Object *o)
708{ 735{
709 *top = *o; 736 *top = *o;
710 incr_top; 737 incr_top;
711 do_call(&luaI_fallBacks[FB_GC].function, (top-stack)-1, 0, (top-stack)-1); 738 callFB(FB_GC);
712} 739}
713 740
714 741
715static void call_arith (char *op) 742static void call_arith (char *op)
716{ 743{
717 lua_pushstring(op); 744 lua_pushstring(op);
718 do_call(&luaI_fallBacks[FB_ARITH].function, (top-stack)-3, 1, (top-stack)-3); 745 callFB(FB_ARITH);
719} 746}
720 747
721static void comparison (lua_Type tag_less, lua_Type tag_equal, 748static void comparison (lua_Type tag_less, lua_Type tag_equal,
@@ -729,7 +756,7 @@ static void comparison (lua_Type tag_less, lua_Type tag_equal,
729 else if (tostring(l) || tostring(r)) 756 else if (tostring(l) || tostring(r))
730 { 757 {
731 lua_pushstring(op); 758 lua_pushstring(op);
732 do_call(&luaI_fallBacks[FB_ORDER].function, (top-stack)-3, 1, (top-stack)-3); 759 callFB(FB_ORDER);
733 return; 760 return;
734 } 761 }
735 else 762 else
@@ -867,7 +894,7 @@ static StkId lua_execute (Byte *pc, StkId base)
867 *(top) = *(top-2-n); 894 *(top) = *(top-2-n);
868 *(top-1) = *(top-3-n); 895 *(top-1) = *(top-3-n);
869 top += 2; 896 top += 2;
870 do_call(&luaI_fallBacks[FB_SETTABLE].function, (top-stack)-3, 0, (top-stack)-3); 897 callFB(FB_SETTABLE);
871 } 898 }
872 else 899 else
873 { 900 {
@@ -1021,7 +1048,7 @@ static StkId lua_execute (Byte *pc, StkId base)
1021 Object *l = top-2; 1048 Object *l = top-2;
1022 Object *r = top-1; 1049 Object *r = top-1;
1023 if (tostring(r) || tostring(l)) 1050 if (tostring(r) || tostring(l))
1024 do_call(&luaI_fallBacks[FB_CONCAT].function, (top-stack)-2, 1, (top-stack)-2); 1051 callFB(FB_CONCAT);
1025 else 1052 else
1026 { 1053 {
1027 tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); 1054 tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r)));
@@ -1102,9 +1129,8 @@ static StkId lua_execute (Byte *pc, StkId base)
1102 { 1129 {
1103 int nParams = *(pc++); 1130 int nParams = *(pc++);
1104 int nResults = *(pc++); 1131 int nResults = *(pc++);
1105 Object *func = top-1-nParams; /* function is below parameters */
1106 StkId newBase = (top-stack)-nParams; 1132 StkId newBase = (top-stack)-nParams;
1107 do_call(func, newBase, nResults, newBase-1); 1133 do_call(newBase, nResults);
1108 } 1134 }
1109 break; 1135 break;
1110 1136