diff options
| -rw-r--r-- | lcode.c | 37 | ||||
| -rw-r--r-- | lcode.h | 3 | ||||
| -rw-r--r-- | lobject.c | 49 | ||||
| -rw-r--r-- | lopcodes.c | 8 | ||||
| -rw-r--r-- | lopcodes.h | 5 | ||||
| -rw-r--r-- | lparser.c | 18 | ||||
| -rw-r--r-- | ltests.c | 4 | ||||
| -rw-r--r-- | ltm.c | 3 | ||||
| -rw-r--r-- | ltm.h | 5 | ||||
| -rw-r--r-- | lua.h | 7 | ||||
| -rw-r--r-- | lvm.c | 30 |
11 files changed, 122 insertions, 47 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.73 2013/12/16 14:30:22 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.74 2013/12/16 19:06:52 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 | */ |
| @@ -750,18 +750,27 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | |||
| 750 | } | 750 | } |
| 751 | 751 | ||
| 752 | 752 | ||
| 753 | /* return false if folding can raise an error */ | ||
| 754 | static int validop (OpCode op, TValue *v1, TValue *v2) { | ||
| 755 | lua_Integer i; | ||
| 756 | switch (op) { | ||
| 757 | case OP_IDIV: /* division by 0 and conversion errors */ | ||
| 758 | return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); | ||
| 759 | case OP_BAND: case OP_BOR: case OP_BXOR: /* conversion errors */ | ||
| 760 | return (tointeger(v1, &i) && tointeger(v2, &i)); | ||
| 761 | case OP_MOD: /* integer module by 0 */ | ||
| 762 | return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0); | ||
| 763 | case OP_POW: /* negative integer exponentiation */ | ||
| 764 | return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) < 0); | ||
| 765 | default: return 1; /* everything else is valid */ | ||
| 766 | } | ||
| 767 | } | ||
| 768 | |||
| 769 | |||
| 753 | static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { | 770 | static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { |
| 754 | TValue v1, v2, res; | 771 | TValue v1, v2, res; |
| 755 | lua_Integer i; | 772 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) |
| 756 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2)) | 773 | return 0; /* non-numeric operands or not safe to fold */ |
| 757 | return 0; /* non-numeric operands */ | ||
| 758 | if (op == OP_IDIV && | ||
| 759 | (!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0)) | ||
| 760 | return 0; /* avoid division by 0 and conversion errors */ | ||
| 761 | if (ttisinteger(&v1) && ttisinteger(&v2) && /* for integer operations... */ | ||
| 762 | ((op == OP_MOD && ivalue(&v2) == 0) || /* ...avoid module by 0... */ | ||
| 763 | (op == OP_POW && ivalue(&v2) < 0))) /* ...and negative exponents */ | ||
| 764 | return 0; | ||
| 765 | lua_assert(OP_IDIV - OP_ADD + LUA_OPADD == LUA_OPIDIV); | 774 | lua_assert(OP_IDIV - OP_ADD + LUA_OPADD == LUA_OPIDIV); |
| 766 | luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res); | 775 | luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res); |
| 767 | if (ttisinteger(&res)) { | 776 | if (ttisinteger(&res)) { |
| @@ -853,7 +862,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
| 853 | } | 862 | } |
| 854 | case OPR_ADD: case OPR_SUB: | 863 | case OPR_ADD: case OPR_SUB: |
| 855 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: | 864 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: |
| 856 | case OPR_MOD: case OPR_POW: { | 865 | case OPR_MOD: case OPR_POW: |
| 866 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { | ||
| 857 | if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); | 867 | if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); |
| 858 | break; | 868 | break; |
| 859 | } | 869 | } |
| @@ -897,7 +907,8 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |||
| 897 | break; | 907 | break; |
| 898 | } | 908 | } |
| 899 | 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: |
| 900 | case OPR_IDIV: case OPR_MOD: case OPR_POW: { | 910 | case OPR_IDIV: case OPR_MOD: case OPR_POW: |
| 911 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { | ||
| 901 | codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); | 912 | codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); |
| 902 | break; | 913 | break; |
| 903 | } | 914 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.h,v 1.60 2013/04/26 13:07:53 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.61 2013/12/16 19:06:52 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 | */ |
| @@ -27,6 +27,7 @@ typedef enum BinOpr { | |||
| 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, | 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, |
| 28 | OPR_DIV, | 28 | OPR_DIV, |
| 29 | OPR_IDIV, | 29 | OPR_IDIV, |
| 30 | OPR_BAND, OPR_BOR, OPR_BXOR, | ||
| 30 | OPR_CONCAT, | 31 | OPR_CONCAT, |
| 31 | OPR_EQ, OPR_LT, OPR_LE, | 32 | OPR_EQ, OPR_LT, OPR_LE, |
| 32 | OPR_NE, OPR_GT, OPR_GE, | 33 | OPR_NE, OPR_GT, OPR_GE, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.68 2013/07/10 17:15:12 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.69 2013/12/16 14:30:22 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 | */ |
| @@ -78,6 +78,10 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, | |||
| 78 | case LUA_OPMUL:return intop(*, v1, v2); | 78 | case LUA_OPMUL:return intop(*, v1, v2); |
| 79 | case LUA_OPMOD: return luaV_mod(L, v1, v2); | 79 | case LUA_OPMOD: return luaV_mod(L, v1, v2); |
| 80 | case LUA_OPPOW: return luaV_pow(L, v1, v2); | 80 | case LUA_OPPOW: return luaV_pow(L, v1, v2); |
| 81 | case LUA_OPIDIV: return luaV_div(L, v1, v2); | ||
| 82 | case LUA_OPBAND: return intop(&, v1, v2); | ||
| 83 | case LUA_OPBOR: return intop(|, v1, v2); | ||
| 84 | case LUA_OPBXOR: return intop(^, v1, v2); | ||
| 81 | case LUA_OPUNM: return intop(-, 0, v1); | 85 | case LUA_OPUNM: return intop(-, 0, v1); |
| 82 | default: lua_assert(0); return 0; | 86 | default: lua_assert(0); return 0; |
| 83 | } | 87 | } |
| @@ -100,25 +104,36 @@ static lua_Number numarith (int op, lua_Number v1, lua_Number v2) { | |||
| 100 | 104 | ||
| 101 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | 105 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, |
| 102 | TValue *res) { | 106 | TValue *res) { |
| 103 | if (op == LUA_OPIDIV) { /* operates only on integers */ | 107 | switch (op) { |
| 104 | lua_Integer i1; lua_Integer i2; | 108 | case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR: |
| 105 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | 109 | case LUA_OPBXOR: { /* operates only on integers */ |
| 106 | setivalue(res, luaV_div(L, i1, i2)); | 110 | lua_Integer i1; lua_Integer i2; |
| 107 | return; | 111 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { |
| 112 | setivalue(res, intarith(L, op, i1, i2)); | ||
| 113 | return; | ||
| 114 | } | ||
| 115 | else break; /* go to the end */ | ||
| 108 | } | 116 | } |
| 109 | /* else go to the end */ | 117 | case LUA_OPDIV: { /* operates only on floats */ |
| 110 | } | 118 | lua_Number n1; lua_Number n2; |
| 111 | else { /* other operations */ | 119 | if (tonumber(p1, &n1) && tonumber(p2, &n2)) { |
| 112 | lua_Number n1; lua_Number n2; | 120 | setnvalue(res, numarith(op, n1, n2)); |
| 113 | if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV) { | 121 | return; |
| 114 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); | 122 | } |
| 115 | return; | 123 | else break; /* go to the end */ |
| 116 | } | 124 | } |
| 117 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | 125 | default: { /* other operations */ |
| 118 | setnvalue(res, numarith(op, n1, n2)); | 126 | lua_Number n1; lua_Number n2; |
| 119 | return; | 127 | if (ttisinteger(p1) && ttisinteger(p2)) { |
| 128 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | ||
| 132 | setnvalue(res, numarith(op, n1, n2)); | ||
| 133 | return; | ||
| 134 | } | ||
| 135 | else break; /* go to the end */ | ||
| 120 | } | 136 | } |
| 121 | /* else go to the end */ | ||
| 122 | } | 137 | } |
| 123 | /* could not perform raw operation; try metmethod */ | 138 | /* could not perform raw operation; try metmethod */ |
| 124 | lua_assert(L != NULL); /* should not fail when folding (compile time) */ | 139 | lua_assert(L != NULL); /* should not fail when folding (compile time) */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.c,v 1.50 2013/04/26 13:07:53 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.51 2013/12/16 19:06:52 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 | */ |
| @@ -35,6 +35,9 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { | |||
| 35 | "POW", | 35 | "POW", |
| 36 | "DIV", | 36 | "DIV", |
| 37 | "IDIV", | 37 | "IDIV", |
| 38 | "BAND", | ||
| 39 | "BOR", | ||
| 40 | "BXOR", | ||
| 38 | "UNM", | 41 | "UNM", |
| 39 | "NOT", | 42 | "NOT", |
| 40 | "LEN", | 43 | "LEN", |
| @@ -84,6 +87,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
| 84 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ | 87 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ |
| 85 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ | 88 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ |
| 86 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ | 89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ |
| 90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ | ||
| 91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ | ||
| 92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ | ||
| 87 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ | 93 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ |
| 88 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ | 94 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ |
| 89 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ | 95 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.143 2013/04/26 13:07:53 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.144 2013/12/16 19:06:52 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 | */ |
| @@ -191,6 +191,9 @@ OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ | |||
| 191 | OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ | 191 | OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ |
| 192 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ | 192 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ |
| 193 | OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */ | 193 | OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */ |
| 194 | OP_BAND,/* A B C R(A) := RK(B) & RK(C) */ | ||
| 195 | OP_BOR,/* A B C R(A) := RK(B) | RK(C) */ | ||
| 196 | OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */ | ||
| 194 | OP_UNM,/* A B R(A) := -R(B) */ | 197 | OP_UNM,/* A B R(A) := -R(B) */ |
| 195 | OP_NOT,/* A B R(A) := not R(B) */ | 198 | OP_NOT,/* A B R(A) := not R(B) */ |
| 196 | OP_LEN,/* A B R(A) := length of R(B) */ | 199 | OP_LEN,/* A B R(A) := length of R(B) */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.135 2013/08/30 16:01:37 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.136 2013/12/16 19:06:52 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 | */ |
| @@ -994,6 +994,9 @@ static BinOpr getbinopr (int op) { | |||
| 994 | case '^': return OPR_POW; | 994 | case '^': return OPR_POW; |
| 995 | case '/': return OPR_DIV; | 995 | case '/': return OPR_DIV; |
| 996 | case TK_IDIV: return OPR_IDIV; | 996 | case TK_IDIV: return OPR_IDIV; |
| 997 | case '&': return OPR_BAND; | ||
| 998 | case '|': return OPR_BOR; | ||
| 999 | case '~': return OPR_BXOR; | ||
| 997 | case TK_CONCAT: return OPR_CONCAT; | 1000 | case TK_CONCAT: return OPR_CONCAT; |
| 998 | case TK_NE: return OPR_NE; | 1001 | case TK_NE: return OPR_NE; |
| 999 | case TK_EQ: return OPR_EQ; | 1002 | case TK_EQ: return OPR_EQ; |
| @@ -1012,17 +1015,18 @@ static const struct { | |||
| 1012 | lu_byte left; /* left priority for each binary operator */ | 1015 | lu_byte left; /* left priority for each binary operator */ |
| 1013 | lu_byte right; /* right priority */ | 1016 | lu_byte right; /* right priority */ |
| 1014 | } priority[] = { /* ORDER OPR */ | 1017 | } priority[] = { /* ORDER OPR */ |
| 1015 | {6, 6}, {6, 6}, /* '+' '-' */ | 1018 | {8, 8}, {8, 8}, /* '+' '-' */ |
| 1016 | {7, 7}, {7, 7}, /* '*' '%' */ | 1019 | {9, 9}, {9, 9}, /* '*' '%' */ |
| 1017 | {10, 9}, /* '^' (right associative) */ | 1020 | {12, 11}, /* '^' (right associative) */ |
| 1018 | {7, 7}, {7, 7}, /* '/' '//' */ | 1021 | {9, 9}, {9, 9}, /* '/' '//' */ |
| 1019 | {5, 4}, /* '..' (right associative) */ | 1022 | {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ |
| 1023 | {7, 6}, /* '..' (right associative) */ | ||
| 1020 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ | 1024 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ |
| 1021 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ | 1025 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ |
| 1022 | {2, 2}, {1, 1} /* and, or */ | 1026 | {2, 2}, {1, 1} /* and, or */ |
| 1023 | }; | 1027 | }; |
| 1024 | 1028 | ||
| 1025 | #define UNARY_PRIORITY 8 /* priority for unary operators */ | 1029 | #define UNARY_PRIORITY 10 /* priority for unary operators */ |
| 1026 | 1030 | ||
| 1027 | 1031 | ||
| 1028 | /* | 1032 | /* |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.159 2013/09/11 14:47:08 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.160 2013/12/16 19:06:52 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 | */ |
| @@ -1198,7 +1198,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
| 1198 | } | 1198 | } |
| 1199 | } | 1199 | } |
| 1200 | else if EQ("arith") { | 1200 | else if EQ("arith") { |
| 1201 | static char ops[] = "+-*%^/\\_"; /* '\' -> '//'; '_' -> '..' */ | 1201 | static char ops[] = "+-*%^/\\&|~_"; /* '\' -> '//'; '_' -> '..' */ |
| 1202 | int op; | 1202 | int op; |
| 1203 | skip(&pc); | 1203 | skip(&pc); |
| 1204 | op = strchr(ops, *pc++) - ops; | 1204 | op = strchr(ops, *pc++) - ops; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.22 2013/08/27 18:53:35 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.23 2013/12/16 19:06:52 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,6 +38,7 @@ 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 | "__unm", "__lt", "__le", | 42 | "__unm", "__lt", "__le", |
| 42 | "__concat", "__call" | 43 | "__concat", "__call" |
| 43 | }; | 44 | }; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.h,v 2.16 2013/04/29 16:56:50 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 2.17 2013/12/16 19:06:52 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 | */ |
| @@ -29,6 +29,9 @@ typedef enum { | |||
| 29 | TM_POW, | 29 | TM_POW, |
| 30 | TM_DIV, | 30 | TM_DIV, |
| 31 | TM_IDIV, | 31 | TM_IDIV, |
| 32 | TM_BAND, | ||
| 33 | TM_BOR, | ||
| 34 | TM_BXOR, | ||
| 32 | TM_UNM, | 35 | TM_UNM, |
| 33 | TM_LT, | 36 | TM_LT, |
| 34 | TM_LE, | 37 | TM_LE, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.295 2013/12/09 14:21:10 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.296 2013/12/16 19:06:52 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 |
| @@ -189,7 +189,10 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx); | |||
| 189 | #define LUA_OPPOW 4 | 189 | #define LUA_OPPOW 4 |
| 190 | #define LUA_OPDIV 5 | 190 | #define LUA_OPDIV 5 |
| 191 | #define LUA_OPIDIV 6 | 191 | #define LUA_OPIDIV 6 |
| 192 | #define LUA_OPUNM 7 | 192 | #define LUA_OPBAND 7 |
| 193 | #define LUA_OPBOR 8 | ||
| 194 | #define LUA_OPBXOR 9 | ||
| 195 | #define LUA_OPUNM 10 | ||
| 193 | 196 | ||
| 194 | LUA_API void (lua_arith) (lua_State *L, int op); | 197 | LUA_API void (lua_arith) (lua_State *L, int op); |
| 195 | 198 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.180 2013/08/29 13:49:57 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.181 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 | */ |
| @@ -437,6 +437,7 @@ void luaV_finishOp (lua_State *L) { | |||
| 437 | OpCode op = GET_OPCODE(inst); | 437 | OpCode op = GET_OPCODE(inst); |
| 438 | switch (op) { /* finish its execution */ | 438 | switch (op) { /* finish its execution */ |
| 439 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: | 439 | 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: | ||
| 440 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 441 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: |
| 441 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { | 442 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { |
| 442 | setobjs2s(L, base + GETARG_A(inst), --L->top); | 443 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
| @@ -671,6 +672,33 @@ void luaV_execute (lua_State *L) { | |||
| 671 | } | 672 | } |
| 672 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } | 673 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } |
| 673 | ) | 674 | ) |
| 675 | vmcase(OP_BAND, | ||
| 676 | TValue *rb = RKB(i); | ||
| 677 | TValue *rc = RKC(i); | ||
| 678 | lua_Integer ib; lua_Integer ic; | ||
| 679 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 680 | setivalue(ra, intop(&, ib, ic)); | ||
| 681 | } | ||
| 682 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } | ||
| 683 | ) | ||
| 684 | vmcase(OP_BOR, | ||
| 685 | TValue *rb = RKB(i); | ||
| 686 | TValue *rc = RKC(i); | ||
| 687 | lua_Integer ib; lua_Integer ic; | ||
| 688 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 689 | setivalue(ra, intop(|, ib, ic)); | ||
| 690 | } | ||
| 691 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } | ||
| 692 | ) | ||
| 693 | vmcase(OP_BXOR, | ||
| 694 | TValue *rb = RKB(i); | ||
| 695 | TValue *rc = RKC(i); | ||
| 696 | lua_Integer ib; lua_Integer ic; | ||
| 697 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 698 | setivalue(ra, intop(^, ib, ic)); | ||
| 699 | } | ||
| 700 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | ||
| 701 | ) | ||
| 674 | vmcase(OP_MOD, | 702 | vmcase(OP_MOD, |
| 675 | TValue *rb = RKB(i); | 703 | TValue *rb = RKB(i); |
| 676 | TValue *rc = RKC(i); | 704 | TValue *rc = RKC(i); |
