diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 19:00:01 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 19:00:01 -0300 |
| commit | d3037d97ec192e7719de485f15dacb473bf96528 (patch) | |
| tree | ea9f837cc64d9df82ae4324f2c7ea447b5c4582f /lvm.c | |
| parent | c6b442bd369ce05b3d4bfb95ba64451521aa1b31 (diff) | |
| download | lua-d3037d97ec192e7719de485f15dacb473bf96528.tar.gz lua-d3037d97ec192e7719de485f15dacb473bf96528.tar.bz2 lua-d3037d97ec192e7719de485f15dacb473bf96528.zip | |
several small improvements based on 'ci' being fixed now (including
erasing savedpc from lua_State)
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 155 |
1 files changed, 79 insertions, 76 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.84 2009/03/10 17:14:37 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.85 2009/04/17 14:28:06 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 | */ |
| @@ -58,21 +58,22 @@ int luaV_tostring (lua_State *L, StkId obj) { | |||
| 58 | 58 | ||
| 59 | 59 | ||
| 60 | static void traceexec (lua_State *L) { | 60 | static void traceexec (lua_State *L) { |
| 61 | CallInfo *ci = L->ci; | ||
| 61 | lu_byte mask = L->hookmask; | 62 | lu_byte mask = L->hookmask; |
| 62 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { | 63 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { |
| 63 | resethookcount(L); | 64 | resethookcount(L); |
| 64 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | 65 | luaD_callhook(L, LUA_HOOKCOUNT, -1); |
| 65 | } | 66 | } |
| 66 | if (mask & LUA_MASKLINE) { | 67 | if (mask & LUA_MASKLINE) { |
| 67 | Proto *p = ci_func(L->ci)->l.p; | 68 | Proto *p = ci_func(ci)->l.p; |
| 68 | int npc = pcRel(L->savedpc, p); | 69 | int npc = pcRel(ci->u.l.savedpc, p); |
| 69 | int newline = getline(p, npc); | 70 | int newline = getline(p, npc); |
| 70 | if (npc == 0 || /* call linehook when enter a new function, */ | 71 | if (npc == 0 || /* call linehook when enter a new function, */ |
| 71 | L->savedpc <= L->oldpc || /* when jump back (loop), or when */ | 72 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ |
| 72 | newline != getline(p, pcRel(L->oldpc, p))) /* enter a new line */ | 73 | newline != getline(p, pcRel(L->oldpc, p))) /* enter a new line */ |
| 73 | luaD_callhook(L, LUA_HOOKLINE, newline); | 74 | luaD_callhook(L, LUA_HOOKLINE, newline); |
| 74 | } | 75 | } |
| 75 | L->oldpc = L->savedpc; | 76 | L->oldpc = ci->u.l.savedpc; |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | 79 | ||
| @@ -357,7 +358,8 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb, | |||
| 357 | ** finish execution of an opcode interrupted by an yield | 358 | ** finish execution of an opcode interrupted by an yield |
| 358 | */ | 359 | */ |
| 359 | void luaV_finishOp (lua_State *L) { | 360 | void luaV_finishOp (lua_State *L) { |
| 360 | Instruction inst = *(L->savedpc - 1); /* interrupted instruction */ | 361 | CallInfo *ci = L->ci; |
| 362 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | ||
| 361 | switch (GET_OPCODE(inst)) { /* finish its execution */ | 363 | switch (GET_OPCODE(inst)) { /* finish its execution */ |
| 362 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: | 364 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: |
| 363 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 365 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: |
| @@ -373,9 +375,9 @@ void luaV_finishOp (lua_State *L) { | |||
| 373 | if (GET_OPCODE(inst) == OP_LE && /* "<=" using "<" instead? */ | 375 | if (GET_OPCODE(inst) == OP_LE && /* "<=" using "<" instead? */ |
| 374 | ttisnil(luaT_gettmbyobj(L, L->base + GETARG_B(inst), TM_LE))) | 376 | ttisnil(luaT_gettmbyobj(L, L->base + GETARG_B(inst), TM_LE))) |
| 375 | res = !res; /* invert result */ | 377 | res = !res; /* invert result */ |
| 376 | lua_assert(GET_OPCODE(*L->savedpc) == OP_JMP); | 378 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); |
| 377 | if (res != GETARG_A(inst)) /* condition failed? */ | 379 | if (res != GETARG_A(inst)) /* condition failed? */ |
| 378 | L->savedpc++; /* skip jump instruction */ | 380 | ci->u.l.savedpc++; /* skip jump instruction */ |
| 379 | break; | 381 | break; |
| 380 | } | 382 | } |
| 381 | case OP_CONCAT: { | 383 | case OP_CONCAT: { |
| @@ -384,7 +386,7 @@ void luaV_finishOp (lua_State *L) { | |||
| 384 | int b = GETARG_B(inst); /* ... first element to concatenate */ | 386 | int b = GETARG_B(inst); /* ... first element to concatenate */ |
| 385 | int total = last - b + 1; /* number of elements to concatenate */ | 387 | int total = last - b + 1; /* number of elements to concatenate */ |
| 386 | setobj2s(L, top - 2, top); /* put TM result in proper position */ | 388 | setobj2s(L, top - 2, top); /* put TM result in proper position */ |
| 387 | L->top = L->ci->top; /* correct top */ | 389 | L->top = ci->top; /* correct top */ |
| 388 | if (total > 1) /* are there elements to concat? */ | 390 | if (total > 1) /* are there elements to concat? */ |
| 389 | luaV_concat(L, total, last); /* concat them (may yield again) */ | 391 | luaV_concat(L, total, last); /* concat them (may yield again) */ |
| 390 | /* move final result to final position */ | 392 | /* move final result to final position */ |
| @@ -392,13 +394,13 @@ void luaV_finishOp (lua_State *L) { | |||
| 392 | break; | 394 | break; |
| 393 | } | 395 | } |
| 394 | case OP_TFORCALL: { | 396 | case OP_TFORCALL: { |
| 395 | lua_assert(GET_OPCODE(*L->savedpc) == OP_TFORLOOP); | 397 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); |
| 396 | L->top = L->ci->top; /* correct top */ | 398 | L->top = ci->top; /* correct top */ |
| 397 | break; | 399 | break; |
| 398 | } | 400 | } |
| 399 | case OP_CALL: { | 401 | case OP_CALL: { |
| 400 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ | 402 | if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ |
| 401 | L->top = L->ci->top; /* adjust results */ | 403 | L->top = ci->top; /* adjust results */ |
| 402 | break; | 404 | break; |
| 403 | } | 405 | } |
| 404 | case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE: | 406 | case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE: |
| @@ -413,8 +415,6 @@ void luaV_finishOp (lua_State *L) { | |||
| 413 | ** some macros for common tasks in `luaV_execute' | 415 | ** some macros for common tasks in `luaV_execute' |
| 414 | */ | 416 | */ |
| 415 | 417 | ||
| 416 | #define runtime_check(L, c) { if (!(c)) break; } | ||
| 417 | |||
| 418 | #define RA(i) (base+GETARG_A(i)) | 418 | #define RA(i) (base+GETARG_A(i)) |
| 419 | /* to be used after possible stack reallocation */ | 419 | /* to be used after possible stack reallocation */ |
| 420 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) | 420 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) |
| @@ -426,10 +426,10 @@ void luaV_finishOp (lua_State *L) { | |||
| 426 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) | 426 | #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) |
| 427 | 427 | ||
| 428 | 428 | ||
| 429 | #define dojump(L,i) { L->savedpc += (i); luai_threadyield(L);} | 429 | #define dojump(i) { ci->u.l.savedpc += (i); luai_threadyield(L);} |
| 430 | 430 | ||
| 431 | 431 | ||
| 432 | #define Protect(x) { {x;}; base = L->base; } | 432 | #define Protect(x) { {x;}; base = ci->base; } |
| 433 | 433 | ||
| 434 | 434 | ||
| 435 | #define arith_op(op,tm) { \ | 435 | #define arith_op(op,tm) { \ |
| @@ -446,32 +446,29 @@ void luaV_finishOp (lua_State *L) { | |||
| 446 | 446 | ||
| 447 | 447 | ||
| 448 | void luaV_execute (lua_State *L) { | 448 | void luaV_execute (lua_State *L) { |
| 449 | LClosure *cl; | 449 | CallInfo *ci = L->ci; |
| 450 | StkId base; | 450 | LClosure *cl = &clvalue(ci->func)->l; |
| 451 | TValue *k; | 451 | TValue *k = cl->p->k; |
| 452 | reentry: /* entry point */ | 452 | StkId base = ci->base; |
| 453 | lua_assert(isLua(L->ci)); | 453 | lua_assert(isLua(ci)); |
| 454 | cl = &curr_func(L)->l; | ||
| 455 | base = L->base; | ||
| 456 | k = cl->p->k; | ||
| 457 | /* main loop of interpreter */ | 454 | /* main loop of interpreter */ |
| 458 | for (;;) { | 455 | for (;;) { |
| 459 | Instruction i = *(L->savedpc++); | 456 | Instruction i = *(ci->u.l.savedpc++); |
| 460 | StkId ra; | 457 | StkId ra; |
| 461 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && | 458 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
| 462 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | 459 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
| 463 | traceexec(L); | 460 | traceexec(L); |
| 464 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 461 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
| 465 | L->savedpc--; /* undo increment */ | 462 | ci->u.l.savedpc--; /* undo increment */ |
| 466 | luaD_throw(L, LUA_YIELD); | 463 | luaD_throw(L, LUA_YIELD); |
| 467 | } | 464 | } |
| 468 | base = L->base; | 465 | base = ci->base; |
| 469 | } | 466 | } |
| 470 | /* warning!! several calls may realloc the stack and invalidate `ra' */ | 467 | /* warning!! several calls may realloc the stack and invalidate `ra' */ |
| 471 | ra = RA(i); | 468 | ra = RA(i); |
| 472 | lua_assert(base == L->base && L->base == L->ci->base); | 469 | lua_assert(base == ci->base && base == L->base); |
| 473 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); | 470 | lua_assert(base <= L->top && L->top <= L->stack + L->stacksize); |
| 474 | lua_assert(L->top == L->ci->top || luaG_checkopenop(i)); | 471 | lua_assert(L->top == ci->top || luaG_checkopenop(i)); |
| 475 | switch (GET_OPCODE(i)) { | 472 | switch (GET_OPCODE(i)) { |
| 476 | case OP_MOVE: { | 473 | case OP_MOVE: { |
| 477 | setobjs2s(L, ra, RB(i)); | 474 | setobjs2s(L, ra, RB(i)); |
| @@ -483,7 +480,7 @@ void luaV_execute (lua_State *L) { | |||
| 483 | } | 480 | } |
| 484 | case OP_LOADBOOL: { | 481 | case OP_LOADBOOL: { |
| 485 | setbvalue(ra, GETARG_B(i)); | 482 | setbvalue(ra, GETARG_B(i)); |
| 486 | if (GETARG_C(i)) L->savedpc++; /* skip next instruction (if C) */ | 483 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
| 487 | continue; | 484 | continue; |
| 488 | } | 485 | } |
| 489 | case OP_LOADNIL: { | 486 | case OP_LOADNIL: { |
| @@ -595,7 +592,7 @@ void luaV_execute (lua_State *L) { | |||
| 595 | continue; | 592 | continue; |
| 596 | } | 593 | } |
| 597 | case OP_JMP: { | 594 | case OP_JMP: { |
| 598 | dojump(L, GETARG_sBx(i)); | 595 | dojump(GETARG_sBx(i)); |
| 599 | continue; | 596 | continue; |
| 600 | } | 597 | } |
| 601 | case OP_EQ: { | 598 | case OP_EQ: { |
| @@ -603,40 +600,40 @@ void luaV_execute (lua_State *L) { | |||
| 603 | TValue *rc = RKC(i); | 600 | TValue *rc = RKC(i); |
| 604 | Protect( | 601 | Protect( |
| 605 | if (equalobj(L, rb, rc) == GETARG_A(i)) | 602 | if (equalobj(L, rb, rc) == GETARG_A(i)) |
| 606 | dojump(L, GETARG_sBx(*L->savedpc)); | 603 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 607 | ) | 604 | ) |
| 608 | L->savedpc++; | 605 | ci->u.l.savedpc++; |
| 609 | continue; | 606 | continue; |
| 610 | } | 607 | } |
| 611 | case OP_LT: { | 608 | case OP_LT: { |
| 612 | Protect( | 609 | Protect( |
| 613 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | 610 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) |
| 614 | dojump(L, GETARG_sBx(*L->savedpc)); | 611 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 615 | ) | 612 | ) |
| 616 | L->savedpc++; | 613 | ci->u.l.savedpc++; |
| 617 | continue; | 614 | continue; |
| 618 | } | 615 | } |
| 619 | case OP_LE: { | 616 | case OP_LE: { |
| 620 | Protect( | 617 | Protect( |
| 621 | if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | 618 | if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) |
| 622 | dojump(L, GETARG_sBx(*L->savedpc)); | 619 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 623 | ) | 620 | ) |
| 624 | L->savedpc++; | 621 | ci->u.l.savedpc++; |
| 625 | continue; | 622 | continue; |
| 626 | } | 623 | } |
| 627 | case OP_TEST: { | 624 | case OP_TEST: { |
| 628 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) | 625 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) |
| 629 | dojump(L, GETARG_sBx(*L->savedpc)); | 626 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 630 | L->savedpc++; | 627 | ci->u.l.savedpc++; |
| 631 | continue; | 628 | continue; |
| 632 | } | 629 | } |
| 633 | case OP_TESTSET: { | 630 | case OP_TESTSET: { |
| 634 | TValue *rb = RB(i); | 631 | TValue *rb = RB(i); |
| 635 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { | 632 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { |
| 636 | setobjs2s(L, ra, rb); | 633 | setobjs2s(L, ra, rb); |
| 637 | dojump(L, GETARG_sBx(*L->savedpc)); | 634 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 638 | } | 635 | } |
| 639 | L->savedpc++; | 636 | ci->u.l.savedpc++; |
| 640 | continue; | 637 | continue; |
| 641 | } | 638 | } |
| 642 | case OP_CALL: { | 639 | case OP_CALL: { |
| @@ -644,13 +641,14 @@ void luaV_execute (lua_State *L) { | |||
| 644 | int nresults = GETARG_C(i) - 1; | 641 | int nresults = GETARG_C(i) - 1; |
| 645 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 642 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 646 | if (luaD_precall(L, ra, nresults)) { /* C function? */ | 643 | if (luaD_precall(L, ra, nresults)) { /* C function? */ |
| 647 | if (nresults >= 0) L->top = L->ci->top; /* adjust results */ | 644 | if (nresults >= 0) L->top = ci->top; /* adjust results */ |
| 648 | base = L->base; | 645 | base = ci->base; |
| 649 | continue; | 646 | continue; |
| 650 | } | 647 | } |
| 651 | else { /* Lua function */ | 648 | else { /* Lua function */ |
| 652 | L->ci->callstatus |= CIST_REENTRY; | 649 | ci = L->ci; |
| 653 | goto reentry; /* restart luaV_execute over new Lua function */ | 650 | ci->callstatus |= CIST_REENTRY; |
| 651 | break; /* restart luaV_execute over new Lua function */ | ||
| 654 | } | 652 | } |
| 655 | } | 653 | } |
| 656 | case OP_TAILCALL: { | 654 | case OP_TAILCALL: { |
| @@ -658,25 +656,26 @@ void luaV_execute (lua_State *L) { | |||
| 658 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 656 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 659 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 657 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
| 660 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ | 658 | if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ |
| 661 | base = L->base; | 659 | base = ci->base; |
| 662 | continue; | 660 | continue; |
| 663 | } | 661 | } |
| 664 | else { | 662 | else { |
| 665 | /* tail call: put new frame in place of previous one */ | 663 | /* tail call: put called frame (n) in place of caller one (o) */ |
| 666 | StkId pfunc = L->ci->func; /* called function index */ | 664 | CallInfo *nci = L->ci; /* called frame */ |
| 667 | CallInfo *ci = L->ci->previous; /* caller frame */ | 665 | CallInfo *oci = nci->previous; /* caller frame */ |
| 668 | StkId func = ci->func; | 666 | StkId nfunc = nci->func; /* called function index */ |
| 667 | StkId ofunc = oci->func; | ||
| 669 | int aux; | 668 | int aux; |
| 670 | if (cl->p->sizep > 0) luaF_close(L, ci->base); | 669 | if (cl->p->sizep > 0) luaF_close(L, oci->base); |
| 671 | L->base = ci->base = ci->func + (L->ci->base - pfunc); | 670 | L->base = oci->base = ofunc + (nci->base - nfunc); |
| 672 | for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ | 671 | for (aux = 0; nfunc+aux < L->top; aux++) /* move frame down */ |
| 673 | setobjs2s(L, func+aux, pfunc+aux); | 672 | setobjs2s(L, ofunc + aux, nfunc + aux); |
| 674 | ci->top = L->top = func+aux; /* correct top */ | 673 | oci->top = L->top = ofunc + aux; /* correct top */ |
| 675 | lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); | 674 | lua_assert(L->top == L->base + clvalue(ofunc)->l.p->maxstacksize); |
| 676 | ci->savedpc = L->savedpc; | 675 | oci->u.l.savedpc = nci->u.l.savedpc; |
| 677 | ci->u.l.tailcalls++; /* one more call lost */ | 676 | oci->u.l.tailcalls++; /* one more call lost */ |
| 678 | L->ci = ci; /* remove new frame */ | 677 | ci = L->ci = oci; /* remove new frame */ |
| 679 | goto reentry; | 678 | break; /* restart luaV_execute over new Lua function */ |
| 680 | } | 679 | } |
| 681 | } | 680 | } |
| 682 | case OP_RETURN: { | 681 | case OP_RETURN: { |
| @@ -684,13 +683,14 @@ void luaV_execute (lua_State *L) { | |||
| 684 | if (b != 0) L->top = ra+b-1; | 683 | if (b != 0) L->top = ra+b-1; |
| 685 | if (cl->p->sizep > 0) luaF_close(L, base); | 684 | if (cl->p->sizep > 0) luaF_close(L, base); |
| 686 | b = luaD_poscall(L, ra); | 685 | b = luaD_poscall(L, ra); |
| 687 | if (!(L->ci->next->callstatus & CIST_REENTRY)) | 686 | if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ |
| 688 | return; /* external invocation: return */ | 687 | return; /* external invocation: return */ |
| 689 | else { /* invocation via reentry: continue execution */ | 688 | else { /* invocation via reentry: continue execution */ |
| 690 | if (b) L->top = L->ci->top; | 689 | ci = L->ci; |
| 691 | lua_assert(isLua(L->ci)); | 690 | if (b) L->top = ci->top; |
| 692 | lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL); | 691 | lua_assert(isLua(ci)); |
| 693 | goto reentry; | 692 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); |
| 693 | break; /* restart luaV_execute over new Lua function */ | ||
| 694 | } | 694 | } |
| 695 | } | 695 | } |
| 696 | case OP_FORLOOP: { | 696 | case OP_FORLOOP: { |
| @@ -699,7 +699,7 @@ void luaV_execute (lua_State *L) { | |||
| 699 | lua_Number limit = nvalue(ra+1); | 699 | lua_Number limit = nvalue(ra+1); |
| 700 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) | 700 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) |
| 701 | : luai_numle(L, limit, idx)) { | 701 | : luai_numle(L, limit, idx)) { |
| 702 | dojump(L, GETARG_sBx(i)); /* jump back */ | 702 | dojump(GETARG_sBx(i)); /* jump back */ |
| 703 | setnvalue(ra, idx); /* update internal index... */ | 703 | setnvalue(ra, idx); /* update internal index... */ |
| 704 | setnvalue(ra+3, idx); /* ...and external index */ | 704 | setnvalue(ra+3, idx); /* ...and external index */ |
| 705 | } | 705 | } |
| @@ -716,7 +716,7 @@ void luaV_execute (lua_State *L) { | |||
| 716 | else if (!tonumber(pstep, ra+2)) | 716 | else if (!tonumber(pstep, ra+2)) |
| 717 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | 717 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
| 718 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); | 718 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); |
| 719 | dojump(L, GETARG_sBx(i)); | 719 | dojump(GETARG_sBx(i)); |
| 720 | continue; | 720 | continue; |
| 721 | } | 721 | } |
| 722 | case OP_TFORCALL: { | 722 | case OP_TFORCALL: { |
| @@ -726,8 +726,8 @@ void luaV_execute (lua_State *L) { | |||
| 726 | setobjs2s(L, cb, ra); | 726 | setobjs2s(L, cb, ra); |
| 727 | L->top = cb + 3; /* func. + 2 args (state and index) */ | 727 | L->top = cb + 3; /* func. + 2 args (state and index) */ |
| 728 | Protect(luaD_call(L, cb, GETARG_C(i), 1)); | 728 | Protect(luaD_call(L, cb, GETARG_C(i), 1)); |
| 729 | L->top = L->ci->top; | 729 | L->top = ci->top; |
| 730 | i = *(L->savedpc++); /* go to next instruction */ | 730 | i = *(ci->u.l.savedpc++); /* go to next instruction */ |
| 731 | ra = RA(i); | 731 | ra = RA(i); |
| 732 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); | 732 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
| 733 | /* go through */ | 733 | /* go through */ |
| @@ -735,7 +735,7 @@ void luaV_execute (lua_State *L) { | |||
| 735 | case OP_TFORLOOP: { | 735 | case OP_TFORLOOP: { |
| 736 | if (!ttisnil(ra + 1)) { /* continue loop? */ | 736 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
| 737 | setobjs2s(L, ra, ra + 1); /* save control variable */ | 737 | setobjs2s(L, ra, ra + 1); /* save control variable */ |
| 738 | dojump(L, GETARG_sBx(i)); /* jump back */ | 738 | dojump(GETARG_sBx(i)); /* jump back */ |
| 739 | } | 739 | } |
| 740 | continue; | 740 | continue; |
| 741 | } | 741 | } |
| @@ -746,10 +746,9 @@ void luaV_execute (lua_State *L) { | |||
| 746 | Table *h; | 746 | Table *h; |
| 747 | if (n == 0) n = cast_int(L->top - ra) - 1; | 747 | if (n == 0) n = cast_int(L->top - ra) - 1; |
| 748 | if (c == 0) { | 748 | if (c == 0) { |
| 749 | lua_assert(GET_OPCODE(*L->savedpc) == OP_EXTRAARG); | 749 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); |
| 750 | c = GETARG_Ax(*L->savedpc++); | 750 | c = GETARG_Ax(*ci->u.l.savedpc++); |
| 751 | } | 751 | } |
| 752 | runtime_check(L, ttistable(ra)); | ||
| 753 | h = hvalue(ra); | 752 | h = hvalue(ra); |
| 754 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 753 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
| 755 | if (last > h->sizearray) /* needs more space? */ | 754 | if (last > h->sizearray) /* needs more space? */ |
| @@ -759,7 +758,7 @@ void luaV_execute (lua_State *L) { | |||
| 759 | setobj2t(L, luaH_setnum(L, h, last--), val); | 758 | setobj2t(L, luaH_setnum(L, h, last--), val); |
| 760 | luaC_barriert(L, h, val); | 759 | luaC_barriert(L, h, val); |
| 761 | } | 760 | } |
| 762 | L->top = L->ci->top; /* correct top (in case of previous open call) */ | 761 | L->top = ci->top; /* correct top (in case of previous open call) */ |
| 763 | continue; | 762 | continue; |
| 764 | } | 763 | } |
| 765 | case OP_CLOSE: { | 764 | case OP_CLOSE: { |
| @@ -776,7 +775,7 @@ void luaV_execute (lua_State *L) { | |||
| 776 | ncl->l.p = p; | 775 | ncl->l.p = p; |
| 777 | setclvalue(L, ra, ncl); | 776 | setclvalue(L, ra, ncl); |
| 778 | for (j=0; j<nup; j++) { | 777 | for (j=0; j<nup; j++) { |
| 779 | Instruction u = *L->savedpc++; | 778 | Instruction u = *ci->u.l.savedpc++; |
| 780 | if (GET_OPCODE(u) == OP_GETUPVAL) | 779 | if (GET_OPCODE(u) == OP_GETUPVAL) |
| 781 | ncl->l.upvals[j] = cl->upvals[GETARG_B(u)]; | 780 | ncl->l.upvals[j] = cl->upvals[GETARG_B(u)]; |
| 782 | else { | 781 | else { |
| @@ -790,7 +789,6 @@ void luaV_execute (lua_State *L) { | |||
| 790 | case OP_VARARG: { | 789 | case OP_VARARG: { |
| 791 | int b = GETARG_B(i) - 1; | 790 | int b = GETARG_B(i) - 1; |
| 792 | int j; | 791 | int j; |
| 793 | CallInfo *ci = L->ci; | ||
| 794 | int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; | 792 | int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1; |
| 795 | if (b == LUA_MULTRET) { | 793 | if (b == LUA_MULTRET) { |
| 796 | Protect(luaD_checkstack(L, n)); | 794 | Protect(luaD_checkstack(L, n)); |
| @@ -813,6 +811,11 @@ void luaV_execute (lua_State *L) { | |||
| 813 | return; | 811 | return; |
| 814 | } | 812 | } |
| 815 | } | 813 | } |
| 814 | /* function changed (call/return): update pointers */ | ||
| 815 | lua_assert(ci == L->ci); | ||
| 816 | cl = &clvalue(ci->func)->l; | ||
| 817 | k = cl->p->k; | ||
| 818 | base = ci->base; | ||
| 816 | } | 819 | } |
| 817 | } | 820 | } |
| 818 | 821 | ||
