diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1996-09-20 09:51:16 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1996-09-20 09:51:16 -0300 |
commit | 82f9f3e552fe3adcf5b1e585f3c99fde4c21936a (patch) | |
tree | 53f84423773900da02361368f3801695f48c3bf1 | |
parent | c96ad1c9455b59ea3ff25660549b0e2ad222791e (diff) | |
download | lua-82f9f3e552fe3adcf5b1e585f3c99fde4c21936a.tar.gz lua-82f9f3e552fe3adcf5b1e585f3c99fde4c21936a.tar.bz2 lua-82f9f3e552fe3adcf5b1e585f3c99fde4c21936a.zip |
better structure to control stack interface lua-C.
beginblock-endblock keeps better control over stack
-rw-r--r-- | opcode.c | 108 |
1 files changed, 53 insertions, 55 deletions
@@ -3,7 +3,7 @@ | |||
3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
4 | */ | 4 | */ |
5 | 5 | ||
6 | char *rcs_opcode="$Id: opcode.c,v 3.72 1996/08/15 18:40:55 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.73 1996/09/02 21:57:51 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
9 | #include <stdio.h> | 9 | #include <stdio.h> |
@@ -50,10 +50,14 @@ static Object *top = &initial_stack; | |||
50 | */ | 50 | */ |
51 | #define incr_top if (++top >= stackLimit) growstack() | 51 | #define incr_top if (++top >= stackLimit) growstack() |
52 | 52 | ||
53 | static StkId CBase = 0; /* when Lua calls C or C calls Lua, points to */ | 53 | struct C_Lua_Stack { |
54 | /* the first slot after the last parameter. */ | 54 | StkId base; /* when Lua calls C or C calls Lua, points to */ |
55 | static int CnResults = 0; /* when Lua calls C, has the number of parameters; */ | 55 | /* the first slot after the last parameter. */ |
56 | /* when C calls Lua, has the number of results. */ | 56 | int num; /* when Lua calls C, has the number of parameters; */ |
57 | /* when C calls Lua, has the number of results. */ | ||
58 | }; | ||
59 | |||
60 | static struct C_Lua_Stack CLS_current = {0, 0}; | ||
57 | 61 | ||
58 | static jmp_buf *errorJmp = NULL; /* current error recover point */ | 62 | static jmp_buf *errorJmp = NULL; /* current error recover point */ |
59 | 63 | ||
@@ -178,7 +182,7 @@ static void adjust_top (StkId newtop) | |||
178 | top = nt; /* top could be bigger than newtop */ | 182 | top = nt; /* top could be bigger than newtop */ |
179 | } | 183 | } |
180 | 184 | ||
181 | #define adjustC(nParams) adjust_top(CBase+nParams) | 185 | #define adjustC(nParams) adjust_top(CLS_current.base+nParams) |
182 | 186 | ||
183 | 187 | ||
184 | /* | 188 | /* |
@@ -198,14 +202,12 @@ static void open_stack (int nelems) | |||
198 | */ | 202 | */ |
199 | static void lineHook (int line) | 203 | static void lineHook (int line) |
200 | { | 204 | { |
201 | StkId oldBase = CBase; | 205 | struct C_Lua_Stack oldCLS = CLS_current; |
202 | int oldCnResults = CnResults; | 206 | StkId old_top = CLS_current.base = top-stack; |
203 | StkId old_top = CBase = top-stack; | 207 | CLS_current.num = 0; |
204 | CnResults = 0; | ||
205 | (*lua_linehook)(line); | 208 | (*lua_linehook)(line); |
206 | top = stack+old_top; | 209 | top = stack+old_top; |
207 | CnResults = oldCnResults; | 210 | CLS_current = oldCLS; |
208 | CBase = oldBase; | ||
209 | } | 211 | } |
210 | 212 | ||
211 | 213 | ||
@@ -215,10 +217,9 @@ static void lineHook (int line) | |||
215 | */ | 217 | */ |
216 | static void callHook (StkId base, lua_Type type, int isreturn) | 218 | static void callHook (StkId base, lua_Type type, int isreturn) |
217 | { | 219 | { |
218 | StkId oldBase = CBase; | 220 | struct C_Lua_Stack oldCLS = CLS_current; |
219 | int oldCnResults = CnResults; | 221 | StkId old_top = CLS_current.base = top-stack; |
220 | StkId old_top = CBase = top-stack; | 222 | CLS_current.num = 0; |
221 | CnResults = 0; | ||
222 | if (isreturn) | 223 | if (isreturn) |
223 | (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); | 224 | (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); |
224 | else | 225 | else |
@@ -230,32 +231,29 @@ static void callHook (StkId base, lua_Type type, int isreturn) | |||
230 | (*lua_callhook)(Ref(f), "(C)", -1); | 231 | (*lua_callhook)(Ref(f), "(C)", -1); |
231 | } | 232 | } |
232 | top = stack+old_top; | 233 | top = stack+old_top; |
233 | CnResults = oldCnResults; | 234 | CLS_current = oldCLS; |
234 | CBase = oldBase; | ||
235 | } | 235 | } |
236 | 236 | ||
237 | 237 | ||
238 | /* | 238 | /* |
239 | ** Call a C function. CBase will point to the top of the stack, | 239 | ** Call a C function. CLS_current.base will point to the top of the stack, |
240 | ** and CnResults is the number of parameters. Returns an index | 240 | ** and CLS_current.num is the number of parameters. Returns an index |
241 | ** to the first result from C. | 241 | ** to the first result from C. |
242 | */ | 242 | */ |
243 | static StkId callC (lua_CFunction func, StkId base) | 243 | static StkId callC (lua_CFunction func, StkId base) |
244 | { | 244 | { |
245 | StkId oldBase = CBase; | 245 | struct C_Lua_Stack oldCLS = CLS_current; |
246 | int oldCnResults = CnResults; | ||
247 | StkId firstResult; | 246 | StkId firstResult; |
248 | CnResults = (top-stack) - base; | 247 | CLS_current.num = (top-stack) - base; |
249 | /* incorporate parameters on the stack */ | 248 | /* incorporate parameters on the stack */ |
250 | CBase = base+CnResults; /* == top-stack */ | 249 | CLS_current.base = base+CLS_current.num; /* == top-stack */ |
251 | if (lua_callhook) | 250 | if (lua_callhook) |
252 | callHook(base, LUA_T_CMARK, 0); | 251 | callHook(base, LUA_T_CMARK, 0); |
253 | (*func)(); | 252 | (*func)(); |
254 | if (lua_callhook) /* func may have changed lua_callhook */ | 253 | if (lua_callhook) /* func may have changed lua_callhook */ |
255 | callHook(base, LUA_T_CMARK, 1); | 254 | callHook(base, LUA_T_CMARK, 1); |
256 | firstResult = CBase; | 255 | firstResult = CLS_current.base; |
257 | CBase = oldBase; | 256 | CLS_current = oldCLS; |
258 | CnResults = oldCnResults; | ||
259 | return firstResult; | 257 | return firstResult; |
260 | } | 258 | } |
261 | 259 | ||
@@ -450,27 +448,27 @@ int lua_setlocal (lua_Function func, int local_number) | |||
450 | 448 | ||
451 | 449 | ||
452 | /* | 450 | /* |
453 | ** Execute a protected call. Assumes that function is at CBase and | 451 | ** Execute a protected call. Assumes that function is at CLS_current.base and |
454 | ** parameters are on top of it. Leave nResults on the stack. | 452 | ** parameters are on top of it. Leave nResults on the stack. |
455 | */ | 453 | */ |
456 | static int do_protectedrun (int nResults) | 454 | static int do_protectedrun (int nResults) |
457 | { | 455 | { |
458 | jmp_buf myErrorJmp; | 456 | jmp_buf myErrorJmp; |
459 | int status; | 457 | int status; |
460 | StkId oldCBase = CBase; | 458 | struct C_Lua_Stack oldCLS = CLS_current; |
461 | jmp_buf *oldErr = errorJmp; | 459 | jmp_buf *oldErr = errorJmp; |
462 | errorJmp = &myErrorJmp; | 460 | errorJmp = &myErrorJmp; |
463 | if (setjmp(myErrorJmp) == 0) | 461 | if (setjmp(myErrorJmp) == 0) |
464 | { | 462 | { |
465 | do_call(CBase+1, nResults); | 463 | do_call(CLS_current.base+1, nResults); |
466 | CnResults = (top-stack) - CBase; /* number of results */ | 464 | CLS_current.num = (top-stack) - CLS_current.base; /* number of results */ |
467 | CBase += CnResults; /* incorporate results on the stack */ | 465 | CLS_current.base += CLS_current.num; /* incorporate results on the stack */ |
468 | status = 0; | 466 | status = 0; |
469 | } | 467 | } |
470 | else | 468 | else |
471 | { /* an error occurred: restore CBase and top */ | 469 | { /* an error occurred: restore CLS_current and top */ |
472 | CBase = oldCBase; | 470 | CLS_current = oldCLS; |
473 | top = stack+CBase; | 471 | top = stack+CLS_current.base; |
474 | status = 1; | 472 | status = 1; |
475 | } | 473 | } |
476 | errorJmp = oldErr; | 474 | errorJmp = oldErr; |
@@ -481,8 +479,8 @@ int luaI_dorun (TFunc *tf) | |||
481 | { | 479 | { |
482 | int status; | 480 | int status; |
483 | adjustC(1); /* one slot for the pseudo-function */ | 481 | adjustC(1); /* one slot for the pseudo-function */ |
484 | stack[CBase].tag = LUA_T_FUNCTION; | 482 | stack[CLS_current.base].tag = LUA_T_FUNCTION; |
485 | stack[CBase].value.tf = tf; | 483 | stack[CLS_current.base].value.tf = tf; |
486 | status = do_protectedrun(0); | 484 | status = do_protectedrun(0); |
487 | adjustC(0); | 485 | adjustC(0); |
488 | return status; | 486 | return status; |
@@ -522,8 +520,8 @@ int lua_callfunction (lua_Object function) | |||
522 | return 1; | 520 | return 1; |
523 | else | 521 | else |
524 | { | 522 | { |
525 | open_stack((top-stack)-CBase); | 523 | open_stack((top-stack)-CLS_current.base); |
526 | stack[CBase] = *Address(function); | 524 | stack[CLS_current.base] = *Address(function); |
527 | return do_protectedrun (MULT_RET); | 525 | return do_protectedrun (MULT_RET); |
528 | } | 526 | } |
529 | } | 527 | } |
@@ -532,8 +530,8 @@ int lua_callfunction (lua_Object function) | |||
532 | int lua_call (char *funcname) | 530 | int lua_call (char *funcname) |
533 | { | 531 | { |
534 | Word n = luaI_findsymbolbyname(funcname); | 532 | Word n = luaI_findsymbolbyname(funcname); |
535 | open_stack((top-stack)-CBase); | 533 | open_stack((top-stack)-CLS_current.base); |
536 | stack[CBase] = s_object(n); | 534 | stack[CLS_current.base] = s_object(n); |
537 | return do_protectedrun(MULT_RET); | 535 | return do_protectedrun(MULT_RET); |
538 | } | 536 | } |
539 | 537 | ||
@@ -584,8 +582,8 @@ int lua_dostring (char *str) | |||
584 | lua_Object lua_setfallback (char *name, lua_CFunction fallback) | 582 | lua_Object lua_setfallback (char *name, lua_CFunction fallback) |
585 | { | 583 | { |
586 | adjustC(1); /* one slot for the pseudo-function */ | 584 | adjustC(1); /* one slot for the pseudo-function */ |
587 | stack[CBase].tag = LUA_T_CFUNCTION; | 585 | stack[CLS_current.base].tag = LUA_T_CFUNCTION; |
588 | stack[CBase].value.f = luaI_setfallback; | 586 | stack[CLS_current.base].value.f = luaI_setfallback; |
589 | lua_pushstring(name); | 587 | lua_pushstring(name); |
590 | lua_pushcfunction(fallback); | 588 | lua_pushcfunction(fallback); |
591 | if (do_protectedrun(1) == 0) | 589 | if (do_protectedrun(1) == 0) |
@@ -603,7 +601,7 @@ lua_Object lua_getsubscript (void) | |||
603 | { | 601 | { |
604 | adjustC(2); | 602 | adjustC(2); |
605 | pushsubscript(); | 603 | pushsubscript(); |
606 | CBase++; /* incorporate object in the stack */ | 604 | CLS_current.base++; /* incorporate object in the stack */ |
607 | return (Ref(top-1)); | 605 | return (Ref(top-1)); |
608 | } | 606 | } |
609 | 607 | ||
@@ -611,7 +609,7 @@ lua_Object lua_getsubscript (void) | |||
611 | #define MAX_C_BLOCKS 10 | 609 | #define MAX_C_BLOCKS 10 |
612 | 610 | ||
613 | static int numCblocks = 0; | 611 | static int numCblocks = 0; |
614 | static StkId Cblocks[MAX_C_BLOCKS]; | 612 | static struct C_Lua_Stack Cblocks[MAX_C_BLOCKS]; |
615 | 613 | ||
616 | /* | 614 | /* |
617 | ** API: starts a new block | 615 | ** API: starts a new block |
@@ -620,7 +618,7 @@ void lua_beginblock (void) | |||
620 | { | 618 | { |
621 | if (numCblocks >= MAX_C_BLOCKS) | 619 | if (numCblocks >= MAX_C_BLOCKS) |
622 | lua_error("`lua_beginblock': too many nested blocks"); | 620 | lua_error("`lua_beginblock': too many nested blocks"); |
623 | Cblocks[numCblocks] = CBase; | 621 | Cblocks[numCblocks] = CLS_current; |
624 | numCblocks++; | 622 | numCblocks++; |
625 | } | 623 | } |
626 | 624 | ||
@@ -630,7 +628,7 @@ void lua_beginblock (void) | |||
630 | void lua_endblock (void) | 628 | void lua_endblock (void) |
631 | { | 629 | { |
632 | --numCblocks; | 630 | --numCblocks; |
633 | CBase = Cblocks[numCblocks]; | 631 | CLS_current = Cblocks[numCblocks]; |
634 | adjustC(0); | 632 | adjustC(0); |
635 | } | 633 | } |
636 | 634 | ||
@@ -652,7 +650,7 @@ lua_Object lua_createtable (void) | |||
652 | avalue(top) = lua_createarray(0); | 650 | avalue(top) = lua_createarray(0); |
653 | tag(top) = LUA_T_ARRAY; | 651 | tag(top) = LUA_T_ARRAY; |
654 | incr_top; | 652 | incr_top; |
655 | CBase++; /* incorporate object in the stack */ | 653 | CLS_current.base++; /* incorporate object in the stack */ |
656 | return Ref(top-1); | 654 | return Ref(top-1); |
657 | } | 655 | } |
658 | 656 | ||
@@ -662,10 +660,10 @@ lua_Object lua_createtable (void) | |||
662 | */ | 660 | */ |
663 | lua_Object lua_getparam (int number) | 661 | lua_Object lua_getparam (int number) |
664 | { | 662 | { |
665 | if (number <= 0 || number > CnResults) return LUA_NOOBJECT; | 663 | if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT; |
666 | /* Ref(stack+(CBase-CnResults+number-1)) == | 664 | /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) == |
667 | stack+(CBase-CnResults+number-1)-stack+1 == */ | 665 | stack+(CLS_current.base-CLS_current.num+number-1)-stack+1 == */ |
668 | return CBase-CnResults+number; | 666 | return CLS_current.base-CLS_current.num+number; |
669 | } | 667 | } |
670 | 668 | ||
671 | int lua_isnumber (lua_Object object) | 669 | int lua_isnumber (lua_Object object) |
@@ -735,7 +733,7 @@ lua_Object lua_getref (int ref) | |||
735 | return LUA_NOOBJECT; | 733 | return LUA_NOOBJECT; |
736 | adjustC(0); | 734 | adjustC(0); |
737 | luaI_pushobject(o); | 735 | luaI_pushobject(o); |
738 | CBase++; /* incorporate object in the stack */ | 736 | CLS_current.base++; /* incorporate object in the stack */ |
739 | return Ref(top-1); | 737 | return Ref(top-1); |
740 | } | 738 | } |
741 | 739 | ||
@@ -764,7 +762,7 @@ lua_Object lua_getglobal (char *name) | |||
764 | { | 762 | { |
765 | adjustC(0); | 763 | adjustC(0); |
766 | getglobal(luaI_findsymbolbyname(name)); | 764 | getglobal(luaI_findsymbolbyname(name)); |
767 | CBase++; /* incorporate object in the stack */ | 765 | CLS_current.base++; /* incorporate object in the stack */ |
768 | return Ref(top-1); | 766 | return Ref(top-1); |
769 | } | 767 | } |
770 | 768 | ||