mirror of https://github.com/rusefi/lua.git
first implementation of '<<', '>>', and '~' (bitwise not)
This commit is contained in:
parent
f5133aa1a5
commit
1ea2d20f74
8
lapi.c
8
lapi.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lapi.c,v 2.190 2013/09/13 16:21:52 roberto Exp roberto $
|
||||
** $Id: lapi.c,v 2.191 2013/12/04 12:15:22 roberto Exp roberto $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -299,9 +299,9 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
|
|||
|
||||
LUA_API void lua_arith (lua_State *L, int op) {
|
||||
lua_lock(L);
|
||||
if (op != LUA_OPUNM) /* all other operations expect two operands */
|
||||
api_checknelems(L, 2);
|
||||
else { /* for unary minus, add fake 2nd operand */
|
||||
if (op != LUA_OPUNM && op != LUA_OPBNOT)
|
||||
api_checknelems(L, 2); /* all other operations expect two operands */
|
||||
else { /* for unary operations, add fake 2nd operand */
|
||||
api_checknelems(L, 1);
|
||||
setobjs2s(L, L->top, L->top - 1);
|
||||
L->top++;
|
||||
|
|
16
lcode.c
16
lcode.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lcode.c,v 2.75 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** $Id: lcode.c,v 2.76 2013/12/18 18:44:42 roberto Exp roberto $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -756,7 +756,8 @@ static int validop (OpCode op, TValue *v1, TValue *v2) {
|
|||
switch (op) {
|
||||
case OP_IDIV: /* division by 0 and conversion errors */
|
||||
return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0);
|
||||
case OP_BAND: case OP_BOR: case OP_BXOR: /* conversion errors */
|
||||
case OP_BAND: case OP_BOR: case OP_BXOR:
|
||||
case OP_SHL: case OP_SHR: case OP_BNOT: /* conversion errors */
|
||||
return (tointeger(v1, &i) && tointeger(v2, &i));
|
||||
case OP_MOD: /* integer module by 0 */
|
||||
return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0);
|
||||
|
@ -771,7 +772,6 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
|
|||
TValue v1, v2, res;
|
||||
if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
|
||||
return 0; /* non-numeric operands or not safe to fold */
|
||||
lua_assert(OP_IDIV - OP_ADD + LUA_OPADD == LUA_OPIDIV);
|
||||
luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);
|
||||
if (ttisinteger(&res)) {
|
||||
e1->k = VKINT;
|
||||
|
@ -792,7 +792,7 @@ static void codearith (FuncState *fs, OpCode op,
|
|||
expdesc *e1, expdesc *e2, int line) {
|
||||
if (!constfolding(op, e1, e2)) { /* could not fold operation? */
|
||||
int o1, o2;
|
||||
if (op == OP_UNM || op == OP_LEN) {
|
||||
if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) {
|
||||
o2 = 0;
|
||||
o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
|
||||
}
|
||||
|
@ -835,7 +835,7 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
|
|||
expdesc e2;
|
||||
e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
|
||||
switch (op) {
|
||||
case OPR_MINUS: case OPR_LEN: {
|
||||
case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
|
||||
codearith(fs, op - OPR_MINUS + OP_UNM, e, &e2, line);
|
||||
break;
|
||||
}
|
||||
|
@ -862,7 +862,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
|
|||
case OPR_ADD: case OPR_SUB:
|
||||
case OPR_MUL: case OPR_DIV: case OPR_IDIV:
|
||||
case OPR_MOD: case OPR_POW:
|
||||
case OPR_BAND: case OPR_BOR: case OPR_BXOR: {
|
||||
case OPR_BAND: case OPR_BOR: case OPR_BXOR:
|
||||
case OPR_SHL: case OPR_SHR: {
|
||||
if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
|
||||
break;
|
||||
}
|
||||
|
@ -907,7 +908,8 @@ void luaK_posfix (FuncState *fs, BinOpr op,
|
|||
}
|
||||
case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
|
||||
case OPR_IDIV: case OPR_MOD: case OPR_POW:
|
||||
case OPR_BAND: case OPR_BOR: case OPR_BXOR: {
|
||||
case OPR_BAND: case OPR_BOR: case OPR_BXOR:
|
||||
case OPR_SHL: case OPR_SHR: {
|
||||
codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
|
||||
break;
|
||||
}
|
||||
|
|
5
lcode.h
5
lcode.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lcode.h,v 1.61 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: lcode.h,v 1.62 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Code generator for Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -28,6 +28,7 @@ typedef enum BinOpr {
|
|||
OPR_DIV,
|
||||
OPR_IDIV,
|
||||
OPR_BAND, OPR_BOR, OPR_BXOR,
|
||||
OPR_SHL, OPR_SHR,
|
||||
OPR_CONCAT,
|
||||
OPR_EQ, OPR_LT, OPR_LE,
|
||||
OPR_NE, OPR_GT, OPR_GE,
|
||||
|
@ -36,7 +37,7 @@ typedef enum BinOpr {
|
|||
} BinOpr;
|
||||
|
||||
|
||||
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
|
||||
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
|
||||
|
||||
|
||||
#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
|
||||
|
|
15
llex.c
15
llex.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: llex.c,v 2.68 2013/08/21 20:09:51 roberto Exp roberto $
|
||||
** $Id: llex.c,v 2.69 2013/08/30 16:01:37 roberto Exp roberto $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -39,7 +39,8 @@ static const char *const luaX_tokens [] = {
|
|||
"end", "false", "for", "function", "goto", "if",
|
||||
"in", "local", "nil", "not", "or", "repeat",
|
||||
"return", "then", "true", "until", "while",
|
||||
"//", "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
|
||||
"//", "..", "...", "==", ">=", "<=", "~=",
|
||||
"<<", ">>", "::", "<eof>",
|
||||
"<number>", "<number>", "<name>", "<string>"
|
||||
};
|
||||
|
||||
|
@ -462,13 +463,15 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
|||
}
|
||||
case '<': {
|
||||
next(ls);
|
||||
if (ls->current != '=') return '<';
|
||||
else { next(ls); return TK_LE; }
|
||||
if (ls->current == '=') { next(ls); return TK_LE; }
|
||||
if (ls->current == '<') { next(ls); return TK_SHL; }
|
||||
return '<';
|
||||
}
|
||||
case '>': {
|
||||
next(ls);
|
||||
if (ls->current != '=') return '>';
|
||||
else { next(ls); return TK_GE; }
|
||||
if (ls->current == '=') { next(ls); return TK_GE; }
|
||||
if (ls->current == '>') { next(ls); return TK_SHR; }
|
||||
return '>';
|
||||
}
|
||||
case '/': {
|
||||
next(ls);
|
||||
|
|
3
llex.h
3
llex.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: llex.h,v 1.74 2013/04/26 13:07:53 roberto Exp roberto $
|
||||
** $Id: llex.h,v 1.75 2013/08/30 16:01:37 roberto Exp roberto $
|
||||
** Lexical Analyzer
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -27,6 +27,7 @@ enum RESERVED {
|
|||
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
|
||||
/* other terminal symbols */
|
||||
TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
|
||||
TK_SHL, TK_SHR,
|
||||
TK_DBCOLON, TK_EOS,
|
||||
TK_FLT, TK_INT, TK_NAME, TK_STRING
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lobject.c,v 2.69 2013/12/16 14:30:22 roberto Exp roberto $
|
||||
** $Id: lobject.c,v 2.70 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Some generic functions over Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -82,7 +82,10 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
|
|||
case LUA_OPBAND: return intop(&, v1, v2);
|
||||
case LUA_OPBOR: return intop(|, v1, v2);
|
||||
case LUA_OPBXOR: return intop(^, v1, v2);
|
||||
case LUA_OPSHL: return luaV_shiftl(v1, v2);
|
||||
case LUA_OPSHR: return luaV_shiftl(v1, -v2);
|
||||
case LUA_OPUNM: return intop(-, 0, v1);
|
||||
case LUA_OPBNOT: return intop(^, cast_integer(-1), v1);
|
||||
default: lua_assert(0); return 0;
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +109,8 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
|
|||
TValue *res) {
|
||||
switch (op) {
|
||||
case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR:
|
||||
case LUA_OPBXOR: { /* operates only on integers */
|
||||
case LUA_OPBXOR: case LUA_OPSHL: case LUA_OPSHR:
|
||||
case LUA_OPBNOT: { /* operates only on integers */
|
||||
lua_Integer i1; lua_Integer i2;
|
||||
if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
|
||||
setivalue(res, intarith(L, op, i1, i2));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lopcodes.c,v 1.51 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: lopcodes.c,v 1.52 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Opcodes for Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -38,7 +38,10 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
|
|||
"BAND",
|
||||
"BOR",
|
||||
"BXOR",
|
||||
"SHL",
|
||||
"SHR",
|
||||
"UNM",
|
||||
"BNOT",
|
||||
"NOT",
|
||||
"LEN",
|
||||
"CONCAT",
|
||||
|
@ -90,7 +93,10 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
|
|||
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */
|
||||
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */
|
||||
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */
|
||||
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */
|
||||
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */
|
||||
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
|
||||
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */
|
||||
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
|
||||
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
|
||||
,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lopcodes.h,v 1.144 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: lopcodes.h,v 1.145 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Opcodes for Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -194,7 +194,10 @@ OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */
|
|||
OP_BAND,/* A B C R(A) := RK(B) & RK(C) */
|
||||
OP_BOR,/* A B C R(A) := RK(B) | RK(C) */
|
||||
OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */
|
||||
OP_SHL,/* A B C R(A) := RK(B) << RK(C) */
|
||||
OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */
|
||||
OP_UNM,/* A B R(A) := -R(B) */
|
||||
OP_BNOT,/* A B R(A) := ~R(B) */
|
||||
OP_NOT,/* A B R(A) := not R(B) */
|
||||
OP_LEN,/* A B R(A) := length of R(B) */
|
||||
|
||||
|
|
18
lparser.c
18
lparser.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lparser.c,v 2.136 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: lparser.c,v 2.137 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Lua Parser
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -979,6 +979,7 @@ static UnOpr getunopr (int op) {
|
|||
switch (op) {
|
||||
case TK_NOT: return OPR_NOT;
|
||||
case '-': return OPR_MINUS;
|
||||
case '~': return OPR_BNOT;
|
||||
case '#': return OPR_LEN;
|
||||
default: return OPR_NOUNOPR;
|
||||
}
|
||||
|
@ -997,6 +998,8 @@ static BinOpr getbinopr (int op) {
|
|||
case '&': return OPR_BAND;
|
||||
case '|': return OPR_BOR;
|
||||
case '~': return OPR_BXOR;
|
||||
case TK_SHL: return OPR_SHL;
|
||||
case TK_SHR: return OPR_SHR;
|
||||
case TK_CONCAT: return OPR_CONCAT;
|
||||
case TK_NE: return OPR_NE;
|
||||
case TK_EQ: return OPR_EQ;
|
||||
|
@ -1015,18 +1018,19 @@ static const struct {
|
|||
lu_byte left; /* left priority for each binary operator */
|
||||
lu_byte right; /* right priority */
|
||||
} priority[] = { /* ORDER OPR */
|
||||
{8, 8}, {8, 8}, /* '+' '-' */
|
||||
{9, 9}, {9, 9}, /* '*' '%' */
|
||||
{12, 11}, /* '^' (right associative) */
|
||||
{9, 9}, {9, 9}, /* '/' '//' */
|
||||
{10, 10}, {10, 10}, /* '+' '-' */
|
||||
{11, 11}, {11, 11}, /* '*' '%' */
|
||||
{14, 13}, /* '^' (right associative) */
|
||||
{11, 11}, {11, 11}, /* '/' '//' */
|
||||
{6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */
|
||||
{7, 6}, /* '..' (right associative) */
|
||||
{7, 7}, {7, 7}, /* '<<' '>>' */
|
||||
{9, 8}, /* '..' (right associative) */
|
||||
{3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
|
||||
{3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
|
||||
{2, 2}, {1, 1} /* and, or */
|
||||
};
|
||||
|
||||
#define UNARY_PRIORITY 10 /* priority for unary operators */
|
||||
#define UNARY_PRIORITY 12 /* priority for unary operators */
|
||||
|
||||
|
||||
/*
|
||||
|
|
13
ltests.c
13
ltests.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltests.c,v 2.160 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: ltests.c,v 2.161 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -1023,6 +1023,16 @@ static void pushcode (lua_State *L, int code) {
|
|||
static int testC (lua_State *L);
|
||||
static int Cfunck (lua_State *L);
|
||||
|
||||
/*
|
||||
** arithmetic operation encoding for 'arith' instruction
|
||||
** LUA_OPIDIV -> \
|
||||
** LUA_OPSHL -> <
|
||||
** LUA_OPSHR -> >
|
||||
** LUA_OPUNM -> _
|
||||
** LUA_OPBNOT -> !
|
||||
*/
|
||||
static char ops[] = "+-*%^/\\&|~<>_!";
|
||||
|
||||
static int runC (lua_State *L, lua_State *L1, const char *pc) {
|
||||
char buff[300];
|
||||
int status = 0;
|
||||
|
@ -1198,7 +1208,6 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
|
|||
}
|
||||
}
|
||||
else if EQ("arith") {
|
||||
static char ops[] = "+-*%^/\\&|~_"; /* '\' -> '//'; '_' -> '..' */
|
||||
int op;
|
||||
skip(&pc);
|
||||
op = strchr(ops, *pc++) - ops;
|
||||
|
|
23
ltm.c
23
ltm.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltm.c,v 2.23 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: ltm.c,v 2.24 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -38,8 +38,8 @@ void luaT_init (lua_State *L) {
|
|||
"__gc", "__mode", "__len", "__eq",
|
||||
"__add", "__sub", "__mul", "__mod", "__pow",
|
||||
"__div", "__idiv",
|
||||
"__band", "__bor", "__bxor",
|
||||
"__unm", "__lt", "__le",
|
||||
"__band", "__bor", "__bxor", "__shl", "__shr",
|
||||
"__unm", "__bnot", "__lt", "__le",
|
||||
"__concat", "__call"
|
||||
};
|
||||
int i;
|
||||
|
@ -112,12 +112,17 @@ int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
|||
void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
|
||||
StkId res, TMS event) {
|
||||
if (!luaT_callbinTM(L, p1, p2, res, event)) {
|
||||
if (event == TM_CONCAT)
|
||||
luaG_concaterror(L, p1, p2);
|
||||
else if (event == TM_IDIV && ttisnumber(p1) && ttisnumber(p2))
|
||||
luaG_tointerror(L, p1, p2);
|
||||
else
|
||||
luaG_aritherror(L, p1, p2);
|
||||
switch (event) {
|
||||
case TM_CONCAT:
|
||||
luaG_concaterror(L, p1, p2);
|
||||
case TM_IDIV: case TM_BAND: case TM_BOR: case TM_BXOR:
|
||||
case TM_SHL: case TM_SHR: case TM_BNOT:
|
||||
if (ttisnumber(p1) && ttisnumber(p2))
|
||||
luaG_tointerror(L, p1, p2);
|
||||
/* else go through */
|
||||
default:
|
||||
luaG_aritherror(L, p1, p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
5
ltm.h
5
ltm.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: ltm.h,v 2.17 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: ltm.h,v 2.18 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -32,7 +32,10 @@ typedef enum {
|
|||
TM_BAND,
|
||||
TM_BOR,
|
||||
TM_BXOR,
|
||||
TM_SHL,
|
||||
TM_SHR,
|
||||
TM_UNM,
|
||||
TM_BNOT,
|
||||
TM_LT,
|
||||
TM_LE,
|
||||
TM_CONCAT,
|
||||
|
|
7
lua.h
7
lua.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lua.h,v 1.296 2013/12/16 19:06:52 roberto Exp roberto $
|
||||
** $Id: lua.h,v 1.297 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Lua - A Scripting Language
|
||||
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
|
||||
** See Copyright Notice at the end of this file
|
||||
|
@ -192,7 +192,10 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx);
|
|||
#define LUA_OPBAND 7
|
||||
#define LUA_OPBOR 8
|
||||
#define LUA_OPBXOR 9
|
||||
#define LUA_OPUNM 10
|
||||
#define LUA_OPSHL 10
|
||||
#define LUA_OPSHR 11
|
||||
#define LUA_OPUNM 12
|
||||
#define LUA_OPBNOT 13
|
||||
|
||||
LUA_API void (lua_arith) (lua_State *L, int op);
|
||||
|
||||
|
|
51
lvm.c
51
lvm.c
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
** $Id: lvm.c,v 2.181 2013/12/16 14:30:22 roberto Exp roberto $
|
||||
** $Id: lvm.c,v 2.182 2013/12/18 14:12:03 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -379,6 +380,21 @@ lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) {
|
|||
}
|
||||
|
||||
|
||||
/* number of bits in an integer */
|
||||
#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
|
||||
|
||||
LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
|
||||
if (y < 0) { /* shift right? */
|
||||
if (y <= -NBITS) return 0;
|
||||
else return cast_integer(cast_unsigned(x) >> (-y));
|
||||
}
|
||||
else { /* shift left */
|
||||
if (y >= NBITS) return 0;
|
||||
else return x << y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** check whether cached closure in prototype 'p' may be reused, that is,
|
||||
** whether there is a cached closure with the same upvalues needed by
|
||||
|
@ -437,8 +453,9 @@ void luaV_finishOp (lua_State *L) {
|
|||
OpCode op = GET_OPCODE(inst);
|
||||
switch (op) { /* finish its execution */
|
||||
case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV:
|
||||
case OP_BAND: case OP_BOR: case OP_BXOR:
|
||||
case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
|
||||
case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR:
|
||||
case OP_MOD: case OP_POW:
|
||||
case OP_UNM: case OP_BNOT: case OP_LEN:
|
||||
case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
|
||||
setobjs2s(L, base + GETARG_A(inst), --L->top);
|
||||
break;
|
||||
|
@ -699,6 +716,24 @@ void luaV_execute (lua_State *L) {
|
|||
}
|
||||
else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); }
|
||||
)
|
||||
vmcase(OP_SHL,
|
||||
TValue *rb = RKB(i);
|
||||
TValue *rc = RKC(i);
|
||||
lua_Integer ib; lua_Integer ic;
|
||||
if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
|
||||
setivalue(ra, luaV_shiftl(ib, ic));
|
||||
}
|
||||
else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); }
|
||||
)
|
||||
vmcase(OP_SHR,
|
||||
TValue *rb = RKB(i);
|
||||
TValue *rc = RKC(i);
|
||||
lua_Integer ib; lua_Integer ic;
|
||||
if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
|
||||
setivalue(ra, luaV_shiftl(ib, -ic));
|
||||
}
|
||||
else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); }
|
||||
)
|
||||
vmcase(OP_MOD,
|
||||
TValue *rb = RKB(i);
|
||||
TValue *rc = RKC(i);
|
||||
|
@ -739,6 +774,16 @@ void luaV_execute (lua_State *L) {
|
|||
Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
|
||||
}
|
||||
)
|
||||
vmcase(OP_BNOT,
|
||||
TValue *rb = RB(i);
|
||||
lua_Integer ib;
|
||||
if (tointeger(rb, &ib)) {
|
||||
setivalue(ra, intop(^, cast_integer(-1), ib));
|
||||
}
|
||||
else {
|
||||
Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT));
|
||||
}
|
||||
)
|
||||
vmcase(OP_NOT,
|
||||
TValue *rb = RB(i);
|
||||
int res = l_isfalse(rb); /* next assignment may change this value */
|
||||
|
|
3
lvm.h
3
lvm.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 roberto Exp roberto $
|
||||
** $Id: lvm.h,v 2.24 2013/12/16 14:30:22 roberto Exp roberto $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
@ -44,6 +44,7 @@ LUAI_FUNC void luaV_concat (lua_State *L, int total);
|
|||
LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
|
||||
LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
|
||||
LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y);
|
||||
LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
|
||||
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue