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.
-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);