summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c8
-rw-r--r--lcode.c16
-rw-r--r--lcode.h5
-rw-r--r--llex.c15
-rw-r--r--llex.h3
-rw-r--r--lobject.c8
-rw-r--r--lopcodes.c8
-rw-r--r--lopcodes.h5
-rw-r--r--lparser.c18
-rw-r--r--ltests.c13
-rw-r--r--ltm.c23
-rw-r--r--ltm.h5
-rw-r--r--lua.h7
-rw-r--r--lvm.c51
-rw-r--r--lvm.h3
15 files changed, 139 insertions, 49 deletions
diff --git a/lapi.c b/lapi.c
index ca37dbee..de13bd62 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.190 2013/09/13 16:21:52 roberto Exp roberto $ 2** $Id: lapi.c,v 2.191 2013/12/04 12:15:22 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -299,9 +299,9 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
299 299
300LUA_API void lua_arith (lua_State *L, int op) { 300LUA_API void lua_arith (lua_State *L, int op) {
301 lua_lock(L); 301 lua_lock(L);
302 if (op != LUA_OPUNM) /* all other operations expect two operands */ 302 if (op != LUA_OPUNM && op != LUA_OPBNOT)
303 api_checknelems(L, 2); 303 api_checknelems(L, 2); /* all other operations expect two operands */
304 else { /* for unary minus, add fake 2nd operand */ 304 else { /* for unary operations, add fake 2nd operand */
305 api_checknelems(L, 1); 305 api_checknelems(L, 1);
306 setobjs2s(L, L->top, L->top - 1); 306 setobjs2s(L, L->top, L->top - 1);
307 L->top++; 307 L->top++;
diff --git a/lcode.c b/lcode.c
index 8b54d71d..2da5e73a 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.75 2013/12/18 14:12:03 roberto Exp roberto $ 2** $Id: lcode.c,v 2.76 2013/12/18 18:44:42 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -756,7 +756,8 @@ static int validop (OpCode op, TValue *v1, TValue *v2) {
756 switch (op) { 756 switch (op) {
757 case OP_IDIV: /* division by 0 and conversion errors */ 757 case OP_IDIV: /* division by 0 and conversion errors */
758 return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); 758 return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0);
759 case OP_BAND: case OP_BOR: case OP_BXOR: /* conversion errors */ 759 case OP_BAND: case OP_BOR: case OP_BXOR:
760 case OP_SHL: case OP_SHR: case OP_BNOT: /* conversion errors */
760 return (tointeger(v1, &i) && tointeger(v2, &i)); 761 return (tointeger(v1, &i) && tointeger(v2, &i));
761 case OP_MOD: /* integer module by 0 */ 762 case OP_MOD: /* integer module by 0 */
762 return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0); 763 return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0);
@@ -771,7 +772,6 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
771 TValue v1, v2, res; 772 TValue v1, v2, res;
772 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) 773 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
773 return 0; /* non-numeric operands or not safe to fold */ 774 return 0; /* non-numeric operands or not safe to fold */
774 lua_assert(OP_IDIV - OP_ADD + LUA_OPADD == LUA_OPIDIV);
775 luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res); 775 luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);
776 if (ttisinteger(&res)) { 776 if (ttisinteger(&res)) {
777 e1->k = VKINT; 777 e1->k = VKINT;
@@ -792,7 +792,7 @@ static void codearith (FuncState *fs, OpCode op,
792 expdesc *e1, expdesc *e2, int line) { 792 expdesc *e1, expdesc *e2, int line) {
793 if (!constfolding(op, e1, e2)) { /* could not fold operation? */ 793 if (!constfolding(op, e1, e2)) { /* could not fold operation? */
794 int o1, o2; 794 int o1, o2;
795 if (op == OP_UNM || op == OP_LEN) { 795 if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) {
796 o2 = 0; 796 o2 = 0;
797 o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ 797 o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
798 } 798 }
@@ -835,7 +835,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
835 expdesc e2; 835 expdesc e2;
836 e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; 836 e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
837 switch (op) { 837 switch (op) {
838 case OPR_MINUS: case OPR_LEN: { 838 case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
839 codearith(fs, op - OPR_MINUS + OP_UNM, e, &e2, line); 839 codearith(fs, op - OPR_MINUS + OP_UNM, e, &e2, line);
840 break; 840 break;
841 } 841 }
@@ -862,7 +862,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
862 case OPR_ADD: case OPR_SUB: 862 case OPR_ADD: case OPR_SUB:
863 case OPR_MUL: case OPR_DIV: case OPR_IDIV: 863 case OPR_MUL: case OPR_DIV: case OPR_IDIV:
864 case OPR_MOD: case OPR_POW: 864 case OPR_MOD: case OPR_POW:
865 case OPR_BAND: case OPR_BOR: case OPR_BXOR: { 865 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
866 case OPR_SHL: case OPR_SHR: {
866 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); 867 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
867 break; 868 break;
868 } 869 }
@@ -907,7 +908,8 @@ void luaK_posfix (FuncState *fs, BinOpr op,
907 } 908 }
908 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: 909 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
909 case OPR_IDIV: case OPR_MOD: case OPR_POW: 910 case OPR_IDIV: case OPR_MOD: case OPR_POW:
910 case OPR_BAND: case OPR_BOR: case OPR_BXOR: { 911 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
912 case OPR_SHL: case OPR_SHR: {
911 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); 913 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
912 break; 914 break;
913 } 915 }
diff --git a/lcode.h b/lcode.h
index 713f76aa..a3fdf520 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.61 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: lcode.h,v 1.62 2013/12/18 14:12:03 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -28,6 +28,7 @@ typedef enum BinOpr {
28 OPR_DIV, 28 OPR_DIV,
29 OPR_IDIV, 29 OPR_IDIV,
30 OPR_BAND, OPR_BOR, OPR_BXOR, 30 OPR_BAND, OPR_BOR, OPR_BXOR,
31 OPR_SHL, OPR_SHR,
31 OPR_CONCAT, 32 OPR_CONCAT,
32 OPR_EQ, OPR_LT, OPR_LE, 33 OPR_EQ, OPR_LT, OPR_LE,
33 OPR_NE, OPR_GT, OPR_GE, 34 OPR_NE, OPR_GT, OPR_GE,
@@ -36,7 +37,7 @@ typedef enum BinOpr {
36} BinOpr; 37} BinOpr;
37 38
38 39
39typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 40typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
40 41
41 42
42#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) 43#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
diff --git a/llex.c b/llex.c
index 7afe31b1..0a2d9916 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 2.68 2013/08/21 20:09:51 roberto Exp roberto $ 2** $Id: llex.c,v 2.69 2013/08/30 16:01:37 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -39,7 +39,8 @@ static const char *const luaX_tokens [] = {
39 "end", "false", "for", "function", "goto", "if", 39 "end", "false", "for", "function", "goto", "if",
40 "in", "local", "nil", "not", "or", "repeat", 40 "in", "local", "nil", "not", "or", "repeat",
41 "return", "then", "true", "until", "while", 41 "return", "then", "true", "until", "while",
42 "//", "..", "...", "==", ">=", "<=", "~=", "::", "<eof>", 42 "//", "..", "...", "==", ">=", "<=", "~=",
43 "<<", ">>", "::", "<eof>",
43 "<number>", "<number>", "<name>", "<string>" 44 "<number>", "<number>", "<name>", "<string>"
44}; 45};
45 46
@@ -462,13 +463,15 @@ static int llex (LexState *ls, SemInfo *seminfo) {
462 } 463 }
463 case '<': { 464 case '<': {
464 next(ls); 465 next(ls);
465 if (ls->current != '=') return '<'; 466 if (ls->current == '=') { next(ls); return TK_LE; }
466 else { next(ls); return TK_LE; } 467 if (ls->current == '<') { next(ls); return TK_SHL; }
468 return '<';
467 } 469 }
468 case '>': { 470 case '>': {
469 next(ls); 471 next(ls);
470 if (ls->current != '=') return '>'; 472 if (ls->current == '=') { next(ls); return TK_GE; }
471 else { next(ls); return TK_GE; } 473 if (ls->current == '>') { next(ls); return TK_SHR; }
474 return '>';
472 } 475 }
473 case '/': { 476 case '/': {
474 next(ls); 477 next(ls);
diff --git a/llex.h b/llex.h
index e9c1ed99..b79da192 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.74 2013/04/26 13:07:53 roberto Exp roberto $ 2** $Id: llex.h,v 1.75 2013/08/30 16:01:37 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,6 +27,7 @@ enum RESERVED {
27 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 27 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
28 /* other terminal symbols */ 28 /* other terminal symbols */
29 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 29 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
30 TK_SHL, TK_SHR,
30 TK_DBCOLON, TK_EOS, 31 TK_DBCOLON, TK_EOS,
31 TK_FLT, TK_INT, TK_NAME, TK_STRING 32 TK_FLT, TK_INT, TK_NAME, TK_STRING
32}; 33};
diff --git a/lobject.c b/lobject.c
index 92c4d678..80f495a4 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.69 2013/12/16 14:30:22 roberto Exp roberto $ 2** $Id: lobject.c,v 2.70 2013/12/18 14:12:03 roberto Exp roberto $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -82,7 +82,10 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
82 case LUA_OPBAND: return intop(&, v1, v2); 82 case LUA_OPBAND: return intop(&, v1, v2);
83 case LUA_OPBOR: return intop(|, v1, v2); 83 case LUA_OPBOR: return intop(|, v1, v2);
84 case LUA_OPBXOR: return intop(^, v1, v2); 84 case LUA_OPBXOR: return intop(^, v1, v2);
85 case LUA_OPSHL: return luaV_shiftl(v1, v2);
86 case LUA_OPSHR: return luaV_shiftl(v1, -v2);
85 case LUA_OPUNM: return intop(-, 0, v1); 87 case LUA_OPUNM: return intop(-, 0, v1);
88 case LUA_OPBNOT: return intop(^, cast_integer(-1), v1);
86 default: lua_assert(0); return 0; 89 default: lua_assert(0); return 0;
87 } 90 }
88} 91}
@@ -106,7 +109,8 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
106 TValue *res) { 109 TValue *res) {
107 switch (op) { 110 switch (op) {
108 case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR: 111 case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR:
109 case LUA_OPBXOR: { /* operates only on integers */ 112 case LUA_OPBXOR: case LUA_OPSHL: case LUA_OPSHR:
113 case LUA_OPBNOT: { /* operates only on integers */
110 lua_Integer i1; lua_Integer i2; 114 lua_Integer i1; lua_Integer i2;
111 if (tointeger(p1, &i1) && tointeger(p2, &i2)) { 115 if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
112 setivalue(res, intarith(L, op, i1, i2)); 116 setivalue(res, intarith(L, op, i1, i2));
diff --git a/lopcodes.c b/lopcodes.c
index ba7b9017..cf2c4d3d 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.51 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.52 2013/12/18 14:12:03 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -38,7 +38,10 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
38 "BAND", 38 "BAND",
39 "BOR", 39 "BOR",
40 "BXOR", 40 "BXOR",
41 "SHL",
42 "SHR",
41 "UNM", 43 "UNM",
44 "BNOT",
42 "NOT", 45 "NOT",
43 "LEN", 46 "LEN",
44 "CONCAT", 47 "CONCAT",
@@ -90,7 +93,10 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
90 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ 93 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */
91 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ 94 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */
92 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ 95 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */
96 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */
97 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */
93 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 98 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
99 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */
94 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 100 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
95 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 101 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
96 ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 102 ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
diff --git a/lopcodes.h b/lopcodes.h
index 6894f45f..632dee64 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.144 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.145 2013/12/18 14:12:03 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -194,7 +194,10 @@ OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */
194OP_BAND,/* A B C R(A) := RK(B) & RK(C) */ 194OP_BAND,/* A B C R(A) := RK(B) & RK(C) */
195OP_BOR,/* A B C R(A) := RK(B) | RK(C) */ 195OP_BOR,/* A B C R(A) := RK(B) | RK(C) */
196OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */ 196OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */
197OP_SHL,/* A B C R(A) := RK(B) << RK(C) */
198OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */
197OP_UNM,/* A B R(A) := -R(B) */ 199OP_UNM,/* A B R(A) := -R(B) */
200OP_BNOT,/* A B R(A) := ~R(B) */
198OP_NOT,/* A B R(A) := not R(B) */ 201OP_NOT,/* A B R(A) := not R(B) */
199OP_LEN,/* A B R(A) := length of R(B) */ 202OP_LEN,/* A B R(A) := length of R(B) */
200 203
diff --git a/lparser.c b/lparser.c
index fce6a04b..86582565 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.136 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: lparser.c,v 2.137 2013/12/18 14:12:03 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -979,6 +979,7 @@ static UnOpr getunopr (int op) {
979 switch (op) { 979 switch (op) {
980 case TK_NOT: return OPR_NOT; 980 case TK_NOT: return OPR_NOT;
981 case '-': return OPR_MINUS; 981 case '-': return OPR_MINUS;
982 case '~': return OPR_BNOT;
982 case '#': return OPR_LEN; 983 case '#': return OPR_LEN;
983 default: return OPR_NOUNOPR; 984 default: return OPR_NOUNOPR;
984 } 985 }
@@ -997,6 +998,8 @@ static BinOpr getbinopr (int op) {
997 case '&': return OPR_BAND; 998 case '&': return OPR_BAND;
998 case '|': return OPR_BOR; 999 case '|': return OPR_BOR;
999 case '~': return OPR_BXOR; 1000 case '~': return OPR_BXOR;
1001 case TK_SHL: return OPR_SHL;
1002 case TK_SHR: return OPR_SHR;
1000 case TK_CONCAT: return OPR_CONCAT; 1003 case TK_CONCAT: return OPR_CONCAT;
1001 case TK_NE: return OPR_NE; 1004 case TK_NE: return OPR_NE;
1002 case TK_EQ: return OPR_EQ; 1005 case TK_EQ: return OPR_EQ;
@@ -1015,18 +1018,19 @@ static const struct {
1015 lu_byte left; /* left priority for each binary operator */ 1018 lu_byte left; /* left priority for each binary operator */
1016 lu_byte right; /* right priority */ 1019 lu_byte right; /* right priority */
1017} priority[] = { /* ORDER OPR */ 1020} priority[] = { /* ORDER OPR */
1018 {8, 8}, {8, 8}, /* '+' '-' */ 1021 {10, 10}, {10, 10}, /* '+' '-' */
1019 {9, 9}, {9, 9}, /* '*' '%' */ 1022 {11, 11}, {11, 11}, /* '*' '%' */
1020 {12, 11}, /* '^' (right associative) */ 1023 {14, 13}, /* '^' (right associative) */
1021 {9, 9}, {9, 9}, /* '/' '//' */ 1024 {11, 11}, {11, 11}, /* '/' '//' */
1022 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ 1025 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */
1023 {7, 6}, /* '..' (right associative) */ 1026 {7, 7}, {7, 7}, /* '<<' '>>' */
1027 {9, 8}, /* '..' (right associative) */
1024 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ 1028 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
1025 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ 1029 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
1026 {2, 2}, {1, 1} /* and, or */ 1030 {2, 2}, {1, 1} /* and, or */
1027}; 1031};
1028 1032
1029#define UNARY_PRIORITY 10 /* priority for unary operators */ 1033#define UNARY_PRIORITY 12 /* priority for unary operators */
1030 1034
1031 1035
1032/* 1036/*
diff --git a/ltests.c b/ltests.c
index 1dccc934..d062d167 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.160 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: ltests.c,v 2.161 2013/12/18 14:12:03 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -1023,6 +1023,16 @@ static void pushcode (lua_State *L, int code) {
1023static int testC (lua_State *L); 1023static int testC (lua_State *L);
1024static int Cfunck (lua_State *L); 1024static int Cfunck (lua_State *L);
1025 1025
1026/*
1027** arithmetic operation encoding for 'arith' instruction
1028** LUA_OPIDIV -> \
1029** LUA_OPSHL -> <
1030** LUA_OPSHR -> >
1031** LUA_OPUNM -> _
1032** LUA_OPBNOT -> !
1033*/
1034static char ops[] = "+-*%^/\\&|~<>_!";
1035
1026static int runC (lua_State *L, lua_State *L1, const char *pc) { 1036static int runC (lua_State *L, lua_State *L1, const char *pc) {
1027 char buff[300]; 1037 char buff[300];
1028 int status = 0; 1038 int status = 0;
@@ -1198,7 +1208,6 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1198 } 1208 }
1199 } 1209 }
1200 else if EQ("arith") { 1210 else if EQ("arith") {
1201 static char ops[] = "+-*%^/\\&|~_"; /* '\' -> '//'; '_' -> '..' */
1202 int op; 1211 int op;
1203 skip(&pc); 1212 skip(&pc);
1204 op = strchr(ops, *pc++) - ops; 1213 op = strchr(ops, *pc++) - ops;
diff --git a/ltm.c b/ltm.c
index 6ca7e9d3..1aa25bf0 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 2.23 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: ltm.c,v 2.24 2013/12/18 14:12:03 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -38,8 +38,8 @@ void luaT_init (lua_State *L) {
38 "__gc", "__mode", "__len", "__eq", 38 "__gc", "__mode", "__len", "__eq",
39 "__add", "__sub", "__mul", "__mod", "__pow", 39 "__add", "__sub", "__mul", "__mod", "__pow",
40 "__div", "__idiv", 40 "__div", "__idiv",
41 "__band", "__bor", "__bxor", 41 "__band", "__bor", "__bxor", "__shl", "__shr",
42 "__unm", "__lt", "__le", 42 "__unm", "__bnot", "__lt", "__le",
43 "__concat", "__call" 43 "__concat", "__call"
44 }; 44 };
45 int i; 45 int i;
@@ -112,12 +112,17 @@ int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
112void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 112void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
113 StkId res, TMS event) { 113 StkId res, TMS event) {
114 if (!luaT_callbinTM(L, p1, p2, res, event)) { 114 if (!luaT_callbinTM(L, p1, p2, res, event)) {
115 if (event == TM_CONCAT) 115 switch (event) {
116 luaG_concaterror(L, p1, p2); 116 case TM_CONCAT:
117 else if (event == TM_IDIV && ttisnumber(p1) && ttisnumber(p2)) 117 luaG_concaterror(L, p1, p2);
118 luaG_tointerror(L, p1, p2); 118 case TM_IDIV: case TM_BAND: case TM_BOR: case TM_BXOR:
119 else 119 case TM_SHL: case TM_SHR: case TM_BNOT:
120 luaG_aritherror(L, p1, p2); 120 if (ttisnumber(p1) && ttisnumber(p2))
121 luaG_tointerror(L, p1, p2);
122 /* else go through */
123 default:
124 luaG_aritherror(L, p1, p2);
125 }
121 } 126 }
122} 127}
123 128
diff --git a/ltm.h b/ltm.h
index 237acc7f..a25247cc 100644
--- a/ltm.h
+++ b/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.h,v 2.17 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: ltm.h,v 2.18 2013/12/18 14:12:03 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -32,7 +32,10 @@ typedef enum {
32 TM_BAND, 32 TM_BAND,
33 TM_BOR, 33 TM_BOR,
34 TM_BXOR, 34 TM_BXOR,
35 TM_SHL,
36 TM_SHR,
35 TM_UNM, 37 TM_UNM,
38 TM_BNOT,
36 TM_LT, 39 TM_LT,
37 TM_LE, 40 TM_LE,
38 TM_CONCAT, 41 TM_CONCAT,
diff --git a/lua.h b/lua.h
index bfb713a7..d40d1956 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.296 2013/12/16 19:06:52 roberto Exp roberto $ 2** $Id: lua.h,v 1.297 2013/12/18 14:12:03 roberto Exp roberto $
3** Lua - A Scripting Language 3** Lua - A Scripting Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org) 4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file 5** See Copyright Notice at the end of this file
@@ -192,7 +192,10 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx);
192#define LUA_OPBAND 7 192#define LUA_OPBAND 7
193#define LUA_OPBOR 8 193#define LUA_OPBOR 8
194#define LUA_OPBXOR 9 194#define LUA_OPBXOR 9
195#define LUA_OPUNM 10 195#define LUA_OPSHL 10
196#define LUA_OPSHR 11
197#define LUA_OPUNM 12
198#define LUA_OPBNOT 13
196 199
197LUA_API void (lua_arith) (lua_State *L, int op); 200LUA_API void (lua_arith) (lua_State *L, int op);
198 201
diff --git a/lvm.c b/lvm.c
index b18ed3fd..9a2c1375 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,10 +1,11 @@
1/* 1/*
2** $Id: lvm.c,v 2.181 2013/12/16 14:30:22 roberto Exp roberto $ 2** $Id: lvm.c,v 2.182 2013/12/18 14:12:03 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7 7
8#include <limits.h>
8#include <stdio.h> 9#include <stdio.h>
9#include <stdlib.h> 10#include <stdlib.h>
10#include <string.h> 11#include <string.h>
@@ -379,6 +380,21 @@ lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) {
379} 380}
380 381
381 382
383/* number of bits in an integer */
384#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
385
386LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
387 if (y < 0) { /* shift right? */
388 if (y <= -NBITS) return 0;
389 else return cast_integer(cast_unsigned(x) >> (-y));
390 }
391 else { /* shift left */
392 if (y >= NBITS) return 0;
393 else return x << y;
394 }
395}
396
397
382/* 398/*
383** check whether cached closure in prototype 'p' may be reused, that is, 399** check whether cached closure in prototype 'p' may be reused, that is,
384** whether there is a cached closure with the same upvalues needed by 400** whether there is a cached closure with the same upvalues needed by
@@ -437,8 +453,9 @@ void luaV_finishOp (lua_State *L) {
437 OpCode op = GET_OPCODE(inst); 453 OpCode op = GET_OPCODE(inst);
438 switch (op) { /* finish its execution */ 454 switch (op) { /* finish its execution */
439 case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: 455 case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV:
440 case OP_BAND: case OP_BOR: case OP_BXOR: 456 case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR:
441 case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: 457 case OP_MOD: case OP_POW:
458 case OP_UNM: case OP_BNOT: case OP_LEN:
442 case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { 459 case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
443 setobjs2s(L, base + GETARG_A(inst), --L->top); 460 setobjs2s(L, base + GETARG_A(inst), --L->top);
444 break; 461 break;
@@ -699,6 +716,24 @@ void luaV_execute (lua_State *L) {
699 } 716 }
700 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } 717 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); }
701 ) 718 )
719 vmcase(OP_SHL,
720 TValue *rb = RKB(i);
721 TValue *rc = RKC(i);
722 lua_Integer ib; lua_Integer ic;
723 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
724 setivalue(ra, luaV_shiftl(ib, ic));
725 }
726 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); }
727 )
728 vmcase(OP_SHR,
729 TValue *rb = RKB(i);
730 TValue *rc = RKC(i);
731 lua_Integer ib; lua_Integer ic;
732 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
733 setivalue(ra, luaV_shiftl(ib, -ic));
734 }
735 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); }
736 )
702 vmcase(OP_MOD, 737 vmcase(OP_MOD,
703 TValue *rb = RKB(i); 738 TValue *rb = RKB(i);
704 TValue *rc = RKC(i); 739 TValue *rc = RKC(i);
@@ -739,6 +774,16 @@ void luaV_execute (lua_State *L) {
739 Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); 774 Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
740 } 775 }
741 ) 776 )
777 vmcase(OP_BNOT,
778 TValue *rb = RB(i);
779 lua_Integer ib;
780 if (tointeger(rb, &ib)) {
781 setivalue(ra, intop(^, cast_integer(-1), ib));
782 }
783 else {
784 Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT));
785 }
786 )
742 vmcase(OP_NOT, 787 vmcase(OP_NOT,
743 TValue *rb = RB(i); 788 TValue *rb = RB(i);
744 int res = l_isfalse(rb); /* next assignment may change this value */ 789 int res = l_isfalse(rb); /* next assignment may change this value */
diff --git a/lvm.h b/lvm.h
index 56713c83..bb35d633 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 roberto Exp roberto $ 2** $Id: lvm.h,v 2.24 2013/12/16 14:30:22 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -44,6 +44,7 @@ LUAI_FUNC void luaV_concat (lua_State *L, int total);
44LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); 44LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
45LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 45LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
46LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y); 46LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y);
47LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
47LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 48LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
48 49
49#endif 50#endif