aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c126
-rw-r--r--ldebug.c10
-rw-r--r--ljumptab.h7
-rw-r--r--lopcodes.c7
-rw-r--r--lopcodes.h10
-rw-r--r--lopnames.h7
-rw-r--r--ltests.h1
-rw-r--r--lvm.c61
-rw-r--r--testes/code.lua82
-rw-r--r--testes/db.lua2
-rw-r--r--testes/events.lua2
11 files changed, 228 insertions, 87 deletions
diff --git a/lcode.c b/lcode.c
index 054b28fd..1872ede2 100644
--- a/lcode.c
+++ b/lcode.c
@@ -371,10 +371,6 @@ int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) {
371} 371}
372 372
373 373
374#define codeABsC(fs,o,a,b,c,k) luaK_codeABCk(fs,o,a,b,((c) + OFFSET_sC),k)
375
376
377
378/* 374/*
379** Format and emit an 'iABx' instruction. 375** Format and emit an 'iABx' instruction.
380*/ 376*/
@@ -885,30 +881,45 @@ void luaK_exp2val (FuncState *fs, expdesc *e) {
885 881
886 882
887/* 883/*
884** Try to make 'e' a K expression with an index in the range of R/K
885** indices. Return true iff succeeded.
886*/
887static int luaK_exp2K (FuncState *fs, expdesc *e) {
888 if (!hasjumps(e)) {
889 int info;
890 switch (e->k) { /* move constants to 'k' */
891 case VTRUE: info = boolK(fs, 1); break;
892 case VFALSE: info = boolK(fs, 0); break;
893 case VNIL: info = nilK(fs); break;
894 case VKINT: info = luaK_intK(fs, e->u.ival); break;
895 case VKFLT: info = luaK_numberK(fs, e->u.nval); break;
896 case VK: info = e->u.info; break;
897 default: return 0; /* not a constant */
898 }
899 if (info <= MAXINDEXRK) { /* does constant fit in 'argC'? */
900 e->k = VK; /* make expression a 'K' expression */
901 e->u.info = info;
902 return 1;
903 }
904 }
905 /* else, expression doesn't fit; leave it unchanged */
906 return 0;
907}
908
909
910/*
888** Ensures final expression result is in a valid R/K index 911** Ensures final expression result is in a valid R/K index
889** (that is, it is either in a register or in 'k' with an index 912** (that is, it is either in a register or in 'k' with an index
890** in the range of R/K indices). 913** in the range of R/K indices).
891** Returns 1 if expression is K, 0 otherwise. 914** Returns 1 iff expression is K.
892*/ 915*/
893int luaK_exp2RK (FuncState *fs, expdesc *e) { 916int luaK_exp2RK (FuncState *fs, expdesc *e) {
894 luaK_exp2val(fs, e); 917 if (luaK_exp2K(fs, e))
895 switch (e->k) { /* move constants to 'k' */ 918 return 1;
896 case VTRUE: e->u.info = boolK(fs, 1); goto vk; 919 else { /* not a constant in the right range: put it in a register */
897 case VFALSE: e->u.info = boolK(fs, 0); goto vk; 920 luaK_exp2anyreg(fs, e);
898 case VNIL: e->u.info = nilK(fs); goto vk; 921 return 0;
899 case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk;
900 case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk;
901 case VK:
902 vk:
903 e->k = VK;
904 if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
905 return 1;
906 else break;
907 default: break;
908 } 922 }
909 /* not a constant in the right range: put it in a register */
910 luaK_exp2anyreg(fs, e);
911 return 0;
912} 923}
913 924
914 925
@@ -1232,8 +1243,19 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
1232} 1243}
1233 1244
1234 1245
1246/*
1247** Emit code for binary expressions that "produce values"
1248** (everything but logical operators 'and'/'or' and comparison
1249** operators).
1250** Expression to produce final result will be encoded in 'e1'.
1251** Because 'luaK_exp2anyreg' can free registers, its calls must be
1252** in "stack order" (that is, first on 'e2', which may have more
1253** recent registers to be released).
1254*/
1235static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, 1255static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
1236 int pc, int line) { 1256 OpCode op, int v2, int k, int line) {
1257 int v1 = luaK_exp2anyreg(fs, e1);
1258 int pc = luaK_codeABCk(fs, op, 0, v1, v2, k);
1237 freeexps(fs, e1, e2); 1259 freeexps(fs, e1, e2);
1238 e1->u.info = pc; 1260 e1->u.info = pc;
1239 e1->k = VRELOC; /* all those operations are relocatable */ 1261 e1->k = VRELOC; /* all those operations are relocatable */
@@ -1242,20 +1264,13 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
1242 1264
1243 1265
1244/* 1266/*
1245** Emit code for binary expressions that "produce values" 1267** Emit code for binary expressions that "produce values" over
1246** (everything but logical operators 'and'/'or' and comparison 1268** two registers.
1247** operators).
1248** Expression to produce final result will be encoded in 'e1'.
1249** Because 'luaK_exp2anyreg' can free registers, its calls must be
1250** in "stack order" (that is, first on 'e2', which may have more
1251** recent registers to be released).
1252*/ 1269*/
1253static void codebinexpval (FuncState *fs, OpCode op, 1270static void codebinexpval (FuncState *fs, OpCode op,
1254 expdesc *e1, expdesc *e2, int line) { 1271 expdesc *e1, expdesc *e2, int line) {
1255 int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ 1272 int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */
1256 int v1 = luaK_exp2anyreg(fs, e1); 1273 finishbinexpval(fs, e1, e2, op, v2, 0, line);
1257 int pc = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */
1258 finishbinexpval(fs, e1, e2, pc, line);
1259} 1274}
1260 1275
1261 1276
@@ -1264,41 +1279,48 @@ static void codebinexpval (FuncState *fs, OpCode op,
1264*/ 1279*/
1265static void codebini (FuncState *fs, OpCode op, 1280static void codebini (FuncState *fs, OpCode op,
1266 expdesc *e1, expdesc *e2, int k, int line) { 1281 expdesc *e1, expdesc *e2, int k, int line) {
1267 int v2 = cast_int(e2->u.ival); /* immediate operand */ 1282 int v2 = cast_int(e2->u.ival) + OFFSET_sC; /* immediate operand */
1268 int v1 = luaK_exp2anyreg(fs, e1); 1283 finishbinexpval(fs, e1, e2, op, v2, k, line);
1269 int pc = codeABsC(fs, op, 0, v1, v2, k); /* generate opcode */ 1284}
1270 finishbinexpval(fs, e1, e2, pc, line); 1285
1286
1287static void swapexps (expdesc *e1, expdesc *e2) {
1288 expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */
1271} 1289}
1272 1290
1273 1291
1274/* 1292/*
1275** Code arithmetic operators ('+', '-', ...). If second operand is a 1293** Code arithmetic operators ('+', '-', ...). If second operand is a
1276** constant in the proper range, use variant opcodes with immediate 1294** constant in the proper range, use variant opcodes with immediate
1277** operands. 1295** operands or K operands.
1278*/ 1296*/
1279static void codearith (FuncState *fs, OpCode op, 1297static void codearith (FuncState *fs, OpCode op,
1280 expdesc *e1, expdesc *e2, int flip, int line) { 1298 expdesc *e1, expdesc *e2, int flip, int line) {
1281 if (!isSCint(e2)) 1299 if (isSCint(e2)) /* immediate operand? */
1282 codebinexpval(fs, op, e1, e2, line); /* use standard operators */
1283 else /* use immediate operators */
1284 codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line); 1300 codebini(fs, cast(OpCode, op - OP_ADD + OP_ADDI), e1, e2, flip, line);
1285} 1301 else if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) { /* K operand? */
1286 1302 int v2 = e2->u.info; /* K index */
1287 1303 op = cast(OpCode, op - OP_ADD + OP_ADDK);
1288static void swapexps (expdesc *e1, expdesc *e2) { 1304 finishbinexpval(fs, e1, e2, op, v2, flip, line);
1289 expdesc temp = *e1; *e1 = *e2; *e2 = temp; /* swap 'e1' and 'e2' */ 1305 }
1306 else { /* 'e2' is neither an immediate nor a K operand */
1307 if (flip)
1308 swapexps(e1, e2); /* back to original order */
1309 codebinexpval(fs, op, e1, e2, line); /* use standard operators */
1310 }
1290} 1311}
1291 1312
1292 1313
1293/* 1314/*
1294** Code commutative operators ('+', '*'). If first operand is a 1315** Code commutative operators ('+', '*'). If first operand is a
1295** constant, change order of operands to use immediate operator. 1316** numeric constant, change order of operands to try to use an
1317** immediate or K operator.
1296*/ 1318*/
1297static void codecommutative (FuncState *fs, OpCode op, 1319static void codecommutative (FuncState *fs, OpCode op,
1298 expdesc *e1, expdesc *e2, int line) { 1320 expdesc *e1, expdesc *e2, int line) {
1299 int flip = 0; 1321 int flip = 0;
1300 if (isSCint(e1)) { 1322 if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */
1301 swapexps(e1, e2); 1323 swapexps(e1, e2); /* change order */
1302 flip = 1; 1324 flip = 1;
1303 } 1325 }
1304 codearith(fs, op, e1, e2, flip, line); 1326 codearith(fs, op, e1, e2, flip, line);
@@ -1312,7 +1334,7 @@ static void codecommutative (FuncState *fs, OpCode op,
1312static void codebitwise (FuncState *fs, BinOpr opr, 1334static void codebitwise (FuncState *fs, BinOpr opr,
1313 expdesc *e1, expdesc *e2, int line) { 1335 expdesc *e1, expdesc *e2, int line) {
1314 int inv = 0; 1336 int inv = 0;
1315 int v1, v2, pc; 1337 int v2;
1316 OpCode op; 1338 OpCode op;
1317 if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { 1339 if (e1->k == VKINT && luaK_exp2RK(fs, e1)) {
1318 swapexps(e1, e2); /* 'e2' will be the constant operand */ 1340 swapexps(e1, e2); /* 'e2' will be the constant operand */
@@ -1323,12 +1345,10 @@ static void codebitwise (FuncState *fs, BinOpr opr,
1323 codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ 1345 codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */
1324 return; 1346 return;
1325 } 1347 }
1326 v1 = luaK_exp2anyreg(fs, e1);
1327 v2 = e2->u.info; /* index in K array */ 1348 v2 = e2->u.info; /* index in K array */
1328 op = cast(OpCode, opr - OPR_BAND + OP_BANDK); 1349 op = cast(OpCode, opr - OPR_BAND + OP_BANDK);
1329 lua_assert(ttisinteger(&fs->f->k[v2])); 1350 lua_assert(ttisinteger(&fs->f->k[v2]));
1330 pc = luaK_codeABCk(fs, op, 0, v1, v2, inv); 1351 finishbinexpval(fs, e1, e2, op, v2, inv, line);
1331 finishbinexpval(fs, e1, e2, pc, line);
1332} 1352}
1333 1353
1334 1354
diff --git a/ldebug.c b/ldebug.c
index ee1b87d9..766a5231 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -610,12 +610,18 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
610 tm = TM_NEWINDEX; 610 tm = TM_NEWINDEX;
611 break; 611 break;
612 case OP_ADDI: case OP_SUBI: case OP_MULI: case OP_MODI: 612 case OP_ADDI: case OP_SUBI: case OP_MULI: case OP_MODI:
613 case OP_POWI: case OP_DIVI: case OP_IDIVI: 613 case OP_POWI: case OP_DIVI: case OP_IDIVI: {
614 case OP_BANDK: case OP_BORK: case OP_BXORK: {
615 int offset = GET_OPCODE(i) - OP_ADDI; /* ORDER OP */ 614 int offset = GET_OPCODE(i) - OP_ADDI; /* ORDER OP */
616 tm = cast(TMS, offset + TM_ADD); /* ORDER TM */ 615 tm = cast(TMS, offset + TM_ADD); /* ORDER TM */
617 break; 616 break;
618 } 617 }
618 case OP_ADDK: case OP_SUBK: case OP_MULK: case OP_MODK:
619 case OP_POWK: case OP_DIVK: case OP_IDIVK:
620 case OP_BANDK: case OP_BORK: case OP_BXORK: {
621 int offset = GET_OPCODE(i) - OP_ADDK; /* ORDER OP */
622 tm = cast(TMS, offset + TM_ADD); /* ORDER TM */
623 break;
624 }
619 case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD: 625 case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:
620 case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND: 626 case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND:
621 case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: { 627 case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: {
diff --git a/ljumptab.h b/ljumptab.h
index 6767e95b..0af997d0 100644
--- a/ljumptab.h
+++ b/ljumptab.h
@@ -51,6 +51,13 @@ static void *disptab[] = {
51&&L_OP_POWI, 51&&L_OP_POWI,
52&&L_OP_DIVI, 52&&L_OP_DIVI,
53&&L_OP_IDIVI, 53&&L_OP_IDIVI,
54&&L_OP_ADDK,
55&&L_OP_SUBK,
56&&L_OP_MULK,
57&&L_OP_MODK,
58&&L_OP_POWK,
59&&L_OP_DIVK,
60&&L_OP_IDIVK,
54&&L_OP_BANDK, 61&&L_OP_BANDK,
55&&L_OP_BORK, 62&&L_OP_BORK,
56&&L_OP_BXORK, 63&&L_OP_BXORK,
diff --git a/lopcodes.c b/lopcodes.c
index 11a73c29..3f0d551a 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -45,6 +45,13 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
45 ,opmode(0, 0, 0, 1, iABC) /* OP_POWI */ 45 ,opmode(0, 0, 0, 1, iABC) /* OP_POWI */
46 ,opmode(0, 0, 0, 1, iABC) /* OP_DIVI */ 46 ,opmode(0, 0, 0, 1, iABC) /* OP_DIVI */
47 ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVI */ 47 ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVI */
48 ,opmode(0, 0, 0, 1, iABC) /* OP_ADDK */
49 ,opmode(0, 0, 0, 1, iABC) /* OP_SUBK */
50 ,opmode(0, 0, 0, 1, iABC) /* OP_MULK */
51 ,opmode(0, 0, 0, 1, iABC) /* OP_MODK */
52 ,opmode(0, 0, 0, 1, iABC) /* OP_POWK */
53 ,opmode(0, 0, 0, 1, iABC) /* OP_DIVK */
54 ,opmode(0, 0, 0, 1, iABC) /* OP_IDIVK */
48 ,opmode(0, 0, 0, 1, iABC) /* OP_BANDK */ 55 ,opmode(0, 0, 0, 1, iABC) /* OP_BANDK */
49 ,opmode(0, 0, 0, 1, iABC) /* OP_BORK */ 56 ,opmode(0, 0, 0, 1, iABC) /* OP_BORK */
50 ,opmode(0, 0, 0, 1, iABC) /* OP_BXORK */ 57 ,opmode(0, 0, 0, 1, iABC) /* OP_BXORK */
diff --git a/lopcodes.h b/lopcodes.h
index 7bb83a1e..d7403caf 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -221,6 +221,14 @@ OP_POWI,/* A B sC R(A) := R(B) ^ C */
221OP_DIVI,/* A B sC R(A) := R(B) / C */ 221OP_DIVI,/* A B sC R(A) := R(B) / C */
222OP_IDIVI,/* A B sC R(A) := R(B) // C */ 222OP_IDIVI,/* A B sC R(A) := R(B) // C */
223 223
224OP_ADDK,/* A B C R(A) := R(B) + K(C) */
225OP_SUBK,/* A B C R(A) := R(B) - K(C) */
226OP_MULK,/* A B C R(A) := R(B) * K(C) */
227OP_MODK,/* A B C R(A) := R(B) % K(C) */
228OP_POWK,/* A B C R(A) := R(B) ^ K(C) */
229OP_DIVK,/* A B C R(A) := R(B) / K(C) */
230OP_IDIVK,/* A B C R(A) := R(B) // K(C) */
231
224OP_BANDK,/* A B C R(A) := R(B) & K(C):integer */ 232OP_BANDK,/* A B C R(A) := R(B) & K(C):integer */
225OP_BORK,/* A B C R(A) := R(B) | K(C):integer */ 233OP_BORK,/* A B C R(A) := R(B) | K(C):integer */
226OP_BXORK,/* A B C R(A) := R(B) ~ K(C):integer */ 234OP_BXORK,/* A B C R(A) := R(B) ~ K(C):integer */
@@ -235,11 +243,13 @@ OP_MOD,/* A B C R(A) := R(B) % R(C) */
235OP_POW,/* A B C R(A) := R(B) ^ R(C) */ 243OP_POW,/* A B C R(A) := R(B) ^ R(C) */
236OP_DIV,/* A B C R(A) := R(B) / R(C) */ 244OP_DIV,/* A B C R(A) := R(B) / R(C) */
237OP_IDIV,/* A B C R(A) := R(B) // R(C) */ 245OP_IDIV,/* A B C R(A) := R(B) // R(C) */
246
238OP_BAND,/* A B C R(A) := R(B) & R(C) */ 247OP_BAND,/* A B C R(A) := R(B) & R(C) */
239OP_BOR,/* A B C R(A) := R(B) | R(C) */ 248OP_BOR,/* A B C R(A) := R(B) | R(C) */
240OP_BXOR,/* A B C R(A) := R(B) ~ R(C) */ 249OP_BXOR,/* A B C R(A) := R(B) ~ R(C) */
241OP_SHL,/* A B C R(A) := R(B) << R(C) */ 250OP_SHL,/* A B C R(A) := R(B) << R(C) */
242OP_SHR,/* A B C R(A) := R(B) >> R(C) */ 251OP_SHR,/* A B C R(A) := R(B) >> R(C) */
252
243OP_UNM,/* A B R(A) := -R(B) */ 253OP_UNM,/* A B R(A) := -R(B) */
244OP_BNOT,/* A B R(A) := ~R(B) */ 254OP_BNOT,/* A B R(A) := ~R(B) */
245OP_NOT,/* A B R(A) := not R(B) */ 255OP_NOT,/* A B R(A) := not R(B) */
diff --git a/lopnames.h b/lopnames.h
index b2c4fe21..96d901ac 100644
--- a/lopnames.h
+++ b/lopnames.h
@@ -36,6 +36,13 @@ static const char *const opnames[] = {
36 "POWI", 36 "POWI",
37 "DIVI", 37 "DIVI",
38 "IDIVI", 38 "IDIVI",
39 "ADDK",
40 "SUBK",
41 "MULK",
42 "MODK",
43 "POWK",
44 "DIVK",
45 "IDIVK",
39 "BANDK", 46 "BANDK",
40 "BORK", 47 "BORK",
41 "BXORK", 48 "BXORK",
diff --git a/ltests.h b/ltests.h
index d44974a4..9d409c8d 100644
--- a/ltests.h
+++ b/ltests.h
@@ -119,7 +119,6 @@ LUA_API void *debug_realloc (void *ud, void *block,
119#undef LUAL_BUFFERSIZE 119#undef LUAL_BUFFERSIZE
120#define LUAL_BUFFERSIZE 23 120#define LUAL_BUFFERSIZE 23
121#define MINSTRTABSIZE 2 121#define MINSTRTABSIZE 2
122#define MAXINDEXRK 1
123#define MAXIWTHABS 3 122#define MAXIWTHABS 3
124 123
125 124
diff --git a/lvm.c b/lvm.c
index ece7d77a..27ef68cf 100644
--- a/lvm.c
+++ b/lvm.c
@@ -856,6 +856,39 @@ void luaV_finishOp (lua_State *L) {
856 856
857 857
858/* 858/*
859** Arithmetic operations with K operands.
860*/
861#define op_arithK(L,iop,fop,tm,flip) { \
862 TValue *v1 = vRB(i); \
863 TValue *v2 = KC(i); \
864 if (ttisinteger(v1) && ttisinteger(v2)) { \
865 lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \
866 setivalue(s2v(ra), iop(L, i1, i2)); \
867 } \
868 else { \
869 lua_Number n1; lua_Number n2; \
870 if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \
871 setfltvalue(s2v(ra), fop(L, n1, n2)); \
872 } \
873 else \
874 Protect(luaT_trybinassocTM(L, v1, v2, ra, flip, tm)); } }
875
876
877/*
878** Arithmetic operations with K operands for floats.
879*/
880#define op_arithfK(L,fop,tm) { \
881 TValue *v1 = vRB(i); \
882 TValue *v2 = KC(i); \
883 lua_Number n1; lua_Number n2; \
884 if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \
885 setfltvalue(s2v(ra), fop(L, n1, n2)); \
886 } \
887 else \
888 Protect(luaT_trybinTM(L, v1, v2, ra, tm)); }
889
890
891/*
859** Bitwise operations with constant operand. 892** Bitwise operations with constant operand.
860*/ 893*/
861#define op_bitwiseK(L,op,tm) { \ 894#define op_bitwiseK(L,op,tm) { \
@@ -1219,6 +1252,34 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1219 op_arithI(L, luaV_idiv, luai_numidiv, TM_IDIV, 0); 1252 op_arithI(L, luaV_idiv, luai_numidiv, TM_IDIV, 0);
1220 vmbreak; 1253 vmbreak;
1221 } 1254 }
1255 vmcase(OP_ADDK) {
1256 op_arithK(L, l_addi, luai_numadd, TM_ADD, GETARG_k(i));
1257 vmbreak;
1258 }
1259 vmcase(OP_SUBK) {
1260 op_arithK(L, l_subi, luai_numsub, TM_SUB, 0);
1261 vmbreak;
1262 }
1263 vmcase(OP_MULK) {
1264 op_arithK(L, l_muli, luai_nummul, TM_MUL, GETARG_k(i));
1265 vmbreak;
1266 }
1267 vmcase(OP_MODK) {
1268 op_arithK(L, luaV_mod, luaV_modf, TM_MOD, 0);
1269 vmbreak;
1270 }
1271 vmcase(OP_POWK) {
1272 op_arithfK(L, luai_numpow, TM_POW);
1273 vmbreak;
1274 }
1275 vmcase(OP_DIVK) {
1276 op_arithfK(L, luai_numdiv, TM_DIV);
1277 vmbreak;
1278 }
1279 vmcase(OP_IDIVK) {
1280 op_arithK(L, luaV_idiv, luai_numidiv, TM_IDIV, 0);
1281 vmbreak;
1282 }
1222 vmcase(OP_ADD) { 1283 vmcase(OP_ADD) {
1223 op_arith(L, l_addi, luai_numadd, TM_ADD); 1284 op_arith(L, l_addi, luai_numadd, TM_ADD);
1224 vmbreak; 1285 vmbreak;
diff --git a/testes/code.lua b/testes/code.lua
index 4d44fa6a..834ff5e2 100644
--- a/testes/code.lua
+++ b/testes/code.lua
@@ -40,6 +40,7 @@ checkKlist(foo, {3.78/4, -3.78/4, -3.79/4})
40 40
41-- testing opcodes 41-- testing opcodes
42 42
43-- check that 'f' opcodes match '...'
43function check (f, ...) 44function check (f, ...)
44 local arg = {...} 45 local arg = {...}
45 local c = T.listcode(f) 46 local c = T.listcode(f)
@@ -52,9 +53,19 @@ function check (f, ...)
52end 53end
53 54
54 55
56-- check that 'f' opcodes match '...' and that 'f(p) == r'.
57function checkR (f, p, r, ...)
58 local r1 = f(p)
59 assert(r == r1 and math.type(r) == math.type(r1))
60 check(f, ...)
61end
62
63
64-- check that 'a' and 'b' has the same opcodes
55function checkequal (a, b) 65function checkequal (a, b)
56 a = T.listcode(a) 66 a = T.listcode(a)
57 b = T.listcode(b) 67 b = T.listcode(b)
68 assert(#a == #b)
58 for i = 1, #a do 69 for i = 1, #a do
59 a[i] = string.gsub(a[i], '%b()', '') -- remove line number 70 a[i] = string.gsub(a[i], '%b()', '') -- remove line number
60 b[i] = string.gsub(b[i], '%b()', '') -- remove line number 71 b[i] = string.gsub(b[i], '%b()', '') -- remove line number
@@ -165,65 +176,64 @@ end,
165 176
166 177
167-- equalities 178-- equalities
168check(function (a) if a == 1 then return 2 end end, 179checkR(function (a) if a == 1 then return 2 end end, 1, 2,
169 'EQI', 'JMP', 'LOADI', 'RETURN1') 180 'EQI', 'JMP', 'LOADI', 'RETURN1')
170 181
171check(function (a) if -4.0 == a then return 2 end end, 182checkR(function (a) if -4.0 == a then return 2 end end, -4, 2,
172 'EQI', 'JMP', 'LOADI', 'RETURN1') 183 'EQI', 'JMP', 'LOADI', 'RETURN1')
173 184
174check(function (a) if a == "hi" then return 2 end end, 185checkR(function (a) if a == "hi" then return 2 end end, 10, nil,
175 'EQK', 'JMP', 'LOADI', 'RETURN1') 186 'EQK', 'JMP', 'LOADI', 'RETURN1')
176 187
177check(function (a) if a == 10000 then return 2 end end, 188checkR(function (a) if a == 10000 then return 2 end end, 1, nil,
178 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large 189 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large
179 190
180check(function (a) if -10000 == a then return 2 end end, 191checkR(function (a) if -10000 == a then return 2 end end, -10000, 2,
181 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large 192 'EQK', 'JMP', 'LOADI', 'RETURN1') -- number too large
182 193
183-- comparisons 194-- comparisons
184 195
185check(function (a) if -10 <= a then return 2 end end, 196checkR(function (a) if -10 <= a then return 2 end end, -10, 2,
186 'GEI', 'JMP', 'LOADI', 'RETURN1') 197 'GEI', 'JMP', 'LOADI', 'RETURN1')
187 198
188check(function (a) if 128.0 > a then return 2 end end, 199checkR(function (a) if 128.0 > a then return 2 end end, 129, nil,
189 'LTI', 'JMP', 'LOADI', 'RETURN1') 200 'LTI', 'JMP', 'LOADI', 'RETURN1')
190 201
191check(function (a) if -127.0 < a then return 2 end end, 202checkR(function (a) if -127.0 < a then return 2 end end, -127, nil,
192 'GTI', 'JMP', 'LOADI', 'RETURN1') 203 'GTI', 'JMP', 'LOADI', 'RETURN1')
193 204
194check(function (a) if 10 < a then return 2 end end, 205checkR(function (a) if 10 < a then return 2 end end, 11, 2,
195 'GTI', 'JMP', 'LOADI', 'RETURN1') 206 'GTI', 'JMP', 'LOADI', 'RETURN1')
196 207
197check(function (a) if 129 < a then return 2 end end, 208checkR(function (a) if 129 < a then return 2 end end, 130, 2,
198 'LOADI', 'LT', 'JMP', 'LOADI', 'RETURN1') 209 'LOADI', 'LT', 'JMP', 'LOADI', 'RETURN1')
199 210
200check(function (a) if a >= 23.0 then return 2 end end, 211checkR(function (a) if a >= 23.0 then return 2 end end, 25, 2,
201 'GEI', 'JMP', 'LOADI', 'RETURN1') 212 'GEI', 'JMP', 'LOADI', 'RETURN1')
202 213
203check(function (a) if a >= 23.1 then return 2 end end, 214checkR(function (a) if a >= 23.1 then return 2 end end, 0, nil,
204 'LOADK', 'LE', 'JMP', 'LOADI', 'RETURN1') 215 'LOADK', 'LE', 'JMP', 'LOADI', 'RETURN1')
205 216
206check(function (a) if a > 2300.0 then return 2 end end, 217checkR(function (a) if a > 2300.0 then return 2 end end, 0, nil,
207 'LOADF', 'LT', 'JMP', 'LOADI', 'RETURN1') 218 'LOADF', 'LT', 'JMP', 'LOADI', 'RETURN1')
208 219
209 220
210-- constant folding 221-- constant folding
211local function checkK (func, val) 222local function checkK (func, val)
212 check(func, 'LOADK', 'RETURN1') 223 check(func, 'LOADK', 'RETURN1')
213 local k = T.listk(func) 224 checkKlist(func, {val})
214 assert(#k == 1 and k[1] == val and math.type(k[1]) == math.type(val))
215 assert(func() == val) 225 assert(func() == val)
216end 226end
217 227
218local function checkI (func, val) 228local function checkI (func, val)
219 check(func, 'LOADI', 'RETURN1') 229 check(func, 'LOADI', 'RETURN1')
220 assert(#T.listk(func) == 0) 230 checkKlist(func, {})
221 assert(func() == val) 231 assert(func() == val)
222end 232end
223 233
224local function checkF (func, val) 234local function checkF (func, val)
225 check(func, 'LOADF', 'RETURN1') 235 check(func, 'LOADF', 'RETURN1')
226 assert(#T.listk(func) == 0) 236 checkKlist(func, {})
227 assert(func() == val) 237 assert(func() == val)
228end 238end
229 239
@@ -258,20 +268,30 @@ checkK(function () return -65536.0 end, -(sbx + 1.0))
258 268
259 269
260-- immediate operands 270-- immediate operands
261check(function (x) return x + 1 end, 'ADDI', 'RETURN1') 271checkR(function (x) return x + 1 end, 10, 11, 'ADDI', 'RETURN1')
262check(function (x) return 128 + x end, 'ADDI', 'RETURN1') 272checkR(function (x) return 128 + x end, 0.0, 128.0, 'ADDI', 'RETURN1')
263check(function (x) return x * -127 end, 'MULI', 'RETURN1') 273checkR(function (x) return x * -127 end, -1.0, 127.0, 'MULI', 'RETURN1')
264check(function (x) return 20 * x end, 'MULI', 'RETURN1') 274checkR(function (x) return 20 * x end, 2, 40, 'MULI', 'RETURN1')
265check(function (x) return x ^ -2 end, 'POWI', 'RETURN1') 275checkR(function (x) return x ^ -2 end, 2, 0.25, 'POWI', 'RETURN1')
266check(function (x) return x / 40 end, 'DIVI', 'RETURN1') 276checkR(function (x) return x / 40 end, 40, 1.0, 'DIVI', 'RETURN1')
267check(function (x) return x // 1 end, 'IDIVI', 'RETURN1') 277checkR(function (x) return x // 1 end, 10.0, 10.0, 'IDIVI', 'RETURN1')
268check(function (x) return x % (100 - 10) end, 'MODI', 'RETURN1') 278checkR(function (x) return x % (100 - 10) end, 91, 1, 'MODI', 'RETURN1')
269check(function (x) return 1 << x end, 'SHLI', 'RETURN1') 279checkR(function (x) return 1 << x end, 3, 8, 'SHLI', 'RETURN1')
270check(function (x) return x << 2 end, 'SHRI', 'RETURN1') 280checkR(function (x) return x << 2 end, 10, 40, 'SHRI', 'RETURN1')
271check(function (x) return x >> 2 end, 'SHRI', 'RETURN1') 281checkR(function (x) return x >> 2 end, 8, 2, 'SHRI', 'RETURN1')
272check(function (x) return x & 1 end, 'BANDK', 'RETURN1') 282checkR(function (x) return x & 1 end, 9, 1, 'BANDK', 'RETURN1')
273check(function (x) return 10 | x end, 'BORK', 'RETURN1') 283checkR(function (x) return 10 | x end, 1, 11, 'BORK', 'RETURN1')
274check(function (x) return -10 ~ x end, 'BXORK', 'RETURN1') 284checkR(function (x) return -10 ~ x end, -1, 9, 'BXORK', 'RETURN1')
285
286-- K operands in arithmetic operations
287checkR(function (x) return x + 0.0 end, 1, 1.0, 'ADDK', 'RETURN1')
288-- check(function (x) return 128 + x end, 'ADDK', 'RETURN1')
289checkR(function (x) return x * -10000 end, 2, -20000, 'MULK', 'RETURN1')
290-- check(function (x) return 20 * x end, 'MULK', 'RETURN1')
291checkR(function (x) return x ^ 0.5 end, 4, 2.0, 'POWK', 'RETURN1')
292checkR(function (x) return x / 2.0 end, 4, 2.0, 'DIVK', 'RETURN1')
293checkR(function (x) return x // 10000 end, 10000, 1, 'IDIVK', 'RETURN1')
294checkR(function (x) return x % (100.0 - 10) end, 91, 1.0, 'MODK', 'RETURN1')
275 295
276-- no foldings (and immediate operands) 296-- no foldings (and immediate operands)
277check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1') 297check(function () return -0.0 end, 'LOADF', 'UNM', 'RETURN1')
diff --git a/testes/db.lua b/testes/db.lua
index 9da68210..5b243c39 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -794,6 +794,8 @@ assert(a[3] == "index" and a^3 == "pow" and a..a == "concat")
794assert(a/3 == "div" and 3%a == "mod") 794assert(a/3 == "div" and 3%a == "mod")
795assert(a+3 == "add" and 3-a == "sub" and a*3 == "mul" and 795assert(a+3 == "add" and 3-a == "sub" and a*3 == "mul" and
796 -a == "unm" and #a == "len" and a&3 == "band") 796 -a == "unm" and #a == "len" and a&3 == "band")
797assert(a + 30000 == "add" and a - 3.0 == "sub" and a * 3.0 == "mul" and
798 -a == "unm" and #a == "len" and a & 3 == "band")
797assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shift" and 799assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shift" and
798 a>>1 == "shift") 800 a>>1 == "shift")
799assert (a==b and a.op == "eq") 801assert (a==b and a.op == "eq")
diff --git a/testes/events.lua b/testes/events.lua
index b071c2a3..ac630d89 100644
--- a/testes/events.lua
+++ b/testes/events.lua
@@ -144,6 +144,8 @@ t.__bnot = f("bnot")
144-- when the constant table is very small. 144-- when the constant table is very small.
145assert(b+5 == b) 145assert(b+5 == b)
146assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==undef) 146assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==undef)
147assert(5.2 + b == 5.2)
148assert(cap[0] == "add" and cap[1] == 5.2 and cap[2] == b and cap[3]==undef)
147assert(b+'5' == b) 149assert(b+'5' == b)
148assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==undef) 150assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==undef)
149assert(5+b == 5) 151assert(5+b == 5)