diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-10-01 17:24:37 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-10-01 17:24:37 -0300 |
| commit | b2a580bdb1982e45bb37f95b78c2dafec6efa7a6 (patch) | |
| tree | 76de58214adff838a26346514a8a6fba459bde9b /lcode.c | |
| parent | 89f6a85f034b2535e43e421991098fa05a92cd60 (diff) | |
| download | lua-b2a580bdb1982e45bb37f95b78c2dafec6efa7a6.tar.gz lua-b2a580bdb1982e45bb37f95b78c2dafec6efa7a6.tar.bz2 lua-b2a580bdb1982e45bb37f95b78c2dafec6efa7a6.zip | |
Janitorial work
- Several details in 'lcode.c'
- A few more tests for code generation
- Bug in assert in 'lcode.c' ("=" x "==")
- Comments in 'lopcodes.h' and 'ltable.c'
Diffstat (limited to 'lcode.c')
| -rw-r--r-- | lcode.c | 61 |
1 files changed, 29 insertions, 32 deletions
| @@ -359,12 +359,12 @@ static void removelastlineinfo (FuncState *fs) { | |||
| 359 | Proto *f = fs->f; | 359 | Proto *f = fs->f; |
| 360 | int pc = fs->pc - 1; /* last instruction coded */ | 360 | int pc = fs->pc - 1; /* last instruction coded */ |
| 361 | if (f->lineinfo[pc] != ABSLINEINFO) { /* relative line info? */ | 361 | if (f->lineinfo[pc] != ABSLINEINFO) { /* relative line info? */ |
| 362 | fs->previousline -= f->lineinfo[pc]; /* last line saved */ | 362 | fs->previousline -= f->lineinfo[pc]; /* correct last line saved */ |
| 363 | fs->iwthabs--; | 363 | fs->iwthabs--; /* undo previous increment */ |
| 364 | } | 364 | } |
| 365 | else { /* absolute line information */ | 365 | else { /* absolute line information */ |
| 366 | lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == pc); | ||
| 366 | fs->nabslineinfo--; /* remove it */ | 367 | fs->nabslineinfo--; /* remove it */ |
| 367 | lua_assert(f->abslineinfo[fs->nabslineinfo].pc = pc); | ||
| 368 | fs->iwthabs = MAXIWTHABS + 1; /* force next line info to be absolute */ | 368 | fs->iwthabs = MAXIWTHABS + 1; /* force next line info to be absolute */ |
| 369 | } | 369 | } |
| 370 | } | 370 | } |
| @@ -626,12 +626,12 @@ static int nilK (FuncState *fs) { | |||
| 626 | 626 | ||
| 627 | 627 | ||
| 628 | /* | 628 | /* |
| 629 | ** Check whether 'i' can be stored in an 'sC' operand. | 629 | ** Check whether 'i' can be stored in an 'sC' operand. Equivalent to |
| 630 | ** Equivalent to (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) | 630 | ** (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) but without risk of |
| 631 | ** but without risk of overflows in the addition. | 631 | ** overflows in the hidden addition inside 'int2sC'. |
| 632 | */ | 632 | */ |
| 633 | static int fitsC (lua_Integer i) { | 633 | static int fitsC (lua_Integer i) { |
| 634 | return (-OFFSET_sC <= i && i <= MAXARG_C - OFFSET_sC); | 634 | return (l_castS2U(i) + OFFSET_sC <= cast_uint(MAXARG_C)); |
| 635 | } | 635 | } |
| 636 | 636 | ||
| 637 | 637 | ||
| @@ -1213,15 +1213,6 @@ static int isSCint (expdesc *e) { | |||
| 1213 | 1213 | ||
| 1214 | 1214 | ||
| 1215 | /* | 1215 | /* |
| 1216 | ** Check whether expression 'e' and its negation are literal integers | ||
| 1217 | ** in proper range to fit in register sC | ||
| 1218 | */ | ||
| 1219 | static int isSCintN (expdesc *e) { | ||
| 1220 | return luaK_isKint(e) && fitsC(e->u.ival) && fitsC(-e->u.ival); | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | |||
| 1224 | /* | ||
| 1225 | ** Check whether expression 'e' is a literal integer or float in | 1216 | ** Check whether expression 'e' is a literal integer or float in |
| 1226 | ** proper range to fit in a register (sB or sC). | 1217 | ** proper range to fit in a register (sB or sC). |
| 1227 | */ | 1218 | */ |
| @@ -1382,15 +1373,25 @@ static void codebini (FuncState *fs, OpCode op, | |||
| 1382 | } | 1373 | } |
| 1383 | 1374 | ||
| 1384 | 1375 | ||
| 1385 | /* Code binary operators negating the immediate operand for the | 1376 | /* Try to code a binary operator negating its second operand. |
| 1386 | ** opcode. For the metamethod, 'v2' must keep its original value. | 1377 | ** For the metamethod, 2nd operand must keep its original value. |
| 1387 | */ | 1378 | */ |
| 1388 | static void finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, | 1379 | static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, |
| 1389 | OpCode op, int line, TMS event) { | 1380 | OpCode op, int line, TMS event) { |
| 1390 | int v2 = cast_int(e2->u.ival); | 1381 | if (!luaK_isKint(e2)) |
| 1391 | finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event); | 1382 | return 0; /* not an integer constant */ |
| 1392 | /* correct metamethod argument */ | 1383 | else { |
| 1393 | SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2)); | 1384 | lua_Integer i2 = e2->u.ival; |
| 1385 | if (!(fitsC(i2) && fitsC(-i2))) | ||
| 1386 | return 0; /* not in the proper range */ | ||
| 1387 | else { /* operating a small integer constant */ | ||
| 1388 | int v2 = cast_int(i2); | ||
| 1389 | finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event); | ||
| 1390 | /* correct metamethod argument */ | ||
| 1391 | SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2)); | ||
| 1392 | return 1; /* successfully coded */ | ||
| 1393 | } | ||
| 1394 | } | ||
| 1394 | } | 1395 | } |
| 1395 | 1396 | ||
| 1396 | 1397 | ||
| @@ -1647,11 +1648,8 @@ void luaK_posfix (FuncState *fs, BinOpr opr, | |||
| 1647 | break; | 1648 | break; |
| 1648 | } | 1649 | } |
| 1649 | case OPR_SUB: { | 1650 | case OPR_SUB: { |
| 1650 | if (isSCintN(e2)) { /* subtracting a small integer constant? */ | 1651 | if (finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB)) |
| 1651 | /* code it as (r1 + -I) */ | 1652 | break; /* coded as (r1 + -I) */ |
| 1652 | finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB); | ||
| 1653 | break; | ||
| 1654 | } | ||
| 1655 | /* ELSE *//* FALLTHROUGH */ | 1653 | /* ELSE *//* FALLTHROUGH */ |
| 1656 | } | 1654 | } |
| 1657 | case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { | 1655 | case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: { |
| @@ -1667,16 +1665,15 @@ void luaK_posfix (FuncState *fs, BinOpr opr, | |||
| 1667 | swapexps(e1, e2); | 1665 | swapexps(e1, e2); |
| 1668 | codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); /* I << r2 */ | 1666 | codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL); /* I << r2 */ |
| 1669 | } | 1667 | } |
| 1670 | else if (isSCintN(e2)) { /* shifting by a small integer constant? */ | 1668 | else if (finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL)) { |
| 1671 | /* code it as (r1 >> -I) */ | 1669 | /* coded as (r1 >> -I) */; |
| 1672 | finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL); | ||
| 1673 | } | 1670 | } |
| 1674 | else /* regular case (two registers) */ | 1671 | else /* regular case (two registers) */ |
| 1675 | codebinexpval(fs, OP_SHL, e1, e2, line); | 1672 | codebinexpval(fs, OP_SHL, e1, e2, line); |
| 1676 | break; | 1673 | break; |
| 1677 | } | 1674 | } |
| 1678 | case OPR_SHR: { | 1675 | case OPR_SHR: { |
| 1679 | if (isSCintN(e2)) | 1676 | if (isSCint(e2)) |
| 1680 | codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */ | 1677 | codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */ |
| 1681 | else /* regular case (two registers) */ | 1678 | else /* regular case (two registers) */ |
| 1682 | codebinexpval(fs, OP_SHR, e1, e2, line); | 1679 | codebinexpval(fs, OP_SHR, e1, e2, line); |
