aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-06-28 11:18:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-06-28 11:18:14 -0300
commitc403e456b66ddacf7f8f974323e9cffdfe6365d4 (patch)
tree2e25027eface85c3156359e4ec182b4a9215903b
parent6ac7219da31df0238dc33c2d4457f69bfe0c1e79 (diff)
downloadlua-c403e456b66ddacf7f8f974323e9cffdfe6365d4.tar.gz
lua-c403e456b66ddacf7f8f974323e9cffdfe6365d4.tar.bz2
lua-c403e456b66ddacf7f8f974323e9cffdfe6365d4.zip
New instruction format for SETLIST/NEWTABLE
New instruction format 'ivABC' (a variant of iABC where parameter vC has 10 bits) allows constructors of up to 1024 elements to be coded without EXTRAARG.
Diffstat (limited to '')
-rw-r--r--lcode.c59
-rw-r--r--lcode.h6
-rw-r--r--lopcodes.c12
-rw-r--r--lopcodes.h35
-rw-r--r--lparser.c2
-rw-r--r--ltests.c5
-rw-r--r--lvm.c25
7 files changed, 97 insertions, 47 deletions
diff --git a/lcode.c b/lcode.c
index e120f0db..c1fce37f 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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*/
393int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) { 393int 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
401int 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*/
404int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { 412int 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*/
414static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) { 422static 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*/
425static int codesJ (FuncState *fs, OpCode o, int sj, int k) { 433static 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*/
436static int codeextraarg (FuncState *fs, int a) { 444static 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
1035static void codeABRK (FuncState *fs, OpCode o, int a, int b, 1043static 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) {
1788void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) { 1796void 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"
1842void luaK_finish (FuncState *fs) { 1851void luaK_finish (FuncState *fs) {
1843 int i; 1852 int i;
1844 Proto *p = fs->f; 1853 Proto *p = fs->f;
diff --git a/lcode.h b/lcode.h
index 5b8eb29e..c1f16da0 100644
--- a/lcode.h
+++ b/lcode.h
@@ -61,8 +61,10 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
61 61
62LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); 62LUAI_FUNC int luaK_code (FuncState *fs, Instruction i);
63LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned Bx); 63LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned Bx);
64LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, 64LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, int B, int C,
65 int B, int C, int k); 65 int k);
66LUAI_FUNC int luaK_codevABCk (FuncState *fs, OpCode o, int A, int B, int C,
67 int k);
66LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); 68LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v);
67LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 69LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
68LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 70LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
diff --git a/lopcodes.c b/lopcodes.c
index 2f9d55c5..5533b517 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -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*/
129int luaP_isIT (Instruction i) { 129int 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
diff --git a/lopcodes.h b/lopcodes.h
index 63918be1..736946e3 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -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
21iABC C(8) | B(8) |k| A(8) | Op(7) | 21iABC C(8) | B(8) |k| A(8) | Op(7) |
22ivABC vC(10) | vB(6) |k| A(8) | Op(7) |
22iABx Bx(17) | A(8) | Op(7) | 23iABx Bx(17) | A(8) | Op(7) |
23iAsBx sBx (signed)(17) | A(8) | Op(7) | 24iAsBx sBx (signed)(17) | A(8) | Op(7) |
24iAx Ax(25) | Op(7) | 25iAx Ax(25) | Op(7) |
25isJ sJ (signed)(25) | Op(7) | 26isJ 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
33enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ 35/* basic instruction formats */
36enum 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 */
306OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ 329OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */
307OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ 330OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */
308 331
309OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ 332OP_SETLIST,/* A vB vC k R[A][vC+i] := R[A+i], 1 <= i <= vB */
310 333
311OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ 334OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */
312 335
diff --git a/lparser.c b/lparser.c
index f3779864..0ed9631a 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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;
diff --git a/ltests.c b/ltests.c
index 2b8db375..cd728947 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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;
diff --git a/lvm.c b/lvm.c
index 4bc8ee81..d8fe55e5 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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);