diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-26 10:38:50 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-10-26 10:38:50 -0300 |
commit | 6e9b719694bffb8de711f182d405ec37d32ae0b1 (patch) | |
tree | 943fcd9aacd2f7845acfd955e1bb0a9607576fa4 /lparser.c | |
parent | 34840301b529686ce8168828b140a478a5d44b53 (diff) | |
download | lua-6e9b719694bffb8de711f182d405ec37d32ae0b1.tar.gz lua-6e9b719694bffb8de711f182d405ec37d32ae0b1.tar.bz2 lua-6e9b719694bffb8de711f182d405ec37d32ae0b1.zip |
More uniformity in code generation for 'for' loops
Added new instruction 'OP_TFORPREP' to prepare a generic for loop.
Currently it is equivalent to a jump (but with a format 'iABx',
similar to other for-loop preparing instructions), but soon it will
be the place to create upvalues for closing loop states.
Diffstat (limited to 'lparser.c')
-rw-r--r-- | lparser.c | 16 |
1 files changed, 6 insertions, 10 deletions
@@ -1350,30 +1350,26 @@ static void fixforjump (FuncState *fs, int pc, int dest, int back) { | |||
1350 | */ | 1350 | */ |
1351 | static void forbody (LexState *ls, int base, int line, int nvars, int kind) { | 1351 | static void forbody (LexState *ls, int base, int line, int nvars, int kind) { |
1352 | /* forbody -> DO block */ | 1352 | /* forbody -> DO block */ |
1353 | static OpCode forprep[3] = {OP_FORPREP, OP_FORPREP1, OP_TFORPREP}; | ||
1354 | static OpCode forloop[3] = {OP_FORLOOP, OP_FORLOOP1, OP_TFORLOOP}; | ||
1353 | BlockCnt bl; | 1355 | BlockCnt bl; |
1354 | FuncState *fs = ls->fs; | 1356 | FuncState *fs = ls->fs; |
1355 | int prep, endfor; | 1357 | int prep, endfor; |
1356 | adjustlocalvars(ls, 3); /* control variables */ | 1358 | adjustlocalvars(ls, 3); /* control variables */ |
1357 | checknext(ls, TK_DO); | 1359 | checknext(ls, TK_DO); |
1358 | prep = (kind == 0) ? luaK_codeABx(fs, OP_FORPREP, base, 0) | 1360 | prep = luaK_codeABx(fs, forprep[kind], base, 0); |
1359 | : (kind == 1) ? luaK_codeABx(fs, OP_FORPREP1, base, 0) | ||
1360 | : luaK_jump(fs); | ||
1361 | enterblock(fs, &bl, 0); /* scope for declared variables */ | 1361 | enterblock(fs, &bl, 0); /* scope for declared variables */ |
1362 | adjustlocalvars(ls, nvars); | 1362 | adjustlocalvars(ls, nvars); |
1363 | luaK_reserveregs(fs, nvars); | 1363 | luaK_reserveregs(fs, nvars); |
1364 | block(ls); | 1364 | block(ls); |
1365 | leaveblock(fs); /* end of scope for declared variables */ | 1365 | leaveblock(fs); /* end of scope for declared variables */ |
1366 | fixforjump(fs, prep, luaK_getlabel(fs), 0); | ||
1366 | if (kind == 2) { /* generic for? */ | 1367 | if (kind == 2) { /* generic for? */ |
1367 | luaK_patchtohere(fs, prep); | ||
1368 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); | 1368 | luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); |
1369 | luaK_fixline(fs, line); | 1369 | luaK_fixline(fs, line); |
1370 | endfor = luaK_codeABx(fs, OP_TFORLOOP, base + 2, 0); | 1370 | base += 2; /* base for 'OP_TFORLOOP' (skips function and state) */ |
1371 | } | ||
1372 | else { | ||
1373 | fixforjump(fs, prep, luaK_getlabel(fs), 0); | ||
1374 | endfor = (kind == 0) ? luaK_codeABx(fs, OP_FORLOOP, base, 0) | ||
1375 | : luaK_codeABx(fs, OP_FORLOOP1, base, 0); | ||
1376 | } | 1371 | } |
1372 | endfor = luaK_codeABx(fs, forloop[kind], base, 0); | ||
1377 | fixforjump(fs, endfor, prep + 1, 1); | 1373 | fixforjump(fs, endfor, prep + 1, 1); |
1378 | luaK_fixline(fs, line); | 1374 | luaK_fixline(fs, line); |
1379 | } | 1375 | } |