diff options
| -rw-r--r-- | lcode.c | 59 | ||||
| -rw-r--r-- | lcode.h | 6 | ||||
| -rw-r--r-- | lopcodes.c | 12 | ||||
| -rw-r--r-- | lopcodes.h | 35 | ||||
| -rw-r--r-- | lparser.c | 2 | ||||
| -rw-r--r-- | ltests.c | 5 | ||||
| -rw-r--r-- | lvm.c | 25 |
7 files changed, 97 insertions, 47 deletions
| @@ -390,32 +390,40 @@ int luaK_code (FuncState *fs, Instruction i) { | |||
| 390 | ** Format and emit an 'iABC' instruction. (Assertions check consistency | 390 | ** Format and emit an 'iABC' instruction. (Assertions check consistency |
| 391 | ** of parameters versus opcode.) | 391 | ** of parameters versus opcode.) |
| 392 | */ | 392 | */ |
| 393 | int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { | 393 | int luaK_codeABCk (FuncState *fs, OpCode o, int A, int B, int C, int k) { |
| 394 | lua_assert(getOpMode(o) == iABC); | 394 | lua_assert(getOpMode(o) == iABC); |
| 395 | lua_assert(a <= MAXARG_A && b <= MAXARG_B && | 395 | lua_assert(A <= MAXARG_A && B <= MAXARG_B && |
| 396 | c <= MAXARG_C && (k & ~1) == 0); | 396 | C <= MAXARG_C && (k & ~1) == 0); |
| 397 | return luaK_code(fs, CREATE_ABCk(o, a, b, c, k)); | 397 | return luaK_code(fs, CREATE_ABCk(o, A, B, C, k)); |
| 398 | } | ||
| 399 | |||
| 400 | |||
| 401 | int luaK_codevABCk (FuncState *fs, OpCode o, int A, int B, int C, int k) { | ||
| 402 | lua_assert(getOpMode(o) == ivABC); | ||
| 403 | lua_assert(A <= MAXARG_A && B <= MAXARG_vB && | ||
| 404 | C <= MAXARG_vC && (k & ~1) == 0); | ||
| 405 | return luaK_code(fs, CREATE_vABCk(o, A, B, C, k)); | ||
| 398 | } | 406 | } |
| 399 | 407 | ||
| 400 | 408 | ||
| 401 | /* | 409 | /* |
| 402 | ** Format and emit an 'iABx' instruction. | 410 | ** Format and emit an 'iABx' instruction. |
| 403 | */ | 411 | */ |
| 404 | int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | 412 | int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bc) { |
| 405 | lua_assert(getOpMode(o) == iABx); | 413 | lua_assert(getOpMode(o) == iABx); |
| 406 | lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); | 414 | lua_assert(A <= MAXARG_A && Bc <= MAXARG_Bx); |
| 407 | return luaK_code(fs, CREATE_ABx(o, a, bc)); | 415 | return luaK_code(fs, CREATE_ABx(o, A, Bc)); |
| 408 | } | 416 | } |
| 409 | 417 | ||
| 410 | 418 | ||
| 411 | /* | 419 | /* |
| 412 | ** Format and emit an 'iAsBx' instruction. | 420 | ** Format and emit an 'iAsBx' instruction. |
| 413 | */ | 421 | */ |
| 414 | static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) { | 422 | static int codeAsBx (FuncState *fs, OpCode o, int A, int Bc) { |
| 415 | unsigned int b = bc + OFFSET_sBx; | 423 | unsigned int b = cast_uint(Bc) + OFFSET_sBx; |
| 416 | lua_assert(getOpMode(o) == iAsBx); | 424 | lua_assert(getOpMode(o) == iAsBx); |
| 417 | lua_assert(a <= MAXARG_A && b <= MAXARG_Bx); | 425 | lua_assert(A <= MAXARG_A && b <= MAXARG_Bx); |
| 418 | return luaK_code(fs, CREATE_ABx(o, a, b)); | 426 | return luaK_code(fs, CREATE_ABx(o, A, b)); |
| 419 | } | 427 | } |
| 420 | 428 | ||
| 421 | 429 | ||
| @@ -423,7 +431,7 @@ static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) { | |||
| 423 | ** Format and emit an 'isJ' instruction. | 431 | ** Format and emit an 'isJ' instruction. |
| 424 | */ | 432 | */ |
| 425 | static int codesJ (FuncState *fs, OpCode o, int sj, int k) { | 433 | static int codesJ (FuncState *fs, OpCode o, int sj, int k) { |
| 426 | unsigned int j = sj + OFFSET_sJ; | 434 | unsigned int j = cast_uint(sj) + OFFSET_sJ; |
| 427 | lua_assert(getOpMode(o) == isJ); | 435 | lua_assert(getOpMode(o) == isJ); |
| 428 | lua_assert(j <= MAXARG_sJ && (k & ~1) == 0); | 436 | lua_assert(j <= MAXARG_sJ && (k & ~1) == 0); |
| 429 | return luaK_code(fs, CREATE_sJ(o, j, k)); | 437 | return luaK_code(fs, CREATE_sJ(o, j, k)); |
| @@ -433,9 +441,9 @@ static int codesJ (FuncState *fs, OpCode o, int sj, int k) { | |||
| 433 | /* | 441 | /* |
| 434 | ** Emit an "extra argument" instruction (format 'iAx') | 442 | ** Emit an "extra argument" instruction (format 'iAx') |
| 435 | */ | 443 | */ |
| 436 | static int codeextraarg (FuncState *fs, int a) { | 444 | static int codeextraarg (FuncState *fs, int A) { |
| 437 | lua_assert(a <= MAXARG_Ax); | 445 | lua_assert(A <= MAXARG_Ax); |
| 438 | return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); | 446 | return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, A)); |
| 439 | } | 447 | } |
| 440 | 448 | ||
| 441 | 449 | ||
| @@ -1032,10 +1040,10 @@ static int exp2RK (FuncState *fs, expdesc *e) { | |||
| 1032 | } | 1040 | } |
| 1033 | 1041 | ||
| 1034 | 1042 | ||
| 1035 | static void codeABRK (FuncState *fs, OpCode o, int a, int b, | 1043 | static void codeABRK (FuncState *fs, OpCode o, int A, int B, |
| 1036 | expdesc *ec) { | 1044 | expdesc *ec) { |
| 1037 | int k = exp2RK(fs, ec); | 1045 | int k = exp2RK(fs, ec); |
| 1038 | luaK_codeABCk(fs, o, a, b, ec->u.info, k); | 1046 | luaK_codeABCk(fs, o, A, B, ec->u.info, k); |
| 1039 | } | 1047 | } |
| 1040 | 1048 | ||
| 1041 | 1049 | ||
| @@ -1788,10 +1796,10 @@ void luaK_fixline (FuncState *fs, int line) { | |||
| 1788 | void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { | 1796 | void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { |
| 1789 | Instruction *inst = &fs->f->code[pc]; | 1797 | Instruction *inst = &fs->f->code[pc]; |
| 1790 | int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0; /* hash size */ | 1798 | int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0; /* hash size */ |
| 1791 | int extra = asize / (MAXARG_C + 1); /* higher bits of array size */ | 1799 | int extra = asize / (MAXARG_vC + 1); /* higher bits of array size */ |
| 1792 | int rc = asize % (MAXARG_C + 1); /* lower bits of array size */ | 1800 | int rc = asize % (MAXARG_vC + 1); /* lower bits of array size */ |
| 1793 | int k = (extra > 0); /* true iff needs extra argument */ | 1801 | int k = (extra > 0); /* true iff needs extra argument */ |
| 1794 | *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k); | 1802 | *inst = CREATE_vABCk(OP_NEWTABLE, ra, rb, rc, k); |
| 1795 | *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); | 1803 | *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra); |
| 1796 | } | 1804 | } |
| 1797 | 1805 | ||
| @@ -1807,12 +1815,12 @@ void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { | |||
| 1807 | lua_assert(tostore != 0); | 1815 | lua_assert(tostore != 0); |
| 1808 | if (tostore == LUA_MULTRET) | 1816 | if (tostore == LUA_MULTRET) |
| 1809 | tostore = 0; | 1817 | tostore = 0; |
| 1810 | if (nelems <= MAXARG_C) | 1818 | if (nelems <= MAXARG_vC) |
| 1811 | luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems); | 1819 | luaK_codevABCk(fs, OP_SETLIST, base, tostore, nelems, 0); |
| 1812 | else { | 1820 | else { |
| 1813 | int extra = nelems / (MAXARG_C + 1); | 1821 | int extra = nelems / (MAXARG_vC + 1); |
| 1814 | nelems %= (MAXARG_C + 1); | 1822 | nelems %= (MAXARG_vC + 1); |
| 1815 | luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1); | 1823 | luaK_codevABCk(fs, OP_SETLIST, base, tostore, nelems, 1); |
| 1816 | codeextraarg(fs, extra); | 1824 | codeextraarg(fs, extra); |
| 1817 | } | 1825 | } |
| 1818 | fs->freereg = base + 1; /* free registers with list values */ | 1826 | fs->freereg = base + 1; /* free registers with list values */ |
| @@ -1839,6 +1847,7 @@ static int finaltarget (Instruction *code, int i) { | |||
| 1839 | ** Do a final pass over the code of a function, doing small peephole | 1847 | ** Do a final pass over the code of a function, doing small peephole |
| 1840 | ** optimizations and adjustments. | 1848 | ** optimizations and adjustments. |
| 1841 | */ | 1849 | */ |
| 1850 | #include "lopnames.h" | ||
| 1842 | void luaK_finish (FuncState *fs) { | 1851 | void luaK_finish (FuncState *fs) { |
| 1843 | int i; | 1852 | int i; |
| 1844 | Proto *p = fs->f; | 1853 | Proto *p = fs->f; |
| @@ -61,8 +61,10 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | |||
| 61 | 61 | ||
| 62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); | 62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); |
| 63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned Bx); | 63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned Bx); |
| 64 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, | 64 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, int B, int C, |
| 65 | int B, int C, int k); | 65 | int k); |
| 66 | LUAI_FUNC int luaK_codevABCk (FuncState *fs, OpCode o, int A, int B, int C, | ||
| 67 | int k); | ||
| 66 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); | 68 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); |
| 67 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); | 69 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); |
| 68 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); | 70 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); |
| @@ -40,7 +40,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
| 40 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ | 40 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETTABLE */ |
| 41 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ | 41 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETI */ |
| 42 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ | 42 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_SETFIELD */ |
| 43 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_NEWTABLE */ | 43 | ,opmode(0, 0, 0, 0, 1, ivABC) /* OP_NEWTABLE */ |
| 44 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ | 44 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_SELF */ |
| 45 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ | 45 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDI */ |
| 46 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ | 46 | ,opmode(0, 0, 0, 0, 1, iABC) /* OP_ADDK */ |
| @@ -99,7 +99,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
| 99 | ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ | 99 | ,opmode(0, 0, 0, 0, 0, iABx) /* OP_TFORPREP */ |
| 100 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ | 100 | ,opmode(0, 0, 0, 0, 0, iABC) /* OP_TFORCALL */ |
| 101 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ | 101 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_TFORLOOP */ |
| 102 | ,opmode(0, 0, 1, 0, 0, iABC) /* OP_SETLIST */ | 102 | ,opmode(0, 0, 1, 0, 0, ivABC) /* OP_SETLIST */ |
| 103 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ | 103 | ,opmode(0, 0, 0, 0, 1, iABx) /* OP_CLOSURE */ |
| 104 | ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ | 104 | ,opmode(0, 1, 0, 0, 1, iABC) /* OP_VARARG */ |
| 105 | ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ | 105 | ,opmode(0, 0, 1, 0, 1, iABC) /* OP_VARARGPREP */ |
| @@ -127,6 +127,12 @@ int luaP_isOT (Instruction i) { | |||
| 127 | ** it accepts multiple results. | 127 | ** it accepts multiple results. |
| 128 | */ | 128 | */ |
| 129 | int luaP_isIT (Instruction i) { | 129 | int luaP_isIT (Instruction i) { |
| 130 | return testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0; | 130 | OpCode op = GET_OPCODE(i); |
| 131 | switch (op) { | ||
| 132 | case OP_SETLIST: | ||
| 133 | return testITMode(GET_OPCODE(i)) && GETARG_vB(i) == 0; | ||
| 134 | default: | ||
| 135 | return testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0; | ||
| 136 | } | ||
| 131 | } | 137 | } |
| 132 | 138 | ||
| @@ -19,25 +19,30 @@ | |||
| 19 | 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | 19 | 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 |
| 20 | 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | 20 | 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
| 21 | iABC C(8) | B(8) |k| A(8) | Op(7) | | 21 | iABC C(8) | B(8) |k| A(8) | Op(7) | |
| 22 | ivABC vC(10) | vB(6) |k| A(8) | Op(7) | | ||
| 22 | iABx Bx(17) | A(8) | Op(7) | | 23 | iABx Bx(17) | A(8) | Op(7) | |
| 23 | iAsBx sBx (signed)(17) | A(8) | Op(7) | | 24 | iAsBx sBx (signed)(17) | A(8) | Op(7) | |
| 24 | iAx Ax(25) | Op(7) | | 25 | iAx Ax(25) | Op(7) | |
| 25 | isJ sJ (signed)(25) | Op(7) | | 26 | isJ sJ (signed)(25) | Op(7) | |
| 26 | 27 | ||
| 28 | ('v' stands for "variant", 's' for "signed", 'x' for "extended".) | ||
| 27 | A signed argument is represented in excess K: The represented value is | 29 | A signed argument is represented in excess K: The represented value is |
| 28 | the written unsigned value minus K, where K is half (rounded down) the | 30 | the written unsigned value minus K, where K is half (rounded down) the |
| 29 | maximum value for the corresponding unsigned argument. | 31 | maximum value for the corresponding unsigned argument. |
| 30 | ===========================================================================*/ | 32 | ===========================================================================*/ |
| 31 | 33 | ||
| 32 | 34 | ||
| 33 | enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ | 35 | /* basic instruction formats */ |
| 36 | enum OpMode {iABC, ivABC, iABx, iAsBx, iAx, isJ}; | ||
| 34 | 37 | ||
| 35 | 38 | ||
| 36 | /* | 39 | /* |
| 37 | ** size and position of opcode arguments. | 40 | ** size and position of opcode arguments. |
| 38 | */ | 41 | */ |
| 39 | #define SIZE_C 8 | 42 | #define SIZE_C 8 |
| 43 | #define SIZE_vC 10 | ||
| 40 | #define SIZE_B 8 | 44 | #define SIZE_B 8 |
| 45 | #define SIZE_vB 6 | ||
| 41 | #define SIZE_Bx (SIZE_C + SIZE_B + 1) | 46 | #define SIZE_Bx (SIZE_C + SIZE_B + 1) |
| 42 | #define SIZE_A 8 | 47 | #define SIZE_A 8 |
| 43 | #define SIZE_Ax (SIZE_Bx + SIZE_A) | 48 | #define SIZE_Ax (SIZE_Bx + SIZE_A) |
| @@ -50,7 +55,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ | |||
| 50 | #define POS_A (POS_OP + SIZE_OP) | 55 | #define POS_A (POS_OP + SIZE_OP) |
| 51 | #define POS_k (POS_A + SIZE_A) | 56 | #define POS_k (POS_A + SIZE_A) |
| 52 | #define POS_B (POS_k + 1) | 57 | #define POS_B (POS_k + 1) |
| 58 | #define POS_vB (POS_k + 1) | ||
| 53 | #define POS_C (POS_B + SIZE_B) | 59 | #define POS_C (POS_B + SIZE_B) |
| 60 | #define POS_vC (POS_vB + SIZE_vB) | ||
| 54 | 61 | ||
| 55 | #define POS_Bx POS_k | 62 | #define POS_Bx POS_k |
| 56 | 63 | ||
| @@ -95,7 +102,9 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ | |||
| 95 | 102 | ||
| 96 | #define MAXARG_A ((1<<SIZE_A)-1) | 103 | #define MAXARG_A ((1<<SIZE_A)-1) |
| 97 | #define MAXARG_B ((1<<SIZE_B)-1) | 104 | #define MAXARG_B ((1<<SIZE_B)-1) |
| 105 | #define MAXARG_vB ((1<<SIZE_vB)-1) | ||
| 98 | #define MAXARG_C ((1<<SIZE_C)-1) | 106 | #define MAXARG_C ((1<<SIZE_C)-1) |
| 107 | #define MAXARG_vC ((1<<SIZE_vC)-1) | ||
| 99 | #define OFFSET_sC (MAXARG_C >> 1) | 108 | #define OFFSET_sC (MAXARG_C >> 1) |
| 100 | 109 | ||
| 101 | #define int2sC(i) ((i) + OFFSET_sC) | 110 | #define int2sC(i) ((i) + OFFSET_sC) |
| @@ -126,16 +135,24 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ | |||
| 126 | #define GETARG_A(i) getarg(i, POS_A, SIZE_A) | 135 | #define GETARG_A(i) getarg(i, POS_A, SIZE_A) |
| 127 | #define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) | 136 | #define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) |
| 128 | 137 | ||
| 129 | #define GETARG_B(i) check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B)) | 138 | #define GETARG_B(i) \ |
| 139 | check_exp(checkopm(i, iABC), getarg(i, POS_B, SIZE_B)) | ||
| 140 | #define GETARG_vB(i) \ | ||
| 141 | check_exp(checkopm(i, ivABC), getarg(i, POS_vB, SIZE_vB)) | ||
| 130 | #define GETARG_sB(i) sC2int(GETARG_B(i)) | 142 | #define GETARG_sB(i) sC2int(GETARG_B(i)) |
| 131 | #define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) | 143 | #define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) |
| 144 | #define SETARG_vB(i,v) setarg(i, v, POS_vB, SIZE_vB) | ||
| 132 | 145 | ||
| 133 | #define GETARG_C(i) check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C)) | 146 | #define GETARG_C(i) \ |
| 147 | check_exp(checkopm(i, iABC), getarg(i, POS_C, SIZE_C)) | ||
| 148 | #define GETARG_vC(i) \ | ||
| 149 | check_exp(checkopm(i, ivABC), getarg(i, POS_vC, SIZE_vC)) | ||
| 134 | #define GETARG_sC(i) sC2int(GETARG_C(i)) | 150 | #define GETARG_sC(i) sC2int(GETARG_C(i)) |
| 135 | #define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) | 151 | #define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) |
| 152 | #define SETARG_vC(i,v) setarg(i, v, POS_vC, SIZE_vC) | ||
| 136 | 153 | ||
| 137 | #define TESTARG_k(i) check_exp(checkopm(i, iABC), (cast_int(((i) & (1u << POS_k))))) | 154 | #define TESTARG_k(i) (cast_int(((i) & (1u << POS_k)))) |
| 138 | #define GETARG_k(i) check_exp(checkopm(i, iABC), getarg(i, POS_k, 1)) | 155 | #define GETARG_k(i) getarg(i, POS_k, 1) |
| 139 | #define SETARG_k(i,v) setarg(i, v, POS_k, 1) | 156 | #define SETARG_k(i,v) setarg(i, v, POS_k, 1) |
| 140 | 157 | ||
| 141 | #define GETARG_Bx(i) check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx)) | 158 | #define GETARG_Bx(i) check_exp(checkopm(i, iABx), getarg(i, POS_Bx, SIZE_Bx)) |
| @@ -160,6 +177,12 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ | |||
| 160 | | (cast(Instruction, c)<<POS_C) \ | 177 | | (cast(Instruction, c)<<POS_C) \ |
| 161 | | (cast(Instruction, k)<<POS_k)) | 178 | | (cast(Instruction, k)<<POS_k)) |
| 162 | 179 | ||
| 180 | #define CREATE_vABCk(o,a,b,c,k) ((cast(Instruction, o)<<POS_OP) \ | ||
| 181 | | (cast(Instruction, a)<<POS_A) \ | ||
| 182 | | (cast(Instruction, b)<<POS_vB) \ | ||
| 183 | | (cast(Instruction, c)<<POS_vC) \ | ||
| 184 | | (cast(Instruction, k)<<POS_k)) | ||
| 185 | |||
| 163 | #define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \ | 186 | #define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \ |
| 164 | | (cast(Instruction, a)<<POS_A) \ | 187 | | (cast(Instruction, a)<<POS_A) \ |
| 165 | | (cast(Instruction, bc)<<POS_Bx)) | 188 | | (cast(Instruction, bc)<<POS_Bx)) |
| @@ -306,7 +329,7 @@ OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */ | |||
| 306 | OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ | 329 | OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ |
| 307 | OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ | 330 | OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ |
| 308 | 331 | ||
| 309 | OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ | 332 | OP_SETLIST,/* A vB vC k R[A][vC+i] := R[A+i], 1 <= i <= vB */ |
| 310 | 333 | ||
| 311 | OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ | 334 | OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ |
| 312 | 335 | ||
| @@ -952,7 +952,7 @@ static void constructor (LexState *ls, expdesc *t) { | |||
| 952 | sep -> ',' | ';' */ | 952 | sep -> ',' | ';' */ |
| 953 | FuncState *fs = ls->fs; | 953 | FuncState *fs = ls->fs; |
| 954 | int line = ls->linenumber; | 954 | int line = ls->linenumber; |
| 955 | int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); | 955 | int pc = luaK_codevABCk(fs, OP_NEWTABLE, 0, 0, 0, 0); |
| 956 | ConsControl cc; | 956 | ConsControl cc; |
| 957 | luaK_code(fs, 0); /* space for extra arg. */ | 957 | luaK_code(fs, 0); /* space for extra arg. */ |
| 958 | cc.na = cc.nh = cc.tostore = 0; | 958 | cc.na = cc.nh = cc.tostore = 0; |
| @@ -697,6 +697,11 @@ static char *buildop (Proto *p, int pc, char *buff) { | |||
| 697 | GETARG_A(i), GETARG_B(i), GETARG_C(i), | 697 | GETARG_A(i), GETARG_B(i), GETARG_C(i), |
| 698 | GETARG_k(i) ? " (k)" : ""); | 698 | GETARG_k(i) ? " (k)" : ""); |
| 699 | break; | 699 | break; |
| 700 | case ivABC: | ||
| 701 | sprintf(buff, "%-12s%4d %4d %4d%s", name, | ||
| 702 | GETARG_A(i), GETARG_vB(i), GETARG_vC(i), | ||
| 703 | GETARG_k(i) ? " (k)" : ""); | ||
| 704 | break; | ||
| 700 | case iABx: | 705 | case iABx: |
| 701 | sprintf(buff, "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); | 706 | sprintf(buff, "%-12s%4d %4d", name, GETARG_A(i), GETARG_Bx(i)); |
| 702 | break; | 707 | break; |
| @@ -1359,14 +1359,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1359 | } | 1359 | } |
| 1360 | vmcase(OP_NEWTABLE) { | 1360 | vmcase(OP_NEWTABLE) { |
| 1361 | StkId ra = RA(i); | 1361 | StkId ra = RA(i); |
| 1362 | int b = GETARG_B(i); /* log2(hash size) + 1 */ | 1362 | int b = GETARG_vB(i); /* log2(hash size) + 1 */ |
| 1363 | int c = GETARG_C(i); /* array size */ | 1363 | int c = GETARG_vC(i); /* array size */ |
| 1364 | Table *t; | 1364 | Table *t; |
| 1365 | if (b > 0) | 1365 | if (b > 0) |
| 1366 | b = 1 << (b - 1); /* size is 2^(b - 1) */ | 1366 | b = 1 << (b - 1); /* hash size is 2^(b - 1) */ |
| 1367 | lua_assert((!TESTARG_k(i)) == (GETARG_Ax(*pc) == 0)); | 1367 | if (TESTARG_k(i)) { /* non-zero extra argument? */ |
| 1368 | if (TESTARG_k(i)) /* non-zero extra argument? */ | 1368 | lua_assert(GETARG_Ax(*pc) != 0); |
| 1369 | c += GETARG_Ax(*pc) * (MAXARG_C + 1); /* add it to size */ | 1369 | c += GETARG_Ax(*pc) * (MAXARG_vC + 1); /* add it to array size */ |
| 1370 | } | ||
| 1370 | pc++; /* skip extra argument */ | 1371 | pc++; /* skip extra argument */ |
| 1371 | L->top.p = ra + 1; /* correct top in case of emergency GC */ | 1372 | L->top.p = ra + 1; /* correct top in case of emergency GC */ |
| 1372 | t = luaH_new(L); /* memory allocation */ | 1373 | t = luaH_new(L); /* memory allocation */ |
| @@ -1850,8 +1851,8 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1850 | }} | 1851 | }} |
| 1851 | vmcase(OP_SETLIST) { | 1852 | vmcase(OP_SETLIST) { |
| 1852 | StkId ra = RA(i); | 1853 | StkId ra = RA(i); |
| 1853 | int n = GETARG_B(i); | 1854 | int n = GETARG_vB(i); |
| 1854 | unsigned int last = GETARG_C(i); | 1855 | unsigned int last = GETARG_vC(i); |
| 1855 | Table *h = hvalue(s2v(ra)); | 1856 | Table *h = hvalue(s2v(ra)); |
| 1856 | if (n == 0) | 1857 | if (n == 0) |
| 1857 | n = cast_int(L->top.p - ra) - 1; /* get up to the top */ | 1858 | n = cast_int(L->top.p - ra) - 1; /* get up to the top */ |
| @@ -1859,11 +1860,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1859 | L->top.p = ci->top.p; /* correct top in case of emergency GC */ | 1860 | L->top.p = ci->top.p; /* correct top in case of emergency GC */ |
| 1860 | last += n; | 1861 | last += n; |
| 1861 | if (TESTARG_k(i)) { | 1862 | if (TESTARG_k(i)) { |
| 1862 | last += GETARG_Ax(*pc) * (MAXARG_C + 1); | 1863 | last += GETARG_Ax(*pc) * (MAXARG_vC + 1); |
| 1863 | pc++; | 1864 | pc++; |
| 1864 | } | 1865 | } |
| 1865 | if (last > luaH_realasize(h)) /* needs more space? */ | 1866 | /* when 'n' is known, table should have proper size */ |
| 1867 | if (last > luaH_realasize(h)) { /* needs more space? */ | ||
| 1868 | /* fixed-size sets should have space preallocated */ | ||
| 1869 | lua_assert(GETARG_vB(i) == 0); | ||
| 1866 | luaH_resizearray(L, h, last); /* preallocate it at once */ | 1870 | luaH_resizearray(L, h, last); /* preallocate it at once */ |
| 1871 | } | ||
| 1867 | for (; n > 0; n--) { | 1872 | for (; n > 0; n--) { |
| 1868 | TValue *val = s2v(ra + n); | 1873 | TValue *val = s2v(ra + n); |
| 1869 | obj2arr(h, last - 1, val); | 1874 | obj2arr(h, last - 1, val); |
