diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-07 16:13:49 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-07 16:13:49 -0200 |
| commit | 7178a5e34aa56c09a01a6664bb7a61c6771700d4 (patch) | |
| tree | 318a1dd14cd5a0497229183e56e29198b3b2016c | |
| parent | 322b7b5fc55da0d166efc693cfe674220190b010 (diff) | |
| download | lua-7178a5e34aa56c09a01a6664bb7a61c6771700d4.tar.gz lua-7178a5e34aa56c09a01a6664bb7a61c6771700d4.tar.bz2 lua-7178a5e34aa56c09a01a6664bb7a61c6771700d4.zip | |
new way to handle top x L->top
| -rw-r--r-- | lapi.c | 10 | ||||
| -rw-r--r-- | lcode.c | 39 | ||||
| -rw-r--r-- | ldebug.c | 18 | ||||
| -rw-r--r-- | ldebug.h | 4 | ||||
| -rw-r--r-- | ldo.c | 11 | ||||
| -rw-r--r-- | ldo.h | 3 | ||||
| -rw-r--r-- | lgc.c | 9 | ||||
| -rw-r--r-- | lvm.c | 227 | ||||
| -rw-r--r-- | lvm.h | 12 |
9 files changed, 153 insertions, 180 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 1.124 2001/02/01 16:03:38 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.125 2001/02/02 15:13:05 roberto Exp roberto $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -208,7 +208,7 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) { | |||
| 208 | o1 = luaA_indexAcceptable(L, index1); | 208 | o1 = luaA_indexAcceptable(L, index1); |
| 209 | o2 = luaA_indexAcceptable(L, index2); | 209 | o2 = luaA_indexAcceptable(L, index2); |
| 210 | i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ | 210 | i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */ |
| 211 | : luaV_lessthan(L, o1, o2, L->top); | 211 | : luaV_lessthan(L, o1, o2); |
| 212 | LUA_UNLOCK(L); | 212 | LUA_UNLOCK(L); |
| 213 | return i; | 213 | return i; |
| 214 | } | 214 | } |
| @@ -364,7 +364,7 @@ LUA_API void lua_gettable (lua_State *L, int index) { | |||
| 364 | StkId t; | 364 | StkId t; |
| 365 | LUA_LOCK(L); | 365 | LUA_LOCK(L); |
| 366 | t = Index(L, index); | 366 | t = Index(L, index); |
| 367 | luaV_gettable(L, t, L->top, L->top-1); | 367 | luaV_gettable(L, t, L->top-1, L->top-1); |
| 368 | LUA_UNLOCK(L); | 368 | LUA_UNLOCK(L); |
| 369 | } | 369 | } |
| 370 | 370 | ||
| @@ -433,7 +433,7 @@ LUA_API void lua_newtable (lua_State *L) { | |||
| 433 | 433 | ||
| 434 | LUA_API void lua_setglobal (lua_State *L, const char *name) { | 434 | LUA_API void lua_setglobal (lua_State *L, const char *name) { |
| 435 | LUA_LOCK(L); | 435 | LUA_LOCK(L); |
| 436 | luaV_setglobal(L, luaS_new(L, name), L->top); | 436 | luaV_setglobal(L, luaS_new(L, name), L->top - 1); |
| 437 | L->top--; /* remove element from the top */ | 437 | L->top--; /* remove element from the top */ |
| 438 | LUA_UNLOCK(L); | 438 | LUA_UNLOCK(L); |
| 439 | } | 439 | } |
| @@ -443,7 +443,7 @@ LUA_API void lua_settable (lua_State *L, int index) { | |||
| 443 | StkId t; | 443 | StkId t; |
| 444 | LUA_LOCK(L); | 444 | LUA_LOCK(L); |
| 445 | t = Index(L, index); | 445 | t = Index(L, index); |
| 446 | luaV_settable(L, t, L->top - 2, L->top); | 446 | luaV_settable(L, t, L->top - 2, L->top - 1); |
| 447 | L->top -= 2; /* pop index and value */ | 447 | L->top -= 2; /* pop index and value */ |
| 448 | LUA_UNLOCK(L); | 448 | LUA_UNLOCK(L); |
| 449 | } | 449 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 1.58 2001/01/29 13:14:49 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.59 2001/01/29 15:26:40 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -460,25 +460,26 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) { | |||
| 460 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | 460 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { |
| 461 | Proto *f; | 461 | Proto *f; |
| 462 | Instruction i = previous_instruction(fs); | 462 | Instruction i = previous_instruction(fs); |
| 463 | int delta = (int)luaK_opproperties[o].push - (int)luaK_opproperties[o].pop; | 463 | int push = (int)luaK_opproperties[o].push; |
| 464 | int pop = (int)luaK_opproperties[o].pop; | ||
| 464 | int optm = 0; /* 1 when there is an optimization */ | 465 | int optm = 0; /* 1 when there is an optimization */ |
| 465 | switch (o) { | 466 | switch (o) { |
| 466 | case OP_CLOSURE: { | 467 | case OP_CLOSURE: { |
| 467 | delta = -arg2+1; | 468 | pop = arg2; |
| 468 | break; | 469 | break; |
| 469 | } | 470 | } |
| 470 | case OP_SETTABLE: { | 471 | case OP_SETTABLE: { |
| 471 | delta = -arg2; | 472 | pop = arg2; |
| 472 | break; | 473 | break; |
| 473 | } | 474 | } |
| 474 | case OP_SETLIST: { | 475 | case OP_SETLIST: { |
| 475 | if (arg2 == 0) return NO_JUMP; /* nothing to do */ | 476 | if (arg2 == 0) return NO_JUMP; /* nothing to do */ |
| 476 | delta = -arg2; | 477 | pop = arg2; |
| 477 | break; | 478 | break; |
| 478 | } | 479 | } |
| 479 | case OP_SETMAP: { | 480 | case OP_SETMAP: { |
| 480 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ | 481 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ |
| 481 | delta = -2*arg1; | 482 | pop = 2*arg1; |
| 482 | break; | 483 | break; |
| 483 | } | 484 | } |
| 484 | case OP_RETURN: { | 485 | case OP_RETURN: { |
| @@ -491,7 +492,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 491 | } | 492 | } |
| 492 | case OP_PUSHNIL: { | 493 | case OP_PUSHNIL: { |
| 493 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ | 494 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ |
| 494 | delta = arg1; | 495 | push = arg1; |
| 495 | switch(GET_OPCODE(i)) { | 496 | switch(GET_OPCODE(i)) { |
| 496 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; | 497 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; |
| 497 | default: break; | 498 | default: break; |
| @@ -500,7 +501,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 500 | } | 501 | } |
| 501 | case OP_POP: { | 502 | case OP_POP: { |
| 502 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ | 503 | if (arg1 == 0) return NO_JUMP; /* nothing to do */ |
| 503 | delta = -arg1; | 504 | pop = arg1; |
| 504 | switch(GET_OPCODE(i)) { | 505 | switch(GET_OPCODE(i)) { |
| 505 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; | 506 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; |
| 506 | default: break; | 507 | default: break; |
| @@ -539,7 +540,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 539 | break; | 540 | break; |
| 540 | } | 541 | } |
| 541 | case OP_CONCAT: { | 542 | case OP_CONCAT: { |
| 542 | delta = -arg1+1; | 543 | pop = arg1; |
| 543 | switch(GET_OPCODE(i)) { | 544 | switch(GET_OPCODE(i)) { |
| 544 | case OP_CONCAT: /* `a..b..c' */ | 545 | case OP_CONCAT: /* `a..b..c' */ |
| 545 | SETARG_U(i, GETARG_U(i)+1); | 546 | SETARG_U(i, GETARG_U(i)+1); |
| @@ -573,7 +574,7 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 573 | case OP_JMPEQ: { | 574 | case OP_JMPEQ: { |
| 574 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ | 575 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ |
| 575 | i = CREATE_0(OP_NOT); | 576 | i = CREATE_0(OP_NOT); |
| 576 | delta = -1; /* just undo effect of previous PUSHNIL */ | 577 | pop = 1; /* just undo effect of previous PUSHNIL */ |
| 577 | optm = 1; | 578 | optm = 1; |
| 578 | } | 579 | } |
| 579 | break; | 580 | break; |
| @@ -637,12 +638,14 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
| 637 | break; | 638 | break; |
| 638 | } | 639 | } |
| 639 | default: { | 640 | default: { |
| 640 | lua_assert(delta != VD); | ||
| 641 | break; | 641 | break; |
| 642 | } | 642 | } |
| 643 | } | 643 | } |
| 644 | f = fs->f; | 644 | f = fs->f; |
| 645 | luaK_deltastack(fs, delta); | 645 | lua_assert(push != VD); |
| 646 | lua_assert(pop != VD); | ||
| 647 | luaK_deltastack(fs, push); | ||
| 648 | luaK_deltastack(fs, -pop); | ||
| 646 | if (optm) { /* optimize: put instruction in place of last one */ | 649 | if (optm) { /* optimize: put instruction in place of last one */ |
| 647 | f->code[fs->pc-1] = i; /* change previous instruction */ | 650 | f->code[fs->pc-1] = i; /* change previous instruction */ |
| 648 | return fs->pc-1; /* do not generate new instruction */ | 651 | return fs->pc-1; /* do not generate new instruction */ |
| @@ -668,7 +671,7 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = { | |||
| 668 | {iAB, 0, 0}, /* OP_CALL */ | 671 | {iAB, 0, 0}, /* OP_CALL */ |
| 669 | {iAB, 0, 0}, /* OP_TAILCALL */ | 672 | {iAB, 0, 0}, /* OP_TAILCALL */ |
| 670 | {iU, VD, 0}, /* OP_PUSHNIL */ | 673 | {iU, VD, 0}, /* OP_PUSHNIL */ |
| 671 | {iU, VD, 0}, /* OP_POP */ | 674 | {iU, 0, VD}, /* OP_POP */ |
| 672 | {iS, 1, 0}, /* OP_PUSHINT */ | 675 | {iS, 1, 0}, /* OP_PUSHINT */ |
| 673 | {iU, 1, 0}, /* OP_PUSHSTRING */ | 676 | {iU, 1, 0}, /* OP_PUSHSTRING */ |
| 674 | {iU, 1, 0}, /* OP_PUSHNUM */ | 677 | {iU, 1, 0}, /* OP_PUSHNUM */ |
| @@ -683,16 +686,16 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = { | |||
| 683 | {iU, 1, 0}, /* OP_CREATETABLE */ | 686 | {iU, 1, 0}, /* OP_CREATETABLE */ |
| 684 | {iU, 0, 1}, /* OP_SETLOCAL */ | 687 | {iU, 0, 1}, /* OP_SETLOCAL */ |
| 685 | {iU, 0, 1}, /* OP_SETGLOBAL */ | 688 | {iU, 0, 1}, /* OP_SETGLOBAL */ |
| 686 | {iAB, VD, 0}, /* OP_SETTABLE */ | 689 | {iAB, 0, VD}, /* OP_SETTABLE */ |
| 687 | {iAB, VD, 0}, /* OP_SETLIST */ | 690 | {iAB, 0, VD}, /* OP_SETLIST */ |
| 688 | {iU, VD, 0}, /* OP_SETMAP */ | 691 | {iU, 0, VD}, /* OP_SETMAP */ |
| 689 | {iO, 1, 2}, /* OP_ADD */ | 692 | {iO, 1, 2}, /* OP_ADD */ |
| 690 | {iS, 1, 1}, /* OP_ADDI */ | 693 | {iS, 1, 1}, /* OP_ADDI */ |
| 691 | {iO, 1, 2}, /* OP_SUB */ | 694 | {iO, 1, 2}, /* OP_SUB */ |
| 692 | {iO, 1, 2}, /* OP_MULT */ | 695 | {iO, 1, 2}, /* OP_MULT */ |
| 693 | {iO, 1, 2}, /* OP_DIV */ | 696 | {iO, 1, 2}, /* OP_DIV */ |
| 694 | {iO, 1, 2}, /* OP_POW */ | 697 | {iO, 1, 2}, /* OP_POW */ |
| 695 | {iU, VD, 0}, /* OP_CONCAT */ | 698 | {iU, 1, VD}, /* OP_CONCAT */ |
| 696 | {iO, 1, 1}, /* OP_MINUS */ | 699 | {iO, 1, 1}, /* OP_MINUS */ |
| 697 | {iO, 1, 1}, /* OP_NOT */ | 700 | {iO, 1, 1}, /* OP_NOT */ |
| 698 | {iS, 0, 2}, /* OP_JMPNE */ | 701 | {iS, 0, 2}, /* OP_JMPNE */ |
| @@ -711,6 +714,6 @@ const OpProperties luaK_opproperties[NUM_OPCODES] = { | |||
| 711 | {iS, 0, 3}, /* OP_FORLOOP */ | 714 | {iS, 0, 3}, /* OP_FORLOOP */ |
| 712 | {iS, 3, 0}, /* OP_LFORPREP */ | 715 | {iS, 3, 0}, /* OP_LFORPREP */ |
| 713 | {iS, 0, 4}, /* OP_LFORLOOP */ | 716 | {iS, 0, 4}, /* OP_LFORLOOP */ |
| 714 | {iAB, VD, 0} /* OP_CLOSURE */ | 717 | {iAB, 1, VD} /* OP_CLOSURE */ |
| 715 | }; | 718 | }; |
| 716 | 719 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.58 2001/01/29 17:16:58 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.59 2001/02/02 15:13:05 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -397,10 +397,12 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { | |||
| 397 | } | 397 | } |
| 398 | default: { | 398 | default: { |
| 399 | OpCode op = GET_OPCODE(i); | 399 | OpCode op = GET_OPCODE(i); |
| 400 | lua_assert(luaK_opproperties[op].push != VD); | 400 | int push = (int)luaK_opproperties[op].push; |
| 401 | top -= (int)luaK_opproperties[op].pop; | 401 | int pop = (int)luaK_opproperties[op].pop; |
| 402 | lua_assert(top >= 0); | 402 | lua_assert(push != VD && pop != VD); |
| 403 | top = pushpc(stack, pc, top, luaK_opproperties[op].push); | 403 | lua_assert(0 <= top-pop && top+push <= pt->maxstacksize); |
| 404 | top -= pop; | ||
| 405 | top = pushpc(stack, pc, top, push); | ||
| 404 | } | 406 | } |
| 405 | } | 407 | } |
| 406 | } | 408 | } |
| @@ -482,9 +484,9 @@ void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) { | |||
| 482 | } | 484 | } |
| 483 | 485 | ||
| 484 | 486 | ||
| 485 | void luaG_ordererror (lua_State *L, StkId top) { | 487 | void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) { |
| 486 | const char *t1 = luaT_typename(G(L), top-2); | 488 | const char *t1 = luaT_typename(G(L), p1); |
| 487 | const char *t2 = luaT_typename(G(L), top-1); | 489 | const char *t2 = luaT_typename(G(L), p2); |
| 488 | if (t1[2] == t2[2]) | 490 | if (t1[2] == t2[2]) |
| 489 | luaO_verror(L, "attempt to compare two %.10s values", t1); | 491 | luaO_verror(L, "attempt to compare two %.10s values", t1); |
| 490 | else | 492 | else |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.h,v 1.6 2000/10/02 20:10:55 roberto Exp roberto $ | 2 | ** $Id: ldebug.h,v 1.7 2000/10/05 12:14:08 roberto Exp roberto $ |
| 3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -15,7 +15,7 @@ | |||
| 15 | void luaG_typeerror (lua_State *L, StkId o, const char *op); | 15 | void luaG_typeerror (lua_State *L, StkId o, const char *op); |
| 16 | void luaG_binerror (lua_State *L, StkId p1, int t, const char *op); | 16 | void luaG_binerror (lua_State *L, StkId p1, int t, const char *op); |
| 17 | int luaG_getline (int *lineinfo, int pc, int refline, int *refi); | 17 | int luaG_getline (int *lineinfo, int pc, int refline, int *refi); |
| 18 | void luaG_ordererror (lua_State *L, StkId top); | 18 | void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | #endif | 21 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 1.121 2001/02/02 15:13:05 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.122 2001/02/02 16:23:20 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -143,14 +143,6 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | 145 | ||
| 146 | void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) { | ||
| 147 | StkId base = L->top - nParams; | ||
| 148 | luaD_openstack(L, base); | ||
| 149 | setclvalue(base, f); | ||
| 150 | luaD_call(L, base, nResults); | ||
| 151 | } | ||
| 152 | |||
| 153 | |||
| 154 | /* | 146 | /* |
| 155 | ** Call a function (C or Lua). The function to be called is at *func. | 147 | ** Call a function (C or Lua). The function to be called is at *func. |
| 156 | ** The arguments are on the stack, right after the function. | 148 | ** The arguments are on the stack, right after the function. |
| @@ -182,6 +174,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) { | |||
| 182 | if (callhook) /* same hook that was active at entry */ | 174 | if (callhook) /* same hook that was active at entry */ |
| 183 | luaD_callHook(L, func, callhook, "return"); | 175 | luaD_callHook(L, func, callhook, "return"); |
| 184 | lua_assert(ttype(func) == LUA_TMARK); | 176 | lua_assert(ttype(func) == LUA_TMARK); |
| 177 | setnilvalue(func); /* remove callinfo from the stack */ | ||
| 185 | /* move results to `func' (to erase parameters and function) */ | 178 | /* move results to `func' (to erase parameters and function) */ |
| 186 | if (nResults == LUA_MULTRET) { | 179 | if (nResults == LUA_MULTRET) { |
| 187 | while (firstResult < L->top) /* copy all results */ | 180 | while (firstResult < L->top) /* copy all results */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 1.29 2001/01/24 15:45:33 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,7 +23,6 @@ void luaD_init (lua_State *L, int stacksize); | |||
| 23 | void luaD_adjusttop (lua_State *L, StkId base, int extra); | 23 | void luaD_adjusttop (lua_State *L, StkId base, int extra); |
| 24 | void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook); | 24 | void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook); |
| 25 | void luaD_call (lua_State *L, StkId func, int nResults); | 25 | void luaD_call (lua_State *L, StkId func, int nResults); |
| 26 | void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults); | ||
| 27 | void luaD_checkstack (lua_State *L, int n); | 26 | void luaD_checkstack (lua_State *L, int n); |
| 28 | 27 | ||
| 29 | void luaD_error (lua_State *L, const char *s); | 28 | void luaD_error (lua_State *L, const char *s); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.86 2001/02/02 16:23:20 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.87 2001/02/02 16:32:00 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -101,11 +101,14 @@ static void markobject (GCState *st, TObject *o) { | |||
| 101 | static void markstacks (lua_State *L, GCState *st) { | 101 | static void markstacks (lua_State *L, GCState *st) { |
| 102 | lua_State *L1 = L; | 102 | lua_State *L1 = L; |
| 103 | do { /* for each thread */ | 103 | do { /* for each thread */ |
| 104 | StkId o; | 104 | StkId o, lim; |
| 105 | marktable(st, L1->gt); /* mark table of globals */ | 105 | marktable(st, L1->gt); /* mark table of globals */ |
| 106 | for (o=L1->stack; o<L1->top; o++) | 106 | for (o=L1->stack; o<L1->top; o++) |
| 107 | markobject(st, o); | 107 | markobject(st, o); |
| 108 | lua_assert(L->previous->next == L && L->next->previous == L); | 108 | lim = (L1->stack_last - L1->top > MAXSTACK) ? L1->top+MAXSTACK |
| 109 | : L1->stack_last; | ||
| 110 | for (; o<=lim; o++) setnilvalue(o); | ||
| 111 | lua_assert(L1->previous->next == L1 && L1->next->previous == L1); | ||
| 109 | L1 = L1->next; | 112 | L1 = L1->next; |
| 110 | } while (L1 != L); | 113 | } while (L1 != L); |
| 111 | } | 114 | } |
| @@ -1,10 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.164 2001/02/02 15:13:05 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.165 2001/02/06 16:01:29 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include <stdarg.h> | ||
| 8 | #include <stdio.h> | 9 | #include <stdio.h> |
| 9 | #include <stdlib.h> | 10 | #include <stdlib.h> |
| 10 | #include <string.h> | 11 | #include <string.h> |
| @@ -26,14 +27,6 @@ | |||
| 26 | 27 | ||
| 27 | 28 | ||
| 28 | 29 | ||
| 29 | /* | ||
| 30 | ** Extra stack size to run a function: | ||
| 31 | ** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...) | ||
| 32 | */ | ||
| 33 | #define EXTRA_FSTACK 8 | ||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | int luaV_tonumber (TObject *obj) { | 30 | int luaV_tonumber (TObject *obj) { |
| 38 | if (ttype(obj) != LUA_TSTRING) | 31 | if (ttype(obj) != LUA_TSTRING) |
| 39 | return 1; | 32 | return 1; |
| @@ -58,7 +51,7 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ | |||
| 58 | } | 51 | } |
| 59 | 52 | ||
| 60 | 53 | ||
| 61 | static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) { | 54 | static void traceexec (lua_State *L, StkId base, lua_Hook linehook) { |
| 62 | CallInfo *ci = infovalue(base-1); | 55 | CallInfo *ci = infovalue(base-1); |
| 63 | int *lineinfo = ci->func->f.l->lineinfo; | 56 | int *lineinfo = ci->func->f.l->lineinfo; |
| 64 | int pc = (*ci->pc - ci->func->f.l->code) - 1; | 57 | int pc = (*ci->pc - ci->func->f.l->code) - 1; |
| @@ -72,7 +65,6 @@ static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) { | |||
| 72 | /* calls linehook when enters a new line or jumps back (loop) */ | 65 | /* calls linehook when enters a new line or jumps back (loop) */ |
| 73 | if (newline != ci->line || pc <= ci->lastpc) { | 66 | if (newline != ci->line || pc <= ci->lastpc) { |
| 74 | ci->line = newline; | 67 | ci->line = newline; |
| 75 | L->top = top; | ||
| 76 | luaD_lineHook(L, base-2, newline, linehook); | 68 | luaD_lineHook(L, base-2, newline, linehook); |
| 77 | } | 69 | } |
| 78 | ci->lastpc = pc; | 70 | ci->lastpc = pc; |
| @@ -104,19 +96,52 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { | |||
| 104 | } | 96 | } |
| 105 | 97 | ||
| 106 | 98 | ||
| 99 | static void callTM (lua_State *L, const char *fmt, ...) { | ||
| 100 | va_list argp; | ||
| 101 | StkId base = L->top; | ||
| 102 | int has_result = 0; | ||
| 103 | va_start(argp, fmt); | ||
| 104 | for (;;) { | ||
| 105 | switch (*fmt++) { | ||
| 106 | case 'c': | ||
| 107 | setclvalue(L->top, va_arg(argp, Closure *)); | ||
| 108 | break; | ||
| 109 | case 'o': | ||
| 110 | setobj(L->top, va_arg(argp, TObject *)); | ||
| 111 | break; | ||
| 112 | case 's': | ||
| 113 | setsvalue(L->top, va_arg(argp, TString *)); | ||
| 114 | break; | ||
| 115 | case 'r': | ||
| 116 | has_result = 1; | ||
| 117 | /* go through */ | ||
| 118 | default: | ||
| 119 | goto endloop; | ||
| 120 | } | ||
| 121 | incr_top; | ||
| 122 | } endloop: | ||
| 123 | luaD_call(L, base, has_result); | ||
| 124 | if (has_result) { | ||
| 125 | L->top--; | ||
| 126 | setobj(va_arg(argp, TObject *), L->top); | ||
| 127 | } | ||
| 128 | va_end(argp); | ||
| 129 | } | ||
| 130 | |||
| 131 | |||
| 107 | /* | 132 | /* |
| 108 | ** Function to index a table. | 133 | ** Function to index a table. |
| 109 | ** Receives the table at `t' and the key at the top (`top'-1), | 134 | ** Receives the table at `t' and the key at the `key'. |
| 110 | ** leaves the result at `res'. | 135 | ** leaves the result at `res'. |
| 111 | */ | 136 | */ |
| 112 | void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res) { | 137 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { |
| 113 | Closure *tm; | 138 | Closure *tm; |
| 114 | int tg; | 139 | int tg; |
| 115 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ | 140 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ |
| 116 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ | 141 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ |
| 117 | luaT_gettm(G(L), tg, TM_GETTABLE) == NULL)) { /* or no TM? */ | 142 | luaT_gettm(G(L), tg, TM_GETTABLE) == NULL)) { /* or no TM? */ |
| 118 | /* do a primitive get */ | 143 | /* do a primitive get */ |
| 119 | const TObject *h = luaH_get(hvalue(t), top-1); | 144 | const TObject *h = luaH_get(hvalue(t), key); |
| 120 | /* result is no nil or there is no `index' tag method? */ | 145 | /* result is no nil or there is no `index' tag method? */ |
| 121 | if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) { | 146 | if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) { |
| 122 | setobj(res, h); | 147 | setobj(res, h); |
| @@ -127,116 +152,79 @@ void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res) { | |||
| 127 | else { /* try a `gettable' tag method */ | 152 | else { /* try a `gettable' tag method */ |
| 128 | tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); | 153 | tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE); |
| 129 | } | 154 | } |
| 130 | L->top = top; | ||
| 131 | if (tm == NULL) /* no tag method? */ | 155 | if (tm == NULL) /* no tag method? */ |
| 132 | luaG_typeerror(L, t, "index"); | 156 | luaG_typeerror(L, t, "index"); |
| 133 | else { /* call tag method */ | 157 | else |
| 134 | luaD_checkstack(L, 2); | 158 | callTM(L, "coor", tm, t, key, res); |
| 135 | setobj(res+2, top-1); /* key */ | ||
| 136 | setobj(res+1, t); /* table */ | ||
| 137 | setclvalue(res, tm); /* tag method */ | ||
| 138 | L->top = res+3; | ||
| 139 | luaD_call(L, res, 1); | ||
| 140 | L->top = top; /* will be decremented by the callee */ | ||
| 141 | } | ||
| 142 | } | 159 | } |
| 143 | 160 | ||
| 144 | 161 | ||
| 162 | |||
| 145 | /* | 163 | /* |
| 146 | ** Receives table at `t', key at `key' and value at top. | 164 | ** Receives table at `t', key at `key' and value at `val'. |
| 147 | */ | 165 | */ |
| 148 | void luaV_settable (lua_State *L, StkId t, StkId key, StkId top) { | 166 | void luaV_settable (lua_State *L, StkId t, StkId key, StkId val) { |
| 149 | int tg; | 167 | int tg; |
| 150 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ | 168 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ |
| 151 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ | 169 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ |
| 152 | luaT_gettm(G(L), tg, TM_SETTABLE) == NULL)) { /* or no TM? */ | 170 | luaT_gettm(G(L), tg, TM_SETTABLE) == NULL)) { /* or no TM? */ |
| 153 | setobj(luaH_set(L, hvalue(t), key), top-1); /* do a primitive set */ | 171 | setobj(luaH_set(L, hvalue(t), key), val); /* do a primitive set */ |
| 154 | } | 172 | } |
| 155 | else { /* try a `settable' tag method */ | 173 | else { /* try a `settable' tag method */ |
| 156 | Closure *tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); | 174 | Closure *tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE); |
| 157 | lua_assert(L->top == top); | ||
| 158 | if (tm == NULL) /* no tag method? */ | 175 | if (tm == NULL) /* no tag method? */ |
| 159 | luaG_typeerror(L, t, "index"); | 176 | luaG_typeerror(L, t, "index"); |
| 160 | else { | 177 | else |
| 161 | luaD_checkstack(L, 3); | 178 | callTM(L, "cooo", tm, t, key, val); |
| 162 | setobj(top+2, top-1); | ||
| 163 | setobj(top+1, key); | ||
| 164 | setobj(top, t); | ||
| 165 | setclvalue(top-1, tm); | ||
| 166 | L->top = top+3; | ||
| 167 | luaD_call(L, top-1, 0); /* call `settable' tag method */ | ||
| 168 | lua_assert(L->top == top-1); | ||
| 169 | L->top = top; /* will be decremented by the callee */ | ||
| 170 | } | ||
| 171 | } | 179 | } |
| 172 | } | 180 | } |
| 173 | 181 | ||
| 174 | 182 | ||
| 175 | void luaV_getglobal (lua_State *L, TString *s, StkId top) { | 183 | void luaV_getglobal (lua_State *L, TString *name, StkId res) { |
| 176 | const TObject *value = luaH_getstr(L->gt, s); | 184 | const TObject *value = luaH_getstr(L->gt, name); |
| 177 | Closure *tm; | 185 | Closure *tm; |
| 178 | if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ | 186 | if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */ |
| 179 | (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { | 187 | (tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) { |
| 180 | setobj(top, value); /* default behavior */ | 188 | setobj(res, value); /* default behavior */ |
| 181 | } | ||
| 182 | else { /* call tag method */ | ||
| 183 | L->top = top; | ||
| 184 | luaD_checkstack(L, 3); | ||
| 185 | setclvalue(top, tm); | ||
| 186 | setsvalue(top+1, s); /* global name */ | ||
| 187 | setobj(top+2, value); | ||
| 188 | L->top = top+3; | ||
| 189 | luaD_call(L, top, 1); | ||
| 190 | lua_assert(L->top == top+1); | ||
| 191 | L->top = top; /* will be incremented by the callee */ | ||
| 192 | } | 189 | } |
| 190 | else | ||
| 191 | callTM(L, "csor", tm, name, value, res); | ||
| 193 | } | 192 | } |
| 194 | 193 | ||
| 195 | 194 | ||
| 196 | void luaV_setglobal (lua_State *L, TString *s, StkId top) { | 195 | void luaV_setglobal (lua_State *L, TString *name, StkId val) { |
| 197 | TObject *oldvalue = luaH_setstr(L, L->gt, s); | 196 | TObject *oldvalue = luaH_setstr(L, L->gt, name); |
| 198 | Closure *tm; | 197 | Closure *tm; |
| 199 | if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ | 198 | if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */ |
| 200 | (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { | 199 | (tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) { |
| 201 | setobj(oldvalue, top-1); /* raw set */ | 200 | setobj(oldvalue, val); /* raw set */ |
| 202 | } | ||
| 203 | else { /* call tag method */ | ||
| 204 | lua_assert(L->top == top); | ||
| 205 | luaD_checkstack(L, 3); | ||
| 206 | setobj(top+2, top-1); /* new value */ | ||
| 207 | setobj(top+1, oldvalue); /* old value */ | ||
| 208 | setsvalue(top, s); /* var name */ | ||
| 209 | setclvalue(top-1, tm); /* tag method */ | ||
| 210 | L->top = top+3; | ||
| 211 | luaD_call(L, top-1, 0); | ||
| 212 | lua_assert(L->top == top-1); | ||
| 213 | L->top = top; /* will be decremented by the callee */ | ||
| 214 | } | 201 | } |
| 202 | else | ||
| 203 | callTM(L, "csoo", tm, name, oldvalue, val); | ||
| 215 | } | 204 | } |
| 216 | 205 | ||
| 217 | 206 | ||
| 218 | static int call_binTM (lua_State *L, StkId top, TMS event) { | 207 | static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, |
| 219 | /* try first operand */ | 208 | TObject *res, TMS event) { |
| 220 | Closure *tm = luaT_gettmbyObj(G(L), top-2, event); | 209 | TString *opname; |
| 221 | L->top = top; | 210 | Closure *tm = luaT_gettmbyObj(G(L), p1, event); /* try first operand */ |
| 222 | if (tm == NULL) { | 211 | if (tm == NULL) { |
| 223 | tm = luaT_gettmbyObj(G(L), top-1, event); /* try second operand */ | 212 | tm = luaT_gettmbyObj(G(L), p2, event); /* try second operand */ |
| 224 | if (tm == NULL) { | 213 | if (tm == NULL) { |
| 225 | tm = luaT_gettm(G(L), 0, event); /* try a `global' method */ | 214 | tm = luaT_gettm(G(L), 0, event); /* try a `global' method */ |
| 226 | if (tm == NULL) | 215 | if (tm == NULL) |
| 227 | return 0; /* error */ | 216 | return 0; /* no tag method */ |
| 228 | } | 217 | } |
| 229 | } | 218 | } |
| 230 | setsvalue(L->top, luaS_new(L, luaT_eventname[event])); | 219 | opname = luaS_new(L, luaT_eventname[event]); |
| 231 | incr_top; | 220 | callTM(L, "coosr", tm, p1, p2, opname, res); |
| 232 | luaD_callTM(L, tm, 3, 1); | ||
| 233 | return 1; | 221 | return 1; |
| 234 | } | 222 | } |
| 235 | 223 | ||
| 236 | 224 | ||
| 237 | static void call_arith (lua_State *L, StkId top, TMS event) { | 225 | static void call_arith (lua_State *L, StkId p1, TMS event) { |
| 238 | if (!call_binTM(L, top, event)) | 226 | if (!call_binTM(L, p1, p1+1, p1, event)) |
| 239 | luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on"); | 227 | luaG_binerror(L, p1, LUA_TNUMBER, "perform arithmetic on"); |
| 240 | } | 228 | } |
| 241 | 229 | ||
| 242 | 230 | ||
| @@ -262,19 +250,14 @@ static int luaV_strlessthan (const TString *ls, const TString *rs) { | |||
| 262 | } | 250 | } |
| 263 | 251 | ||
| 264 | 252 | ||
| 265 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) { | 253 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) { |
| 266 | if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) | 254 | if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER) |
| 267 | return (nvalue(l) < nvalue(r)); | 255 | return (nvalue(l) < nvalue(r)); |
| 268 | else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) | 256 | else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING) |
| 269 | return luaV_strlessthan(tsvalue(l), tsvalue(r)); | 257 | return luaV_strlessthan(tsvalue(l), tsvalue(r)); |
| 270 | else { /* call TM */ | 258 | else { /* try TM */ |
| 271 | L->top = top; | 259 | if (!call_binTM(L, l, r, L->top, TM_LT)) |
| 272 | luaD_checkstack(L, 2); | 260 | luaG_ordererror(L, l, r); |
| 273 | setobj(top++, l); | ||
| 274 | setobj(top++, r); | ||
| 275 | if (!call_binTM(L, top, TM_LT)) | ||
| 276 | luaG_ordererror(L, top); | ||
| 277 | L->top--; | ||
| 278 | return (ttype(L->top) != LUA_TNIL); | 261 | return (ttype(L->top) != LUA_TNIL); |
| 279 | } | 262 | } |
| 280 | } | 263 | } |
| @@ -284,7 +267,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
| 284 | do { | 267 | do { |
| 285 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 268 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
| 286 | if (tostring(L, top-2) || tostring(L, top-1)) { | 269 | if (tostring(L, top-2) || tostring(L, top-1)) { |
| 287 | if (!call_binTM(L, top, TM_CONCAT)) | 270 | if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) |
| 288 | luaG_binerror(L, top-2, LUA_TSTRING, "concat"); | 271 | luaG_binerror(L, top-2, LUA_TSTRING, "concat"); |
| 289 | } | 272 | } |
| 290 | else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ | 273 | else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ |
| @@ -350,17 +333,16 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 350 | TString **const kstr = tf->kstr; | 333 | TString **const kstr = tf->kstr; |
| 351 | const lua_Hook linehook = L->linehook; | 334 | const lua_Hook linehook = L->linehook; |
| 352 | infovalue(base-1)->pc = &pc; | 335 | infovalue(base-1)->pc = &pc; |
| 353 | luaD_checkstack(L, tf->maxstacksize+EXTRA_FSTACK); | ||
| 354 | if (tf->is_vararg) /* varargs? */ | 336 | if (tf->is_vararg) /* varargs? */ |
| 355 | adjust_varargs(L, base, tf->numparams); | 337 | adjust_varargs(L, base, tf->numparams); |
| 356 | else | 338 | luaD_adjusttop(L, base, tf->maxstacksize); |
| 357 | luaD_adjusttop(L, base, tf->numparams); | 339 | top = base+tf->numparams+tf->is_vararg; |
| 358 | top = L->top; | ||
| 359 | /* main loop of interpreter */ | 340 | /* main loop of interpreter */ |
| 360 | for (;;) { | 341 | for (;;) { |
| 361 | const Instruction i = *pc++; | 342 | const Instruction i = *pc++; |
| 343 | lua_assert(L->top == base+tf->maxstacksize); | ||
| 362 | if (linehook) | 344 | if (linehook) |
| 363 | traceexec(L, base, top, linehook); | 345 | traceexec(L, base, linehook); |
| 364 | switch (GET_OPCODE(i)) { | 346 | switch (GET_OPCODE(i)) { |
| 365 | case OP_RETURN: { | 347 | case OP_RETURN: { |
| 366 | L->top = top; | 348 | L->top = top; |
| @@ -372,6 +354,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 372 | L->top = top; | 354 | L->top = top; |
| 373 | luaD_call(L, base+GETARG_A(i), nres); | 355 | luaD_call(L, base+GETARG_A(i), nres); |
| 374 | top = L->top; | 356 | top = L->top; |
| 357 | L->top = base+tf->maxstacksize; | ||
| 375 | break; | 358 | break; |
| 376 | } | 359 | } |
| 377 | case OP_TAILCALL: { | 360 | case OP_TAILCALL: { |
| @@ -425,31 +408,27 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 425 | break; | 408 | break; |
| 426 | } | 409 | } |
| 427 | case OP_GETTABLE: { | 410 | case OP_GETTABLE: { |
| 428 | luaV_gettable(L, top-2, top, top-2); | ||
| 429 | top--; | 411 | top--; |
| 412 | luaV_gettable(L, top-1, top, top-1); | ||
| 430 | break; | 413 | break; |
| 431 | } | 414 | } |
| 432 | case OP_GETDOTTED: { | 415 | case OP_GETDOTTED: { |
| 433 | setsvalue(top, kstr[GETARG_U(i)]); | 416 | setsvalue(top, kstr[GETARG_U(i)]); |
| 434 | luaV_gettable(L, top-1, top+1, top-1); | 417 | luaV_gettable(L, top-1, top, top-1); |
| 435 | break; | 418 | break; |
| 436 | } | 419 | } |
| 437 | case OP_GETINDEXED: { | 420 | case OP_GETINDEXED: { |
| 438 | setobj(top, base+GETARG_U(i)); | 421 | luaV_gettable(L, top-1, base+GETARG_U(i), top-1); |
| 439 | luaV_gettable(L, top-1, top+1, top-1); | ||
| 440 | break; | 422 | break; |
| 441 | } | 423 | } |
| 442 | case OP_PUSHSELF: { | 424 | case OP_PUSHSELF: { |
| 443 | TObject receiver; | 425 | setobj(top, top-1); |
| 444 | setobj(&receiver, top-1); | 426 | setsvalue(top+1, kstr[GETARG_U(i)]); |
| 445 | setsvalue(top, kstr[GETARG_U(i)]); | 427 | luaV_gettable(L, top-1, top+1, top-1); |
| 446 | top++; | 428 | top++; |
| 447 | luaV_gettable(L, top-2, top, top-2); | ||
| 448 | setobj(top-1, &receiver); | ||
| 449 | break; | 429 | break; |
| 450 | } | 430 | } |
| 451 | case OP_CREATETABLE: { | 431 | case OP_CREATETABLE: { |
| 452 | L->top = top; | ||
| 453 | luaC_checkGC(L); | 432 | luaC_checkGC(L); |
| 454 | sethvalue(top, luaH_new(L, GETARG_U(i))); | 433 | sethvalue(top, luaH_new(L, GETARG_U(i))); |
| 455 | top++; | 434 | top++; |
| @@ -460,15 +439,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 460 | break; | 439 | break; |
| 461 | } | 440 | } |
| 462 | case OP_SETGLOBAL: { | 441 | case OP_SETGLOBAL: { |
| 463 | L->top = top; /* primitive set may generate an error */ | ||
| 464 | luaV_setglobal(L, kstr[GETARG_U(i)], top); | ||
| 465 | top--; | 442 | top--; |
| 443 | luaV_setglobal(L, kstr[GETARG_U(i)], top); | ||
| 466 | break; | 444 | break; |
| 467 | } | 445 | } |
| 468 | case OP_SETTABLE: { | 446 | case OP_SETTABLE: { |
| 469 | StkId t = top-GETARG_A(i); | 447 | StkId t = top-GETARG_A(i); |
| 470 | L->top = top; /* primitive set may generate an error */ | 448 | luaV_settable(L, t, t+1, top-1); |
| 471 | luaV_settable(L, t, t+1, top); | ||
| 472 | top -= GETARG_B(i); /* pop values */ | 449 | top -= GETARG_B(i); /* pop values */ |
| 473 | break; | 450 | break; |
| 474 | } | 451 | } |
| @@ -476,16 +453,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 476 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; | 453 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; |
| 477 | int n = GETARG_B(i); | 454 | int n = GETARG_B(i); |
| 478 | Hash *arr = hvalue(top-n-1); | 455 | Hash *arr = hvalue(top-n-1); |
| 479 | L->top = top-n; | ||
| 480 | for (; n; n--) | 456 | for (; n; n--) |
| 481 | setobj(luaH_setnum(L, arr, n+aux), --top); | 457 | setobj(luaH_setnum(L, arr, n+aux), --top); |
| 482 | break; | 458 | break; |
| 483 | } | 459 | } |
| 484 | case OP_SETMAP: { | 460 | case OP_SETMAP: { |
| 485 | int n = GETARG_U(i); | 461 | int n = GETARG_U(i); |
| 486 | StkId finaltop = top-2*n; | 462 | Hash *arr = hvalue((top-2*n)-1); |
| 487 | Hash *arr = hvalue(finaltop-1); | ||
| 488 | L->top = finaltop; | ||
| 489 | for (; n; n--) { | 463 | for (; n; n--) { |
| 490 | top-=2; | 464 | top-=2; |
| 491 | setobj(luaH_set(L, arr, top), top+1); | 465 | setobj(luaH_set(L, arr, top), top+1); |
| @@ -494,7 +468,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 494 | } | 468 | } |
| 495 | case OP_ADD: { | 469 | case OP_ADD: { |
| 496 | if (tonumber(top-2) || tonumber(top-1)) | 470 | if (tonumber(top-2) || tonumber(top-1)) |
| 497 | call_arith(L, top, TM_ADD); | 471 | call_arith(L, top-2, TM_ADD); |
| 498 | else | 472 | else |
| 499 | nvalue(top-2) += nvalue(top-1); | 473 | nvalue(top-2) += nvalue(top-1); |
| 500 | top--; | 474 | top--; |
| @@ -503,7 +477,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 503 | case OP_ADDI: { | 477 | case OP_ADDI: { |
| 504 | if (tonumber(top-1)) { | 478 | if (tonumber(top-1)) { |
| 505 | setnvalue(top, (lua_Number)GETARG_S(i)); | 479 | setnvalue(top, (lua_Number)GETARG_S(i)); |
| 506 | call_arith(L, top+1, TM_ADD); | 480 | call_arith(L, top-1, TM_ADD); |
| 507 | } | 481 | } |
| 508 | else | 482 | else |
| 509 | nvalue(top-1) += (lua_Number)GETARG_S(i); | 483 | nvalue(top-1) += (lua_Number)GETARG_S(i); |
| @@ -511,7 +485,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 511 | } | 485 | } |
| 512 | case OP_SUB: { | 486 | case OP_SUB: { |
| 513 | if (tonumber(top-2) || tonumber(top-1)) | 487 | if (tonumber(top-2) || tonumber(top-1)) |
| 514 | call_arith(L, top, TM_SUB); | 488 | call_arith(L, top-2, TM_SUB); |
| 515 | else | 489 | else |
| 516 | nvalue(top-2) -= nvalue(top-1); | 490 | nvalue(top-2) -= nvalue(top-1); |
| 517 | top--; | 491 | top--; |
| @@ -519,7 +493,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 519 | } | 493 | } |
| 520 | case OP_MULT: { | 494 | case OP_MULT: { |
| 521 | if (tonumber(top-2) || tonumber(top-1)) | 495 | if (tonumber(top-2) || tonumber(top-1)) |
| 522 | call_arith(L, top, TM_MUL); | 496 | call_arith(L, top-2, TM_MUL); |
| 523 | else | 497 | else |
| 524 | nvalue(top-2) *= nvalue(top-1); | 498 | nvalue(top-2) *= nvalue(top-1); |
| 525 | top--; | 499 | top--; |
| @@ -527,14 +501,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 527 | } | 501 | } |
| 528 | case OP_DIV: { | 502 | case OP_DIV: { |
| 529 | if (tonumber(top-2) || tonumber(top-1)) | 503 | if (tonumber(top-2) || tonumber(top-1)) |
| 530 | call_arith(L, top, TM_DIV); | 504 | call_arith(L, top-2, TM_DIV); |
| 531 | else | 505 | else |
| 532 | nvalue(top-2) /= nvalue(top-1); | 506 | nvalue(top-2) /= nvalue(top-1); |
| 533 | top--; | 507 | top--; |
| 534 | break; | 508 | break; |
| 535 | } | 509 | } |
| 536 | case OP_POW: { | 510 | case OP_POW: { |
| 537 | if (!call_binTM(L, top, TM_POW)) | 511 | if (!call_binTM(L, top-2, top-1, top-2, TM_POW)) |
| 538 | luaD_error(L, "undefined operation"); | 512 | luaD_error(L, "undefined operation"); |
| 539 | top--; | 513 | top--; |
| 540 | break; | 514 | break; |
| @@ -543,14 +517,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 543 | int n = GETARG_U(i); | 517 | int n = GETARG_U(i); |
| 544 | luaV_strconc(L, n, top); | 518 | luaV_strconc(L, n, top); |
| 545 | top -= n-1; | 519 | top -= n-1; |
| 546 | L->top = top; | ||
| 547 | luaC_checkGC(L); | 520 | luaC_checkGC(L); |
| 548 | break; | 521 | break; |
| 549 | } | 522 | } |
| 550 | case OP_MINUS: { | 523 | case OP_MINUS: { |
| 551 | if (tonumber(top-1)) { | 524 | if (tonumber(top-1)) { |
| 552 | setnilvalue(top); | 525 | setnilvalue(top); |
| 553 | call_arith(L, top+1, TM_UNM); | 526 | call_arith(L, top-1, TM_UNM); |
| 554 | } | 527 | } |
| 555 | else | 528 | else |
| 556 | nvalue(top-1) = -nvalue(top-1); | 529 | nvalue(top-1) = -nvalue(top-1); |
| @@ -574,22 +547,22 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 574 | } | 547 | } |
| 575 | case OP_JMPLT: { | 548 | case OP_JMPLT: { |
| 576 | top -= 2; | 549 | top -= 2; |
| 577 | if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i); | 550 | if (luaV_lessthan(L, top, top+1)) dojump(pc, i); |
| 578 | break; | 551 | break; |
| 579 | } | 552 | } |
| 580 | case OP_JMPLE: { /* a <= b === !(b<a) */ | 553 | case OP_JMPLE: { /* a <= b === !(b<a) */ |
| 581 | top -= 2; | 554 | top -= 2; |
| 582 | if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i); | 555 | if (!luaV_lessthan(L, top+1, top)) dojump(pc, i); |
| 583 | break; | 556 | break; |
| 584 | } | 557 | } |
| 585 | case OP_JMPGT: { /* a > b === (b<a) */ | 558 | case OP_JMPGT: { /* a > b === (b<a) */ |
| 586 | top -= 2; | 559 | top -= 2; |
| 587 | if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i); | 560 | if (luaV_lessthan(L, top+1, top)) dojump(pc, i); |
| 588 | break; | 561 | break; |
| 589 | } | 562 | } |
| 590 | case OP_JMPGE: { /* a >= b === !(a<b) */ | 563 | case OP_JMPGE: { /* a >= b === !(a<b) */ |
| 591 | top -= 2; | 564 | top -= 2; |
| 592 | if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i); | 565 | if (!luaV_lessthan(L, top, top+1)) dojump(pc, i); |
| 593 | break; | 566 | break; |
| 594 | } | 567 | } |
| 595 | case OP_JMPT: { | 568 | case OP_JMPT: { |
| @@ -675,11 +648,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 675 | } | 648 | } |
| 676 | case OP_CLOSURE: { | 649 | case OP_CLOSURE: { |
| 677 | int nup = GETARG_B(i); | 650 | int nup = GETARG_B(i); |
| 651 | luaC_checkGC(L); | ||
| 678 | L->top = top; | 652 | L->top = top; |
| 679 | luaV_Lclosure(L, tf->kproto[GETARG_A(i)], nup); | 653 | luaV_Lclosure(L, tf->kproto[GETARG_A(i)], nup); |
| 680 | top -= (nup-1); | 654 | top -= (nup-1); |
| 681 | lua_assert(top == L->top); | 655 | L->top = base+tf->maxstacksize; |
| 682 | luaC_checkGC(L); | ||
| 683 | break; | 656 | break; |
| 684 | } | 657 | } |
| 685 | } | 658 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.h,v 1.27 2000/10/05 12:14:08 roberto Exp roberto $ | 2 | ** $Id: lvm.h,v 1.28 2001/02/01 16:03:38 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,14 +19,14 @@ | |||
| 19 | 19 | ||
| 20 | int luaV_tonumber (TObject *obj); | 20 | int luaV_tonumber (TObject *obj); |
| 21 | int luaV_tostring (lua_State *L, TObject *obj); | 21 | int luaV_tostring (lua_State *L, TObject *obj); |
| 22 | void luaV_gettable (lua_State *L, StkId t, StkId top, StkId res); | 22 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res); |
| 23 | void luaV_settable (lua_State *L, StkId t, StkId key, StkId top); | 23 | void luaV_settable (lua_State *L, StkId t, StkId key, StkId val); |
| 24 | void luaV_getglobal (lua_State *L, TString *s, StkId top); | 24 | void luaV_getglobal (lua_State *L, TString *s, StkId res); |
| 25 | void luaV_setglobal (lua_State *L, TString *s, StkId top); | 25 | void luaV_setglobal (lua_State *L, TString *s, StkId val); |
| 26 | StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); | 26 | StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); |
| 27 | void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems); | 27 | void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems); |
| 28 | void luaV_Lclosure (lua_State *L, Proto *l, int nelems); | 28 | void luaV_Lclosure (lua_State *L, Proto *l, int nelems); |
| 29 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top); | 29 | int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r); |
| 30 | void luaV_strconc (lua_State *L, int total, StkId top); | 30 | void luaV_strconc (lua_State *L, int total, StkId top); |
| 31 | 31 | ||
| 32 | #endif | 32 | #endif |
