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