diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-15 14:59:35 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-15 14:59:35 -0300 |
| commit | 758c1ef445ab27d89bace746111add04083a8e20 (patch) | |
| tree | 8136726cfaa1dc0841547987f2cb0555d02f2303 /lcode.c | |
| parent | dd6d8db49acda5d5353a0a9c42485d9b4bde419d (diff) | |
| download | lua-758c1ef445ab27d89bace746111add04083a8e20.tar.gz lua-758c1ef445ab27d89bace746111add04083a8e20.tar.bz2 lua-758c1ef445ab27d89bace746111add04083a8e20.zip | |
Unification of size representation in OP_NEWTABLE and OP_SETLIST
Opcodes OP_NEWTABLE and OP_SETLIST use the same representation to
store the size of the array part of a table. This new representation
can go up to 2^33 (8 + 25 bits).
Diffstat (limited to 'lcode.c')
| -rw-r--r-- | lcode.c | 40 |
1 files changed, 28 insertions, 12 deletions
| @@ -372,7 +372,7 @@ static void removelastinstruction (FuncState *fs) { | |||
| 372 | ** Emit instruction 'i', checking for array sizes and saving also its | 372 | ** Emit instruction 'i', checking for array sizes and saving also its |
| 373 | ** line information. Return 'i' position. | 373 | ** line information. Return 'i' position. |
| 374 | */ | 374 | */ |
| 375 | static int luaK_code (FuncState *fs, Instruction i) { | 375 | int luaK_code (FuncState *fs, Instruction i) { |
| 376 | Proto *f = fs->f; | 376 | Proto *f = fs->f; |
| 377 | /* put new instruction in code array */ | 377 | /* put new instruction in code array */ |
| 378 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, | 378 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, |
| @@ -430,7 +430,7 @@ static int codesJ (FuncState *fs, OpCode o, int sj, int k) { | |||
| 430 | /* | 430 | /* |
| 431 | ** Emit an "extra argument" instruction (format 'iAx') | 431 | ** Emit an "extra argument" instruction (format 'iAx') |
| 432 | */ | 432 | */ |
| 433 | int luaK_codeextraarg (FuncState *fs, int a) { | 433 | static int codeextraarg (FuncState *fs, int a) { |
| 434 | lua_assert(a <= MAXARG_Ax); | 434 | lua_assert(a <= MAXARG_Ax); |
| 435 | return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); | 435 | return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); |
| 436 | } | 436 | } |
| @@ -446,7 +446,7 @@ static int luaK_codek (FuncState *fs, int reg, int k) { | |||
| 446 | return luaK_codeABx(fs, OP_LOADK, reg, k); | 446 | return luaK_codeABx(fs, OP_LOADK, reg, k); |
| 447 | else { | 447 | else { |
| 448 | int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); | 448 | int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); |
| 449 | luaK_codeextraarg(fs, k); | 449 | codeextraarg(fs, k); |
| 450 | return p; | 450 | return p; |
| 451 | } | 451 | } |
| 452 | } | 452 | } |
| @@ -1672,6 +1672,22 @@ void luaK_fixline (FuncState *fs, int line) { | |||
| 1672 | } | 1672 | } |
| 1673 | 1673 | ||
| 1674 | 1674 | ||
| 1675 | void luaK_settablesize (FuncState *fs, int pc, int ra, int rc, int rb) { | ||
| 1676 | Instruction *inst = &fs->f->code[pc]; | ||
| 1677 | int extra = 0; | ||
| 1678 | int k = 0; | ||
| 1679 | if (rb != 0) | ||
| 1680 | rb = luaO_ceillog2(rb) + 1; /* hash size */ | ||
| 1681 | if (rc > MAXARG_C) { /* does it need the extra argument? */ | ||
| 1682 | extra = rc / (MAXARG_C + 1); | ||
| 1683 | rc %= (MAXARG_C + 1); | ||
| 1684 | k = 1; | ||
| 1685 | } | ||
| 1686 | *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); | ||
| 1687 | *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); | ||
| 1688 | } | ||
| 1689 | |||
| 1690 | |||
| 1675 | /* | 1691 | /* |
| 1676 | ** Emit a SETLIST instruction. | 1692 | ** Emit a SETLIST instruction. |
| 1677 | ** 'base' is register that keeps table; | 1693 | ** 'base' is register that keeps table; |
| @@ -1680,17 +1696,17 @@ void luaK_fixline (FuncState *fs, int line) { | |||
| 1680 | ** table (or LUA_MULTRET to add up to stack top). | 1696 | ** table (or LUA_MULTRET to add up to stack top). |
| 1681 | */ | 1697 | */ |
| 1682 | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { | 1698 | void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { |
| 1683 | int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; | ||
| 1684 | int b = (tostore == LUA_MULTRET) ? 0 : tostore; | ||
| 1685 | lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); | 1699 | lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH); |
| 1686 | if (c <= MAXARG_C) | 1700 | if (tostore == LUA_MULTRET) |
| 1687 | luaK_codeABC(fs, OP_SETLIST, base, b, c); | 1701 | tostore = 0; |
| 1688 | else if (c <= MAXARG_Ax) { | 1702 | if (nelems <= MAXARG_C) |
| 1689 | luaK_codeABC(fs, OP_SETLIST, base, b, 0); | 1703 | luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems); |
| 1690 | luaK_codeextraarg(fs, c); | 1704 | else { |
| 1705 | int extra = nelems / (MAXARG_C + 1); | ||
| 1706 | nelems %= (MAXARG_C + 1); | ||
| 1707 | luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1); | ||
| 1708 | codeextraarg(fs, extra); | ||
| 1691 | } | 1709 | } |
| 1692 | else | ||
| 1693 | luaX_syntaxerror(fs->ls, "constructor too long"); | ||
| 1694 | fs->freereg = base + 1; /* free registers with list values */ | 1710 | fs->freereg = base + 1; /* free registers with list values */ |
| 1695 | } | 1711 | } |
| 1696 | 1712 | ||
