diff options
-rw-r--r-- | lcode.c | 42 | ||||
-rw-r--r-- | ljumptab.h | 2 | ||||
-rw-r--r-- | llimits.h | 2 | ||||
-rw-r--r-- | lopcodes.c | 2 | ||||
-rw-r--r-- | lopcodes.h | 5 | ||||
-rw-r--r-- | lopnames.h | 2 | ||||
-rw-r--r-- | lparser.c | 2 | ||||
-rw-r--r-- | ltm.c | 8 | ||||
-rw-r--r-- | ltm.h | 2 | ||||
-rw-r--r-- | lvm.c | 96 | ||||
-rw-r--r-- | onelua.c | 107 | ||||
-rw-r--r-- | testes/db.lua | 2 | ||||
-rw-r--r-- | testes/events.lua | 99 |
13 files changed, 237 insertions, 134 deletions
@@ -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 | */ |
182 | static int condjump (FuncState *fs, OpCode op, int A, int B, int k) { | 182 | static 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 | */ |
1144 | static int isSCnumber (expdesc *e, lua_Integer *i) { | 1145 | static 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 | */ |
1380 | static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { | 1381 | static 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) { | |||
1409 | static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | 1411 | static 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; |
@@ -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 | }; |
@@ -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 | ||
@@ -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 | ||
@@ -294,7 +294,7 @@ OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ | |||
294 | 294 | ||
295 | OP_VARARG,/* A C R(A), R(A+1), ..., R(A+C-2) = vararg */ | 295 | OP_VARARG,/* A C R(A), R(A+1), ..., R(A+C-2) = vararg */ |
296 | 296 | ||
297 | OP_PREPVARARG,/*A (adjust vararg parameters) */ | 297 | OP_VARARGPREP,/*A (adjust vararg parameters) */ |
298 | 298 | ||
299 | OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ | 299 | OP_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 | ||
@@ -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 | }; |
@@ -817,7 +817,7 @@ static void constructor (LexState *ls, expdesc *t) { | |||
817 | 817 | ||
818 | static void setvararg (FuncState *fs, int nparams) { | 818 | static 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 | ||
@@ -205,9 +205,13 @@ int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, | |||
205 | 205 | ||
206 | 206 | ||
207 | int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | 207 | int 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 | } |
@@ -82,7 +82,7 @@ LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, | |||
82 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, | 82 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, |
83 | const TValue *p2, TMS event); | 83 | const TValue *p2, TMS event); |
84 | LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | 84 | LUAI_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 | ||
87 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, | 87 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, |
88 | struct CallInfo *ci, const Proto *p); | 88 | struct CallInfo *ci, const Proto *p); |
@@ -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 | |||
162 | end | 162 | end |
163 | ]], {1,2,1,2,1,3}) | 163 | ]], {1,2,1,2,1,3}) |
164 | 164 | ||
165 | test([[for i=1,4 do a=1 end]], {1,1,1,1}, true) | 165 | test([[for i=1,4 do a=1 end]], {1,1,1,1}) |
166 | 166 | ||
167 | 167 | ||
168 | do -- testing line info/trace with large gaps in source | 168 | do -- 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") | |||
138 | t.__shl = f("shl") | 138 | t.__shl = f("shl") |
139 | t.__shr = f("shr") | 139 | t.__shr = f("shr") |
140 | t.__bnot = f("bnot") | 140 | t.__bnot = f("bnot") |
141 | t.__lt = f("lt") | ||
142 | t.__le = f("le") | ||
143 | |||
144 | |||
145 | local 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 | ||
151 | end | ||
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. |
145 | assert(b+5 == b) | 156 | assert(b+5 == b); checkcap{"add", b, 5} |
146 | assert(cap[0] == "add" and cap[1] == b and cap[2] == 5 and cap[3]==undef) | 157 | assert(5.2 + b == 5.2); checkcap{"add", 5.2, b} |
147 | assert(5.2 + b == 5.2) | 158 | assert(b+'5' == b); checkcap{"add", b, '5'} |
148 | assert(cap[0] == "add" and cap[1] == 5.2 and cap[2] == b and cap[3]==undef) | 159 | assert(5+b == 5); checkcap{"add", 5, b} |
149 | assert(b+'5' == b) | 160 | assert('5'+b == '5'); checkcap{"add", '5', b} |
150 | assert(cap[0] == "add" and cap[1] == b and cap[2] == '5' and cap[3]==undef) | 161 | b=b-3; assert(getmetatable(b) == t); checkcap{"sub", b, 3} |
151 | assert(5+b == 5) | 162 | assert(5-a == 5); checkcap{"sub", 5, a} |
152 | assert(cap[0] == "add" and cap[1] == 5 and cap[2] == b and cap[3]==undef) | 163 | assert('5'-a == '5'); checkcap{"sub", '5', a} |
153 | assert('5'+b == '5') | 164 | assert(a*a == a); checkcap{"mul", a, a} |
154 | assert(cap[0] == "add" and cap[1] == '5' and cap[2] == b and cap[3]==undef) | 165 | assert(a/0 == a); checkcap{"div", a, 0} |
155 | b=b-3; assert(getmetatable(b) == t) | 166 | assert(a/0.0 == a); checkcap{"div", a, 0.0} |
156 | assert(cap[0] == "sub" and cap[1] == b and cap[2] == 3 and cap[3]==undef) | 167 | assert(a%2 == a); checkcap{"mod", a, 2} |
157 | assert(5-a == 5) | 168 | assert(a // (1/0) == a); checkcap{"idiv", a, 1/0} |
158 | assert(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"} |
159 | assert('5'-a == '5') | 170 | ;(function () assert(10 & a == 10) end)(); checkcap{"band", 10, a} |
160 | assert(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} |
161 | assert(a*a == a) | 172 | assert(a | "hi" == a); checkcap{"bor", a, "hi"} |
162 | assert(cap[0] == "mul" and cap[1] == a and cap[2] == a and cap[3]==undef) | 173 | assert("hi" ~ a == "hi"); checkcap{"bxor", "hi", a} |
163 | assert(a/0 == a) | 174 | ;(function () assert(10 ~ a == 10) end)(); checkcap{"bxor", 10, a} |
164 | assert(cap[0] == "div" and cap[1] == a and cap[2] == 0 and cap[3]==undef) | 175 | assert(-a == a); checkcap{"unm", a, a} |
165 | assert(a%2 == a) | 176 | assert(a^4.0 == a); checkcap{"pow", a, 4.0} |
166 | assert(cap[0] == "mod" and cap[1] == a and cap[2] == 2 and cap[3]==undef) | 177 | assert(a^'4' == a); checkcap{"pow", a, '4'} |
167 | assert(a // (1/0) == a) | 178 | assert(4^a == 4); checkcap{"pow", 4, a} |
168 | assert(cap[0] == "idiv" and cap[1] == a and cap[2] == 1/0 and cap[3]==undef) | 179 | assert('4'^a == '4'); checkcap{"pow", '4', a} |
169 | ;(function () assert(a & "hi" == a) end)() | 180 | assert(#a == a); checkcap{"len", a, a} |
170 | assert(cap[0] == "band" and cap[1] == a and cap[2] == "hi" and cap[3]==undef) | 181 | assert(~a == a); checkcap{"bnot", a, a} |
171 | ;(function () assert(10 & a == 10) end)() | 182 | assert(a << 3 == a); checkcap{"shl", a, 3} |
172 | assert(cap[0] == "band" and cap[1] == 10 and cap[2] == a and cap[3]==undef) | 183 | assert(1.5 >> a == 1.5); checkcap{"shr", 1.5, a} |
173 | ;(function () assert(a | 10 == a) end)() | 184 | |
174 | assert(cap[0] == "bor" and cap[1] == a and cap[2] == 10 and cap[3]==undef) | 185 | -- for comparsion operators, all results are true |
175 | assert(a | "hi" == a) | 186 | assert(5.0 > a); checkcap{"lt", a, 5.0} |
176 | assert(cap[0] == "bor" and cap[1] == a and cap[2] == "hi" and cap[3]==undef) | 187 | assert(a >= 10); checkcap{"le", 10, a} |
177 | assert("hi" ~ a == "hi") | 188 | assert(a <= -10.0); checkcap{"le", a, -10.0} |
178 | assert(cap[0] == "bxor" and cap[1] == "hi" and cap[2] == a and cap[3]==undef) | 189 | assert(a < -10); checkcap{"lt", a, -10} |
179 | ;(function () assert(10 ~ a == 10) end)() | ||
180 | assert(cap[0] == "bxor" and cap[1] == 10 and cap[2] == a and cap[3]==undef) | ||
181 | assert(-a == a) | ||
182 | assert(cap[0] == "unm" and cap[1] == a) | ||
183 | assert(a^4 == a) | ||
184 | assert(cap[0] == "pow" and cap[1] == a and cap[2] == 4 and cap[3]==undef) | ||
185 | assert(a^'4' == a) | ||
186 | assert(cap[0] == "pow" and cap[1] == a and cap[2] == '4' and cap[3]==undef) | ||
187 | assert(4^a == 4) | ||
188 | assert(cap[0] == "pow" and cap[1] == 4 and cap[2] == a and cap[3]==undef) | ||
189 | assert('4'^a == '4') | ||
190 | assert(cap[0] == "pow" and cap[1] == '4' and cap[2] == a and cap[3]==undef) | ||
191 | assert(#a == a) | ||
192 | assert(cap[0] == "len" and cap[1] == a) | ||
193 | assert(~a == a) | ||
194 | assert(cap[0] == "bnot" and cap[1] == a) | ||
195 | assert(a << 3 == a) | ||
196 | assert(cap[0] == "shl" and cap[1] == a and cap[2] == 3) | ||
197 | assert(1.5 >> a == 1.5) | ||
198 | assert(cap[0] == "shr" and cap[1] == 1.5 and cap[2] == a) | ||
199 | 190 | ||
200 | 191 | ||
201 | -- test for rawlen | 192 | -- test for rawlen |