diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2008-10-30 13:39:30 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2008-10-30 13:39:30 -0200 |
| commit | 84b3daebbd09b334db0fa125700ffdb1d326c4f6 (patch) | |
| tree | dc99189c46297759609894ac71f75d4a57c854fa | |
| parent | f6978173e03fdbe5536887b08beb53884f7c1a18 (diff) | |
| download | lua-84b3daebbd09b334db0fa125700ffdb1d326c4f6.tar.gz lua-84b3daebbd09b334db0fa125700ffdb1d326c4f6.tar.bz2 lua-84b3daebbd09b334db0fa125700ffdb1d326c4f6.zip | |
generic for coded as two dedicated instructions to simplify resumption
| -rw-r--r-- | ldebug.c | 6 | ||||
| -rw-r--r-- | ldo.c | 18 | ||||
| -rw-r--r-- | lopcodes.c | 8 | ||||
| -rw-r--r-- | lopcodes.h | 9 | ||||
| -rw-r--r-- | lparser.c | 15 | ||||
| -rw-r--r-- | lvm.c | 26 |
6 files changed, 43 insertions, 39 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.40 2008/07/03 14:24:11 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.41 2008/08/26 13:27:42 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 | */ |
| @@ -388,12 +388,14 @@ static Instruction symbexec (const Proto *pt, int lastpc, int reg) { | |||
| 388 | check(b < c); /* at least two operands */ | 388 | check(b < c); /* at least two operands */ |
| 389 | break; | 389 | break; |
| 390 | } | 390 | } |
| 391 | case OP_TFORLOOP: { | 391 | case OP_TFORCALL: { |
| 392 | check(c >= 1); /* at least one result (control variable) */ | 392 | check(c >= 1); /* at least one result (control variable) */ |
| 393 | checkreg(pt, a+2+c); /* space for results */ | 393 | checkreg(pt, a+2+c); /* space for results */ |
| 394 | check(GET_OPCODE(pt->code[pc+1]) == OP_TFORLOOP); | ||
| 394 | if (reg >= a+2) last = pc; /* affect all regs above its base */ | 395 | if (reg >= a+2) last = pc; /* affect all regs above its base */ |
| 395 | break; | 396 | break; |
| 396 | } | 397 | } |
| 398 | case OP_TFORLOOP: | ||
| 397 | case OP_FORLOOP: | 399 | case OP_FORLOOP: |
| 398 | case OP_FORPREP: | 400 | case OP_FORPREP: |
| 399 | checkreg(pt, a+3); | 401 | checkreg(pt, a+3); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.48 2008/08/26 13:27:42 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.49 2008/10/28 16:53:16 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 | */ |
| @@ -391,8 +391,10 @@ static void unroll (lua_State *L) { | |||
| 391 | for (;;) { | 391 | for (;;) { |
| 392 | Instruction inst; | 392 | Instruction inst; |
| 393 | luaV_execute(L); /* execute up to higher C 'boundary' */ | 393 | luaV_execute(L); /* execute up to higher C 'boundary' */ |
| 394 | if (L->ci == L->base_ci) /* stack is empty? */ | 394 | if (L->ci == L->base_ci) { /* stack is empty? */ |
| 395 | lua_assert(L->baseCcalls == G(L)->nCcalls); | ||
| 395 | return; /* coroutine finished normally */ | 396 | return; /* coroutine finished normally */ |
| 397 | } | ||
| 396 | L->baseCcalls--; /* undo increment that allows yields */ | 398 | L->baseCcalls--; /* undo increment that allows yields */ |
| 397 | inst = *(L->savedpc - 1); /* interrupted instruction */ | 399 | inst = *(L->savedpc - 1); /* interrupted instruction */ |
| 398 | switch (GET_OPCODE(inst)) { /* finish its execution */ | 400 | switch (GET_OPCODE(inst)) { /* finish its execution */ |
| @@ -419,15 +421,9 @@ static void unroll (lua_State *L) { | |||
| 419 | } | 421 | } |
| 420 | case OP_SETGLOBAL: case OP_SETTABLE: | 422 | case OP_SETGLOBAL: case OP_SETTABLE: |
| 421 | break; /* nothing to be done */ | 423 | break; /* nothing to be done */ |
| 422 | case OP_TFORLOOP: { | 424 | case OP_TFORCALL: { |
| 423 | StkId cb = L->base + GETARG_A(inst) + 3; | 425 | lua_assert(GET_OPCODE(*L->savedpc) == OP_TFORLOOP); |
| 424 | L->top = L->ci->top; | 426 | L->top = L->ci->top; /* correct top */ |
| 425 | lua_assert(GET_OPCODE(*L->savedpc) == OP_JMP); | ||
| 426 | if (!ttisnil(cb)) { /* continue loop? */ | ||
| 427 | setobjs2s(L, cb - 1, cb); /* save control variable */ | ||
| 428 | L->savedpc += GETARG_sBx(*L->savedpc); /* jump back */ | ||
| 429 | } | ||
| 430 | L->savedpc++; | ||
| 431 | break; | 427 | break; |
| 432 | } | 428 | } |
| 433 | default: lua_assert(0); | 429 | default: lua_assert(0); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.c,v 1.38 2006/09/11 14:07:24 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.39 2008/04/02 16:16:06 roberto Exp roberto $ |
| 3 | ** See Copyright Notice in lua.h | 3 | ** See Copyright Notice in lua.h |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| @@ -47,11 +47,12 @@ const char *const luaP_opnames[NUM_OPCODES+1] = { | |||
| 47 | "RETURN", | 47 | "RETURN", |
| 48 | "FORLOOP", | 48 | "FORLOOP", |
| 49 | "FORPREP", | 49 | "FORPREP", |
| 50 | "TFORLOOP", | 50 | "TFORCALL", |
| 51 | "SETLIST", | 51 | "SETLIST", |
| 52 | "CLOSE", | 52 | "CLOSE", |
| 53 | "CLOSURE", | 53 | "CLOSURE", |
| 54 | "VARARG", | 54 | "VARARG", |
| 55 | "TFORLOOP", | ||
| 55 | "EXTRAARG", | 56 | "EXTRAARG", |
| 56 | NULL | 57 | NULL |
| 57 | }; | 58 | }; |
| @@ -94,11 +95,12 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
| 94 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ | 95 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ |
| 95 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ | 96 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ |
| 96 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ | 97 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ |
| 97 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */ | 98 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ |
| 98 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ | 99 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ |
| 99 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ | 100 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ |
| 100 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ | 101 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ |
| 101 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ | 102 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ |
| 103 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ | ||
| 102 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ | 104 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ |
| 103 | }; | 105 | }; |
| 104 | 106 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.126 2006/09/11 14:07:24 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.127 2008/04/02 16:16:06 roberto Exp roberto $ |
| 3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -211,8 +211,7 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2); | |||
| 211 | if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ | 211 | if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ |
| 212 | OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ | 212 | OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ |
| 213 | 213 | ||
| 214 | OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); | 214 | OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */ |
| 215 | if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */ | ||
| 216 | OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ | 215 | OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ |
| 217 | 216 | ||
| 218 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ | 217 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ |
| @@ -220,6 +219,8 @@ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */ | |||
| 220 | 219 | ||
| 221 | OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ | 220 | OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ |
| 222 | 221 | ||
| 222 | OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ | ||
| 223 | |||
| 223 | OP_EXTRAARG/* Ax extra argument for previous opcode */ | 224 | OP_EXTRAARG/* Ax extra argument for previous opcode */ |
| 224 | } OpCode; | 225 | } OpCode; |
| 225 | 226 | ||
| @@ -255,7 +256,7 @@ OP_EXTRAARG/* Ax extra argument for previous opcode */ | |||
| 255 | ** bits 2-3: C arg mode | 256 | ** bits 2-3: C arg mode |
| 256 | ** bits 4-5: B arg mode | 257 | ** bits 4-5: B arg mode |
| 257 | ** bit 6: instruction set register A | 258 | ** bit 6: instruction set register A |
| 258 | ** bit 7: operator is a test | 259 | ** bit 7: operator is a test (next instruction must be a jump) |
| 259 | */ | 260 | */ |
| 260 | 261 | ||
| 261 | enum OpArgMask { | 262 | enum OpArgMask { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.58 2008/05/08 15:44:51 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.59 2008/10/28 12:55:00 roberto Exp roberto $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -1055,7 +1055,7 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { | |||
| 1055 | /* forbody -> DO block */ | 1055 | /* forbody -> DO block */ |
| 1056 | BlockCnt bl; | 1056 | BlockCnt bl; |
| 1057 | FuncState *fs = ls->fs; | 1057 | FuncState *fs = ls->fs; |
| 1058 | int prep; | 1058 | int prep, endfor; |
| 1059 | adjustlocalvars(ls, 3); /* control variables */ | 1059 | adjustlocalvars(ls, 3); /* control variables */ |
| 1060 | checknext(ls, TK_DO); | 1060 | checknext(ls, TK_DO); |
| 1061 | prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); | 1061 | prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); |
| @@ -1065,15 +1065,14 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { | |||
| 1065 | block(ls); | 1065 | block(ls); |
| 1066 | leaveblock(fs); /* end of scope for declared variables */ | 1066 | leaveblock(fs); /* end of scope for declared variables */ |
| 1067 | luaK_patchtohere(fs, prep); | 1067 | luaK_patchtohere(fs, prep); |
| 1068 | if (isnum) { /* numeric for? */ | 1068 | if (isnum) /* numeric for? */ |
| 1069 | int endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); | 1069 | endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); |
| 1070 | luaK_patchlist(fs, endfor, prep + 1); | ||
| 1071 | } | ||
| 1072 | else { /* generic for */ | 1070 | else { /* generic for */ |
| 1073 | luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars); | 1071 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); |
| 1074 | luaK_fixline(fs, line); | 1072 | luaK_fixline(fs, line); |
| 1075 | luaK_jumpto(fs, prep + 1); | 1073 | endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); |
| 1076 | } | 1074 | } |
| 1075 | luaK_patchlist(fs, endfor, prep + 1); | ||
| 1077 | luaK_fixline(fs, line); | 1076 | luaK_fixline(fs, line); |
| 1078 | } | 1077 | } |
| 1079 | 1078 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.77 2008/09/09 13:53:02 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.78 2008/10/28 16:53:16 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 | */ |
| @@ -404,7 +404,7 @@ void luaV_execute (lua_State *L) { | |||
| 404 | k = cl->p->k; | 404 | k = cl->p->k; |
| 405 | /* main loop of interpreter */ | 405 | /* main loop of interpreter */ |
| 406 | for (;;) { | 406 | for (;;) { |
| 407 | const Instruction i = *(L->savedpc++); | 407 | Instruction i = *(L->savedpc++); |
| 408 | StkId ra; | 408 | StkId ra; |
| 409 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && | 409 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
| 410 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | 410 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
| @@ -667,22 +667,26 @@ void luaV_execute (lua_State *L) { | |||
| 667 | dojump(L, GETARG_sBx(i)); | 667 | dojump(L, GETARG_sBx(i)); |
| 668 | continue; | 668 | continue; |
| 669 | } | 669 | } |
| 670 | case OP_TFORLOOP: { | 670 | case OP_TFORCALL: { |
| 671 | StkId cb = ra + 3; /* call base */ | 671 | StkId cb = ra + 3; /* call base */ |
| 672 | setobjs2s(L, cb+2, ra+2); | 672 | setobjs2s(L, cb+2, ra+2); |
| 673 | setobjs2s(L, cb+1, ra+1); | 673 | setobjs2s(L, cb+1, ra+1); |
| 674 | setobjs2s(L, cb, ra); | 674 | setobjs2s(L, cb, ra); |
| 675 | L->top = cb+3; /* func. + 2 args (state and index) */ | 675 | L->baseCcalls++; /* allow yields */ |
| 676 | L->baseCcalls++; | 676 | L->top = cb + 3; /* func. + 2 args (state and index) */ |
| 677 | Protect(luaD_call(L, cb, GETARG_C(i))); | 677 | Protect(luaD_call(L, cb, GETARG_C(i))); |
| 678 | L->baseCcalls--; | ||
| 679 | L->top = L->ci->top; | 678 | L->top = L->ci->top; |
| 680 | cb = RA(i) + 3; /* previous call may change the stack */ | 679 | L->baseCcalls--; |
| 681 | if (!ttisnil(cb)) { /* continue loop? */ | 680 | i = *(L->savedpc++); /* go to next instruction */ |
| 682 | setobjs2s(L, cb-1, cb); /* save control variable */ | 681 | ra = RA(i); |
| 683 | dojump(L, GETARG_sBx(*L->savedpc)); /* jump back */ | 682 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
| 683 | /* go through */ | ||
| 684 | } | ||
| 685 | case OP_TFORLOOP: { | ||
| 686 | if (!ttisnil(ra + 1)) { /* continue loop? */ | ||
| 687 | setobjs2s(L, ra, ra + 1); /* save control variable */ | ||
| 688 | dojump(L, GETARG_sBx(i)); /* jump back */ | ||
| 684 | } | 689 | } |
| 685 | L->savedpc++; | ||
| 686 | continue; | 690 | continue; |
| 687 | } | 691 | } |
| 688 | case OP_SETLIST: { | 692 | case OP_SETLIST: { |
