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 | ||