aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c42
-rw-r--r--ljumptab.h2
-rw-r--r--llimits.h2
-rw-r--r--lopcodes.c2
-rw-r--r--lopcodes.h5
-rw-r--r--lopnames.h2
-rw-r--r--lparser.c2
-rw-r--r--ltm.c8
-rw-r--r--ltm.h2
-rw-r--r--lvm.c96
-rw-r--r--onelua.c107
-rw-r--r--testes/db.lua2
-rw-r--r--testes/events.lua99
13 files changed, 237 insertions, 134 deletions
diff --git a/lcode.c b/lcode.c
index 1872ede2..1e36e584 100644
--- a/lcode.c
+++ b/lcode.c
@@ -179,8 +179,8 @@ void luaK_ret (FuncState *fs, int first, int nret) {
179** Code a "conditional jump", that is, a test or comparison opcode 179** Code a "conditional jump", that is, a test or comparison opcode
180** followed by a jump. Return jump position. 180** followed by a jump. Return jump position.
181*/ 181*/
182static int condjump (FuncState *fs, OpCode op, int A, int B, int k) { 182static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) {
183 luaK_codeABCk(fs, op, A, B, 0, k); 183 luaK_codeABCk(fs, op, A, B, C, k);
184 return luaK_jump(fs); 184 return luaK_jump(fs);
185} 185}
186 186
@@ -799,7 +799,7 @@ static int need_value (FuncState *fs, int list) {
799 799
800/* 800/*
801** Ensures final expression result (which includes results from its 801** Ensures final expression result (which includes results from its
802** jump ** lists) is in register 'reg'. 802** jump lists) is in register 'reg'.
803** If expression has jumps, need to patch these jumps either to 803** If expression has jumps, need to patch these jumps either to
804** its final position or to "load" instructions (for those tests 804** its final position or to "load" instructions (for those tests
805** that do not produce values). 805** that do not produce values).
@@ -814,8 +814,9 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) {
814 int p_t = NO_JUMP; /* position of an eventual LOAD true */ 814 int p_t = NO_JUMP; /* position of an eventual LOAD true */
815 if (need_value(fs, e->t) || need_value(fs, e->f)) { 815 if (need_value(fs, e->t) || need_value(fs, e->f)) {
816 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); 816 int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
817 p_f = code_loadbool(fs, reg, 0, 1); 817 p_f = code_loadbool(fs, reg, 0, 1); /* load false and skip next i. */
818 p_t = code_loadbool(fs, reg, 1, 0); 818 p_t = code_loadbool(fs, reg, 1, 0); /* load true */
819 /* jump around these booleans if 'e' is not a test */
819 luaK_patchtohere(fs, fj); 820 luaK_patchtohere(fs, fj);
820 } 821 }
821 final = luaK_getlabel(fs); 822 final = luaK_getlabel(fs);
@@ -1005,13 +1006,13 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
1005 Instruction ie = getinstruction(fs, e); 1006 Instruction ie = getinstruction(fs, e);
1006 if (GET_OPCODE(ie) == OP_NOT) { 1007 if (GET_OPCODE(ie) == OP_NOT) {
1007 removelastinstruction(fs); /* remove previous OP_NOT */ 1008 removelastinstruction(fs); /* remove previous OP_NOT */
1008 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); 1009 return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond);
1009 } 1010 }
1010 /* else go through */ 1011 /* else go through */
1011 } 1012 }
1012 discharge2anyreg(fs, e); 1013 discharge2anyreg(fs, e);
1013 freeexp(fs, e); 1014 freeexp(fs, e);
1014 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); 1015 return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond);
1015} 1016}
1016 1017
1017 1018
@@ -1139,13 +1140,15 @@ static int isSCint (expdesc *e) {
1139 1140
1140/* 1141/*
1141** Check whether expression 'e' is a literal integer or float in 1142** Check whether expression 'e' is a literal integer or float in
1142** proper range to fit in register sC 1143** proper range to fit in a register (sB or sC).
1143*/ 1144*/
1144static int isSCnumber (expdesc *e, lua_Integer *i) { 1145static int isSCnumber (expdesc *e, lua_Integer *i, int *isfloat) {
1145 if (e->k == VKINT) 1146 if (e->k == VKINT)
1146 *i = e->u.ival; 1147 *i = e->u.ival;
1147 else if (!(e->k == VKFLT && floatI(e->u.nval, i))) 1148 else if (!(e->k == VKFLT && floatI(e->u.nval, i)))
1148 return 0; /* not a number */ 1149 return 0; /* not a number */
1150 else
1151 *isfloat = 1;
1149 if (!hasjumps(e) && fitsC(*i)) { 1152 if (!hasjumps(e) && fitsC(*i)) {
1150 *i += OFFSET_sC; 1153 *i += OFFSET_sC;
1151 return 1; 1154 return 1;
@@ -1372,21 +1375,20 @@ static void codeshift (FuncState *fs, OpCode op,
1372 1375
1373 1376
1374/* 1377/*
1375** Emit code for order comparisons. 1378** Emit code for order comparisons. When using an immediate operand,
1376** When the first operand A is an integral value in the proper range, 1379** 'isfloat' tells whether the original value was a float.
1377** change (A < B) to (B > A) and (A <= B) to (B >= A) so that
1378** it can use an immediate operand.
1379*/ 1380*/
1380static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { 1381static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1381 int r1, r2; 1382 int r1, r2;
1382 lua_Integer im; 1383 lua_Integer im;
1383 if (isSCnumber(e2, &im)) { 1384 int isfloat = 0;
1385 if (isSCnumber(e2, &im, &isfloat)) {
1384 /* use immediate operand */ 1386 /* use immediate operand */
1385 r1 = luaK_exp2anyreg(fs, e1); 1387 r1 = luaK_exp2anyreg(fs, e1);
1386 r2 = cast_int(im); 1388 r2 = cast_int(im);
1387 op = cast(OpCode, (op - OP_LT) + OP_LTI); 1389 op = cast(OpCode, (op - OP_LT) + OP_LTI);
1388 } 1390 }
1389 else if (isSCnumber(e1, &im)) { 1391 else if (isSCnumber(e1, &im, &isfloat)) {
1390 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ 1392 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
1391 r1 = luaK_exp2anyreg(fs, e2); 1393 r1 = luaK_exp2anyreg(fs, e2);
1392 r2 = cast_int(im); 1394 r2 = cast_int(im);
@@ -1397,7 +1399,7 @@ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1397 r2 = luaK_exp2anyreg(fs, e2); 1399 r2 = luaK_exp2anyreg(fs, e2);
1398 } 1400 }
1399 freeexps(fs, e1, e2); 1401 freeexps(fs, e1, e2);
1400 e1->u.info = condjump(fs, op, r1, r2, 1); 1402 e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
1401 e1->k = VJMP; 1403 e1->k = VJMP;
1402} 1404}
1403 1405
@@ -1409,13 +1411,14 @@ static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
1409static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { 1411static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1410 int r1, r2; 1412 int r1, r2;
1411 lua_Integer im; 1413 lua_Integer im;
1414 int isfloat = 0; /* not needed here, but kept for symmetry */
1412 OpCode op; 1415 OpCode op;
1413 if (e1->k != VNONRELOC) { 1416 if (e1->k != VNONRELOC) {
1414 lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); 1417 lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT);
1415 swapexps(e1, e2); 1418 swapexps(e1, e2);
1416 } 1419 }
1417 r1 = luaK_exp2anyreg(fs, e1); /* 1nd expression must be in register */ 1420 r1 = luaK_exp2anyreg(fs, e1); /* 1nd expression must be in register */
1418 if (isSCnumber(e2, &im)) { 1421 if (isSCnumber(e2, &im, &isfloat)) {
1419 op = OP_EQI; 1422 op = OP_EQI;
1420 r2 = cast_int(im); /* immediate operand */ 1423 r2 = cast_int(im); /* immediate operand */
1421 } 1424 }
@@ -1428,7 +1431,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1428 r2 = luaK_exp2anyreg(fs, e2); 1431 r2 = luaK_exp2anyreg(fs, e2);
1429 } 1432 }
1430 freeexps(fs, e1, e2); 1433 freeexps(fs, e1, e2);
1431 e1->u.info = condjump(fs, op, r1, r2, (opr == OPR_EQ)); 1434 e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ));
1432 e1->k = VJMP; 1435 e1->k = VJMP;
1433} 1436}
1434 1437
@@ -1489,7 +1492,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1489 case OPR_LT: case OPR_LE: 1492 case OPR_LT: case OPR_LE:
1490 case OPR_GT: case OPR_GE: { 1493 case OPR_GT: case OPR_GE: {
1491 lua_Integer dummy; 1494 lua_Integer dummy;
1492 if (!isSCnumber(v, &dummy)) 1495 int dummy2;
1496 if (!isSCnumber(v, &dummy, &dummy2))
1493 luaK_exp2anyreg(fs, v); 1497 luaK_exp2anyreg(fs, v);
1494 /* else keep numeral, which may be an immediate operand */ 1498 /* else keep numeral, which may be an immediate operand */
1495 break; 1499 break;
diff --git a/ljumptab.h b/ljumptab.h
index fa4277cc..2d4cf28b 100644
--- a/ljumptab.h
+++ b/ljumptab.h
@@ -107,7 +107,7 @@ static void *disptab[NUM_OPCODES] = {
107&&L_OP_SETLIST, 107&&L_OP_SETLIST,
108&&L_OP_CLOSURE, 108&&L_OP_CLOSURE,
109&&L_OP_VARARG, 109&&L_OP_VARARG,
110&&L_OP_PREPVARARG, 110&&L_OP_VARARGPREP,
111&&L_OP_EXTRAARG 111&&L_OP_EXTRAARG
112 112
113}; 113};
diff --git a/llimits.h b/llimits.h
index 9d35d1c7..155bb160 100644
--- a/llimits.h
+++ b/llimits.h
@@ -325,6 +325,8 @@ typedef l_uint32 Instruction;
325#define luai_numeq(a,b) ((a)==(b)) 325#define luai_numeq(a,b) ((a)==(b))
326#define luai_numlt(a,b) ((a)<(b)) 326#define luai_numlt(a,b) ((a)<(b))
327#define luai_numle(a,b) ((a)<=(b)) 327#define luai_numle(a,b) ((a)<=(b))
328#define luai_numgt(a,b) ((a)>(b))
329#define luai_numge(a,b) ((a)>=(b))
328#define luai_numisnan(a) (!luai_numeq((a), (a))) 330#define luai_numisnan(a) (!luai_numeq((a), (a)))
329#endif 331#endif
330 332
diff --git a/lopcodes.c b/lopcodes.c
index c35a0aaf..23c3a6e4 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -101,7 +101,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
101 ,opmode(0, 1, 0, 0, iABC) /* OP_SETLIST */ 101 ,opmode(0, 1, 0, 0, iABC) /* OP_SETLIST */
102 ,opmode(0, 0, 0, 1, iABx) /* OP_CLOSURE */ 102 ,opmode(0, 0, 0, 1, iABx) /* OP_CLOSURE */
103 ,opmode(1, 0, 0, 1, iABC) /* OP_VARARG */ 103 ,opmode(1, 0, 0, 1, iABC) /* OP_VARARG */
104 ,opmode(0, 0, 0, 1, iABC) /* OP_PREPVARARG */ 104 ,opmode(0, 0, 0, 1, iABC) /* OP_VARARGPREP */
105 ,opmode(0, 0, 0, 0, iAx) /* OP_EXTRAARG */ 105 ,opmode(0, 0, 0, 0, iAx) /* OP_EXTRAARG */
106}; 106};
107 107
diff --git a/lopcodes.h b/lopcodes.h
index f867a01b..bbdd6897 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -294,7 +294,7 @@ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
294 294
295OP_VARARG,/* A C R(A), R(A+1), ..., R(A+C-2) = vararg */ 295OP_VARARG,/* A C R(A), R(A+1), ..., R(A+C-2) = vararg */
296 296
297OP_PREPVARARG,/*A (adjust vararg parameters) */ 297OP_VARARGPREP,/*A (adjust vararg parameters) */
298 298
299OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ 299OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
300} OpCode; 300} OpCode;
@@ -331,6 +331,9 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
331 C > 0 means the function is vararg and (C - 1) is its number of 331 C > 0 means the function is vararg and (C - 1) is its number of
332 fixed parameters. 332 fixed parameters.
333 333
334 (*) In comparisons with an immediate operand, C signals whether the
335 original operand was a float.
336
334===========================================================================*/ 337===========================================================================*/
335 338
336 339
diff --git a/lopnames.h b/lopnames.h
index dfca34d1..28535fe2 100644
--- a/lopnames.h
+++ b/lopnames.h
@@ -92,7 +92,7 @@ static const char *const opnames[] = {
92 "SETLIST", 92 "SETLIST",
93 "CLOSURE", 93 "CLOSURE",
94 "VARARG", 94 "VARARG",
95 "PREPVARARG", 95 "VARARGPREP",
96 "EXTRAARG", 96 "EXTRAARG",
97 NULL 97 NULL
98}; 98};
diff --git a/lparser.c b/lparser.c
index 8ffd9742..4c2ddbfe 100644
--- a/lparser.c
+++ b/lparser.c
@@ -817,7 +817,7 @@ static void constructor (LexState *ls, expdesc *t) {
817 817
818static void setvararg (FuncState *fs, int nparams) { 818static void setvararg (FuncState *fs, int nparams) {
819 fs->f->is_vararg = 1; 819 fs->f->is_vararg = 1;
820 luaK_codeABC(fs, OP_PREPVARARG, nparams, 0, 0); 820 luaK_codeABC(fs, OP_VARARGPREP, nparams, 0, 0);
821} 821}
822 822
823 823
diff --git a/ltm.c b/ltm.c
index 23a97a62..c4fd762b 100644
--- a/ltm.c
+++ b/ltm.c
@@ -205,9 +205,13 @@ int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
205 205
206 206
207int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 207int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
208 int inv, TMS event) { 208 int inv, int isfloat, TMS event) {
209 TValue aux; const TValue *p2; 209 TValue aux; const TValue *p2;
210 setivalue(&aux, v2); 210 if (isfloat) {
211 setfltvalue(&aux, cast_num(v2));
212 }
213 else
214 setivalue(&aux, v2);
211 if (inv) { /* arguments were exchanged? */ 215 if (inv) { /* arguments were exchanged? */
212 p2 = p1; p1 = &aux; /* correct them */ 216 p2 = p1; p1 = &aux; /* correct them */
213 } 217 }
diff --git a/ltm.h b/ltm.h
index fad47842..e308fb80 100644
--- a/ltm.h
+++ b/ltm.h
@@ -82,7 +82,7 @@ LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2,
82LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 82LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
83 const TValue *p2, TMS event); 83 const TValue *p2, TMS event);
84LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, 84LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
85 int inv, TMS event); 85 int inv, int isfloat, TMS event);
86 86
87LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, 87LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
88 struct CallInfo *ci, const Proto *p); 88 struct CallInfo *ci, const Proto *p);
diff --git a/lvm.c b/lvm.c
index 31b4dc36..47bc67c9 100644
--- a/lvm.c
+++ b/lvm.c
@@ -772,11 +772,10 @@ void luaV_finishOp (lua_State *L) {
772 772
773/* 773/*
774** {================================================================== 774** {==================================================================
775** Macros for arithmetic/bitwise opcodes in 'luaV_execute' 775** Macros for arithmetic/bitwise/comparison opcodes in 'luaV_execute'
776** =================================================================== 776** ===================================================================
777*/ 777*/
778 778
779
780#define l_addi(L,a,b) intop(+, a, b) 779#define l_addi(L,a,b) intop(+, a, b)
781#define l_subi(L,a,b) intop(-, a, b) 780#define l_subi(L,a,b) intop(-, a, b)
782#define l_muli(L,a,b) intop(*, a, b) 781#define l_muli(L,a,b) intop(*, a, b)
@@ -784,6 +783,11 @@ void luaV_finishOp (lua_State *L) {
784#define l_bor(L,a,b) intop(|, a, b) 783#define l_bor(L,a,b) intop(|, a, b)
785#define l_bxor(L,a,b) intop(^, a, b) 784#define l_bxor(L,a,b) intop(^, a, b)
786 785
786#define l_lti(a,b) (a < b)
787#define l_lei(a,b) (a <= b)
788#define l_gti(a,b) (a > b)
789#define l_gei(a,b) (a >= b)
790
787 791
788/* 792/*
789** Auxiliary macro for arithmetic operations over floats and others 793** Auxiliary macro for arithmetic operations over floats and others
@@ -916,6 +920,36 @@ void luaV_finishOp (lua_State *L) {
916 else \ 920 else \
917 Protect(luaT_trybinTM(L, v1, v2, ra, tm)); } 921 Protect(luaT_trybinTM(L, v1, v2, ra, tm)); }
918 922
923
924/*
925** Order operations with register operands.
926*/
927#define op_order(L,opi,opf,other) { \
928 TValue *rb = vRB(i); \
929 if (ttisinteger(s2v(ra)) && ttisinteger(rb)) \
930 cond = opi(ivalue(s2v(ra)), ivalue(rb)); \
931 else if (ttisnumber(s2v(ra)) && ttisnumber(rb)) \
932 cond = opf(s2v(ra), rb); \
933 else \
934 Protect(cond = other(L, s2v(ra), rb)); \
935 docondjump(); }
936
937
938/*
939** Order operations with immediate operand.
940*/
941#define op_orderI(L,opi,opf,inv,tm) { \
942 int im = GETARG_sB(i); \
943 if (ttisinteger(s2v(ra))) \
944 cond = opi(ivalue(s2v(ra)), im); \
945 else if (ttisfloat(s2v(ra))) \
946 cond = opf(fltvalue(s2v(ra)), cast_num(im)); \
947 else { \
948 int isf = GETARG_C(i); \
949 Protect(cond = luaT_callorderiTM(L, s2v(ra), im, inv, isf, tm)); \
950 } \
951 docondjump(); }
952
919/* }================================================================== */ 953/* }================================================================== */
920 954
921 955
@@ -1034,7 +1068,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1034 pc = ci->u.l.savedpc; 1068 pc = ci->u.l.savedpc;
1035 if (trap) { 1069 if (trap) {
1036 if (cl->p->is_vararg) 1070 if (cl->p->is_vararg)
1037 trap = 0; /* hooks will start after PREPVARARG instruction */ 1071 trap = 0; /* hooks will start after VARARGPREP instruction */
1038 else if (pc == cl->p->code) /* first instruction (not resuming)? */ 1072 else if (pc == cl->p->code) /* first instruction (not resuming)? */
1039 luaD_hookcall(L, ci); 1073 luaD_hookcall(L, ci);
1040 ci->u.l.trap = 1; /* there may be other hooks */ 1074 ci->u.l.trap = 1; /* there may be other hooks */
@@ -1447,25 +1481,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1447 vmbreak; 1481 vmbreak;
1448 } 1482 }
1449 vmcase(OP_LT) { 1483 vmcase(OP_LT) {
1450 TValue *rb = vRB(i); 1484 op_order(L, l_lti, LTnum, lessthanothers);
1451 if (ttisinteger(s2v(ra)) && ttisinteger(rb))
1452 cond = (ivalue(s2v(ra)) < ivalue(rb));
1453 else if (ttisnumber(s2v(ra)) && ttisnumber(rb))
1454 cond = LTnum(s2v(ra), rb);
1455 else
1456 Protect(cond = lessthanothers(L, s2v(ra), rb));
1457 docondjump();
1458 vmbreak; 1485 vmbreak;
1459 } 1486 }
1460 vmcase(OP_LE) { 1487 vmcase(OP_LE) {
1461 TValue *rb = vRB(i); 1488 op_order(L, l_lei, LEnum, lessequalothers);
1462 if (ttisinteger(s2v(ra)) && ttisinteger(rb))
1463 cond = (ivalue(s2v(ra)) <= ivalue(rb));
1464 else if (ttisnumber(s2v(ra)) && ttisnumber(rb))
1465 cond = LEnum(s2v(ra), rb);
1466 else
1467 Protect(cond = lessequalothers(L, s2v(ra), rb));
1468 docondjump();
1469 vmbreak; 1489 vmbreak;
1470 } 1490 }
1471 vmcase(OP_EQK) { 1491 vmcase(OP_EQK) {
@@ -1487,47 +1507,19 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1487 vmbreak; 1507 vmbreak;
1488 } 1508 }
1489 vmcase(OP_LTI) { 1509 vmcase(OP_LTI) {
1490 int im = GETARG_sB(i); 1510 op_orderI(L, l_lti, luai_numlt, 0, TM_LT);
1491 if (ttisinteger(s2v(ra)))
1492 cond = (ivalue(s2v(ra)) < im);
1493 else if (ttisfloat(s2v(ra)))
1494 cond = luai_numlt(fltvalue(s2v(ra)), cast_num(im));
1495 else
1496 Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 0, TM_LT));
1497 docondjump();
1498 vmbreak; 1511 vmbreak;
1499 } 1512 }
1500 vmcase(OP_LEI) { 1513 vmcase(OP_LEI) {
1501 int im = GETARG_sB(i); 1514 op_orderI(L, l_lei, luai_numle, 0, TM_LE);
1502 if (ttisinteger(s2v(ra)))
1503 cond = (ivalue(s2v(ra)) <= im);
1504 else if (ttisfloat(s2v(ra)))
1505 cond = luai_numle(fltvalue(s2v(ra)), cast_num(im));
1506 else
1507 Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 0, TM_LE));
1508 docondjump();
1509 vmbreak; 1515 vmbreak;
1510 } 1516 }
1511 vmcase(OP_GTI) { 1517 vmcase(OP_GTI) {
1512 int im = GETARG_sB(i); 1518 op_orderI(L, l_gti, luai_numgt, 1, TM_LT);
1513 if (ttisinteger(s2v(ra)))
1514 cond = (im < ivalue(s2v(ra)));
1515 else if (ttisfloat(s2v(ra)))
1516 cond = luai_numlt(cast_num(im), fltvalue(s2v(ra)));
1517 else
1518 Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 1, TM_LT));
1519 docondjump();
1520 vmbreak; 1519 vmbreak;
1521 } 1520 }
1522 vmcase(OP_GEI) { 1521 vmcase(OP_GEI) {
1523 int im = GETARG_sB(i); 1522 op_orderI(L, l_gei, luai_numge, 1, TM_LE);
1524 if (ttisinteger(s2v(ra)))
1525 cond = (im <= ivalue(s2v(ra)));
1526 else if (ttisfloat(s2v(ra)))
1527 cond = luai_numle(cast_num(im), fltvalue(s2v(ra)));
1528 else
1529 Protect(cond = luaT_callorderiTM(L, s2v(ra), im, 1, TM_LE));
1530 docondjump();
1531 vmbreak; 1523 vmbreak;
1532 } 1524 }
1533 vmcase(OP_TEST) { 1525 vmcase(OP_TEST) {
@@ -1787,7 +1779,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1787 Protect(luaT_getvarargs(L, ci, ra, n)); 1779 Protect(luaT_getvarargs(L, ci, ra, n));
1788 vmbreak; 1780 vmbreak;
1789 } 1781 }
1790 vmcase(OP_PREPVARARG) { 1782 vmcase(OP_VARARGPREP) {
1791 luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p); 1783 luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p);
1792 updatetrap(ci); 1784 updatetrap(ci);
1793 if (trap) { 1785 if (trap) {
diff --git a/onelua.c b/onelua.c
new file mode 100644
index 00000000..3c605981
--- /dev/null
+++ b/onelua.c
@@ -0,0 +1,107 @@
1/*
2* one.c -- Lua core, libraries, and interpreter in a single file
3*/
4
5/* default is to build the full interpreter */
6#ifndef MAKE_LIB
7#ifndef MAKE_LUAC
8#ifndef MAKE_LUA
9#define MAKE_LUA
10#endif
11#endif
12#endif
13
14/* choose suitable platform-specific features */
15/* some of these may need extra libraries such as -ldl -lreadline -lncurses */
16#if 0
17#define LUA_USE_LINUX
18#define LUA_USE_MACOSX
19#define LUA_USE_POSIX
20#define LUA_ANSI
21#endif
22
23/* no need to change anything below this line ----------------------------- */
24
25#include "lprefix.h"
26
27#include <assert.h>
28#include <ctype.h>
29#include <errno.h>
30#include <float.h>
31#include <limits.h>
32#include <locale.h>
33#include <math.h>
34#include <setjmp.h>
35#include <signal.h>
36#include <stdarg.h>
37#include <stddef.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <time.h>
42
43
44/* setup for luaconf.h */
45#define LUA_CORE
46#define LUA_LIB
47#define ltable_c
48#define lvm_c
49#include "luaconf.h"
50
51/* do not export internal symbols */
52#undef LUAI_FUNC
53#undef LUAI_DDEC
54#undef LUAI_DDEF
55#define LUAI_FUNC static
56#define LUAI_DDEC(def) /* empty */
57#define LUAI_DDEF static
58
59/* core -- used by all */
60#include "lzio.c"
61#include "lctype.c"
62#include "lopcodes.c"
63#include "lmem.c"
64#include "lundump.c"
65#include "ldump.c"
66#include "lstate.c"
67#include "lgc.c"
68#include "llex.c"
69#include "lcode.c"
70#include "lparser.c"
71#include "ldebug.c"
72#include "lfunc.c"
73#include "lobject.c"
74#include "ltm.c"
75#include "lstring.c"
76#include "ltable.c"
77#include "ldo.c"
78#include "lvm.c"
79#include "lapi.c"
80
81/* auxiliary library -- used by all */
82#include "lauxlib.c"
83
84/* standard library -- not used by luac */
85#ifndef MAKE_LUAC
86#include "lbaselib.c"
87#include "lcorolib.c"
88#include "ldblib.c"
89#include "liolib.c"
90#include "lmathlib.c"
91#include "loadlib.c"
92#include "loslib.c"
93#include "lstrlib.c"
94#include "ltablib.c"
95#include "lutf8lib.c"
96#include "linit.c"
97#endif
98
99/* lua */
100#ifdef MAKE_LUA
101#include "lua.c"
102#endif
103
104/* luac */
105#ifdef MAKE_LUAC
106#include "luac.c"
107#endif
diff --git a/testes/db.lua b/testes/db.lua
index 0858dd20..95275fb4 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -162,7 +162,7 @@ test([[for i,v in pairs{'a','b'} do
162end 162end
163]], {1,2,1,2,1,3}) 163]], {1,2,1,2,1,3})
164 164
165test([[for i=1,4 do a=1 end]], {1,1,1,1}, true) 165test([[for i=1,4 do a=1 end]], {1,1,1,1})
166 166
167 167
168do -- testing line info/trace with large gaps in source 168do -- testing line info/trace with large gaps in source
diff --git a/testes/events.lua b/testes/events.lua
index ac630d89..cf68d1e9 100644
--- a/testes/events.lua
+++ b/testes/events.lua
@@ -138,64 +138,55 @@ t.__bxor = f("bxor")
138t.__shl = f("shl") 138t.__shl = f("shl")
139t.__shr = f("shr") 139t.__shr = f("shr")
140t.__bnot = f("bnot") 140t.__bnot = f("bnot")
141t.__lt = f("lt")
142t.__le = f("le")
143
144
145local function checkcap (t)
146 assert(#cap + 1 == #t)
147 for i = 1, #t do
148 assert(cap[i - 1] == t[i])
149 assert(math.type(cap[i - 1]) == math.type(t[i]))
150 end
151end
141 152
142-- Some tests are done inside small anonymous functions to ensure 153-- Some tests are done inside small anonymous functions to ensure
143-- that constants go to constant table even in debug compilation, 154-- that constants go to constant table even in debug compilation,
144-- when the constant table is very small. 155-- when the constant table is very small.
145assert(b+5 == b) 156assert(b+5 == b); checkcap{"add", b, 5}
146assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==undef) 157assert(5.2 + b == 5.2); checkcap{"add", 5.2, b}
147assert(5.2 + b == 5.2) 158assert(b+'5' == b); checkcap{"add", b, '5'}
148assert(cap[0] == "add" and cap[1] == 5.2 and cap[2] == b and cap[3]==undef) 159assert(5+b == 5); checkcap{"add", 5, b}
149assert(b+'5' == b) 160assert('5'+b == '5'); checkcap{"add", '5', b}
150assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==undef) 161b=b-3; assert(getmetatable(b) == t); checkcap{"sub", b, 3}
151assert(5+b == 5) 162assert(5-a == 5); checkcap{"sub", 5, a}
152assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==undef) 163assert('5'-a == '5'); checkcap{"sub", '5', a}
153assert('5'+b == '5') 164assert(a*a == a); checkcap{"mul", a, a}
154assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==undef) 165assert(a/0 == a); checkcap{"div", a, 0}
155b=b-3; assert(getmetatable(b) == t) 166assert(a/0.0 == a); checkcap{"div", a, 0.0}
156assert(cap[0] == "sub" and cap[1] == b and cap[2] == 3 and cap[3]==undef) 167assert(a%2 == a); checkcap{"mod", a, 2}
157assert(5-a == 5) 168assert(a // (1/0) == a); checkcap{"idiv", a, 1/0}
158assert(cap[0] == "sub" and cap[1] == 5 and cap[2] == a and cap[3]==undef) 169;(function () assert(a & "hi" == a) end)(); checkcap{"band", a, "hi"}
159assert('5'-a == '5') 170;(function () assert(10 & a == 10) end)(); checkcap{"band", 10, a}
160assert(cap[0] == "sub" and cap[1] == '5' and cap[2] == a and cap[3]==undef) 171;(function () assert(a | 10 == a) end)(); checkcap{"bor", a, 10}
161assert(a*a == a) 172assert(a | "hi" == a); checkcap{"bor", a, "hi"}
162assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==undef) 173assert("hi" ~ a == "hi"); checkcap{"bxor", "hi", a}
163assert(a/0 == a) 174;(function () assert(10 ~ a == 10) end)(); checkcap{"bxor", 10, a}
164assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==undef) 175assert(-a == a); checkcap{"unm", a, a}
165assert(a%2 == a) 176assert(a^4.0 == a); checkcap{"pow", a, 4.0}
166assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==undef) 177assert(a^'4' == a); checkcap{"pow", a, '4'}
167assert(a // (1/0) == a) 178assert(4^a == 4); checkcap{"pow", 4, a}
168assert(cap[0] == "idiv" and cap[1] == a and cap[2] == 1/0 and cap[3]==undef) 179assert('4'^a == '4'); checkcap{"pow", '4', a}
169;(function () assert(a & "hi" == a) end)() 180assert(#a == a); checkcap{"len", a, a}
170assert(cap[0] == "band" and cap[1] == a and cap[2] == "hi" and cap[3]==undef) 181assert(~a == a); checkcap{"bnot", a, a}
171;(function () assert(10 & a == 10) end)() 182assert(a << 3 == a); checkcap{"shl", a, 3}
172assert(cap[0] == "band" and cap[1] == 10 and cap[2] == a and cap[3]==undef) 183assert(1.5 >> a == 1.5); checkcap{"shr", 1.5, a}
173;(function () assert(a | 10 == a) end)() 184
174assert(cap[0] == "bor" and cap[1] == a and cap[2] == 10 and cap[3]==undef) 185-- for comparsion operators, all results are true
175assert(a | "hi" == a) 186assert(5.0 > a); checkcap{"lt", a, 5.0}
176assert(cap[0] == "bor" and cap[1] == a and cap[2] == "hi" and cap[3]==undef) 187assert(a >= 10); checkcap{"le", 10, a}
177assert("hi" ~ a == "hi") 188assert(a <= -10.0); checkcap{"le", a, -10.0}
178assert(cap[0] == "bxor" and cap[1] == "hi" and cap[2] == a and cap[3]==undef) 189assert(a < -10); checkcap{"lt", a, -10}
179;(function () assert(10 ~ a == 10) end)()
180assert(cap[0] == "bxor" and cap[1] == 10 and cap[2] == a and cap[3]==undef)
181assert(-a == a)
182assert(cap[0] == "unm" and cap[1] == a)
183assert(a^4 == a)
184assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==undef)
185assert(a^'4' == a)
186assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==undef)
187assert(4^a == 4)
188assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==undef)
189assert('4'^a == '4')
190assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==undef)
191assert(#a == a)
192assert(cap[0] == "len" and cap[1] == a)
193assert(~a == a)
194assert(cap[0] == "bnot" and cap[1] == a)
195assert(a << 3 == a)
196assert(cap[0] == "shl" and cap[1] == a and cap[2] == 3)
197assert(1.5 >> a == 1.5)
198assert(cap[0] == "shr" and cap[1] == 1.5 and cap[2] == a)
199 190
200 191
201-- test for rawlen 192-- test for rawlen