diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-16 10:59:14 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-11-16 10:59:14 -0200 |
commit | 4c0e36a46e11be2f101203ed0db66ea750bf4333 (patch) | |
tree | 625e7be62fc7d9eb95c052a6a8f31ee1892332e7 | |
parent | 5440b42f434ecb6fe7a8e0d19fb8e8baf82e90b7 (diff) | |
download | lua-4c0e36a46e11be2f101203ed0db66ea750bf4333.tar.gz lua-4c0e36a46e11be2f101203ed0db66ea750bf4333.tar.bz2 lua-4c0e36a46e11be2f101203ed0db66ea750bf4333.zip |
new instruction 'OP_EQK' (for equality with constants)
-rw-r--r-- | lcode.c | 55 | ||||
-rw-r--r-- | lopcodes.c | 4 | ||||
-rw-r--r-- | lopcodes.h | 4 | ||||
-rw-r--r-- | lvm.c | 12 |
4 files changed, 61 insertions, 14 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.131 2017/11/07 17:20:42 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.132 2017/11/08 14:50:23 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 | */ |
@@ -1251,10 +1251,10 @@ static void codecommutative (FuncState *fs, OpCode op, | |||
1251 | 1251 | ||
1252 | 1252 | ||
1253 | /* | 1253 | /* |
1254 | ** Emit code for comparisons. | 1254 | ** Emit code for order comparisons. |
1255 | ** 'e1' was already put in register by 'luaK_infix'. | 1255 | ** 'e1' was already put in register by 'luaK_infix'. |
1256 | */ | 1256 | */ |
1257 | static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | 1257 | static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { |
1258 | int rk1 = check_exp(e1->k == VNONRELOC, e1->u.info); | 1258 | int rk1 = check_exp(e1->k == VNONRELOC, e1->u.info); |
1259 | int rk2 = luaK_exp2anyreg(fs, e2); | 1259 | int rk2 = luaK_exp2anyreg(fs, e2); |
1260 | freeexps(fs, e1, e2); | 1260 | freeexps(fs, e1, e2); |
@@ -1280,6 +1280,30 @@ static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | |||
1280 | 1280 | ||
1281 | 1281 | ||
1282 | /* | 1282 | /* |
1283 | ** Emit code for equality comparisons ('==', '~='). | ||
1284 | ** 'e1' was already put as RK by 'luaK_infix'. | ||
1285 | */ | ||
1286 | static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | ||
1287 | int r1, rk2; | ||
1288 | OpCode op = OP_EQK; /* will try first to use a constant */ | ||
1289 | if (e1->k == VK) { /* 1st expression is constant? */ | ||
1290 | rk2 = e1->u.info; /* constant index */ | ||
1291 | r1 = luaK_exp2anyreg(fs, e2); /* 2nd expression must be in register */ | ||
1292 | } | ||
1293 | else { | ||
1294 | lua_assert(e1->k == VNONRELOC); /* 1st expression is in a register */ | ||
1295 | r1 = e1->u.info; | ||
1296 | if (!luaK_exp2RK(fs, e2)) /* 2nd expression is not constant? */ | ||
1297 | op = OP_EQ; /* will compare two registers */ | ||
1298 | rk2 = e2->u.info; /* constant/register index */ | ||
1299 | } | ||
1300 | freeexps(fs, e1, e2); | ||
1301 | e1->u.info = condjump(fs, op, (opr == OPR_EQ), r1, rk2); | ||
1302 | e1->k = VJMP; | ||
1303 | } | ||
1304 | |||
1305 | |||
1306 | /* | ||
1283 | ** Aplly prefix operation 'op' to expression 'e'. | 1307 | ** Aplly prefix operation 'op' to expression 'e'. |
1284 | */ | 1308 | */ |
1285 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | 1309 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { |
@@ -1321,12 +1345,17 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
1321 | case OPR_MOD: case OPR_POW: | 1345 | case OPR_MOD: case OPR_POW: |
1322 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | 1346 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
1323 | case OPR_SHL: case OPR_SHR: { | 1347 | case OPR_SHL: case OPR_SHR: { |
1324 | if (tonumeral(v, NULL)) | 1348 | if (!tonumeral(v, NULL)) |
1325 | break; /* keep numeral, which may be folded with 2nd operand */ | 1349 | luaK_exp2anyreg(fs, v); |
1326 | /* else *//* FALLTHROUGH */ | 1350 | /* else keep numeral, which may be folded with 2nd operand */ |
1351 | break; | ||
1352 | } | ||
1353 | case OPR_EQ: case OPR_NE: { | ||
1354 | luaK_exp2RK(fs, v); | ||
1355 | break; | ||
1327 | } | 1356 | } |
1328 | case OPR_EQ: case OPR_LT: case OPR_LE: | 1357 | case OPR_LT: case OPR_LE: |
1329 | case OPR_NE: case OPR_GT: case OPR_GE: { | 1358 | case OPR_GT: case OPR_GE: { |
1330 | luaK_exp2anyreg(fs, v); | 1359 | luaK_exp2anyreg(fs, v); |
1331 | break; | 1360 | break; |
1332 | } | 1361 | } |
@@ -1390,9 +1419,13 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |||
1390 | codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line); | 1419 | codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line); |
1391 | break; | 1420 | break; |
1392 | } | 1421 | } |
1393 | case OPR_EQ: case OPR_LT: case OPR_LE: | 1422 | case OPR_EQ: case OPR_NE: { |
1394 | case OPR_NE: case OPR_GT: case OPR_GE: { | 1423 | codeeq(fs, op, e1, e2); |
1395 | codecomp(fs, op, e1, e2); | 1424 | break; |
1425 | } | ||
1426 | case OPR_LT: case OPR_LE: | ||
1427 | case OPR_GT: case OPR_GE: { | ||
1428 | codeorder(fs, op, e1, e2); | ||
1396 | break; | 1429 | break; |
1397 | } | 1430 | } |
1398 | default: lua_assert(0); | 1431 | default: lua_assert(0); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.c,v 1.66 2017/10/04 15:49:24 roberto Exp roberto $ | 2 | ** $Id: lopcodes.c,v 1.67 2017/11/07 17:20:42 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 | */ |
@@ -66,6 +66,7 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { | |||
66 | "EQ", | 66 | "EQ", |
67 | "LT", | 67 | "LT", |
68 | "LE", | 68 | "LE", |
69 | "EQK", | ||
69 | "TEST", | 70 | "TEST", |
70 | "TESTSET", | 71 | "TESTSET", |
71 | "CALL", | 72 | "CALL", |
@@ -133,6 +134,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { | |||
133 | ,opmode(1, 0, iABC) /* OP_EQ */ | 134 | ,opmode(1, 0, iABC) /* OP_EQ */ |
134 | ,opmode(1, 0, iABC) /* OP_LT */ | 135 | ,opmode(1, 0, iABC) /* OP_LT */ |
135 | ,opmode(1, 0, iABC) /* OP_LE */ | 136 | ,opmode(1, 0, iABC) /* OP_LE */ |
137 | ,opmode(1, 0, iABC) /* OP_EQK */ | ||
136 | ,opmode(1, 0, iABC) /* OP_TEST */ | 138 | ,opmode(1, 0, iABC) /* OP_TEST */ |
137 | ,opmode(1, 1, iABC) /* OP_TESTSET */ | 139 | ,opmode(1, 1, iABC) /* OP_TESTSET */ |
138 | ,opmode(0, 1, iABC) /* OP_CALL */ | 140 | ,opmode(0, 1, iABC) /* OP_CALL */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.166 2017/10/04 21:56:32 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.167 2017/11/07 17:20:42 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 | */ |
@@ -240,6 +240,8 @@ OP_EQ,/* A B C if ((R(B) == R(C)) ~= A) then pc++ */ | |||
240 | OP_LT,/* A B C if ((R(B) < R(C)) ~= A) then pc++ */ | 240 | OP_LT,/* A B C if ((R(B) < R(C)) ~= A) then pc++ */ |
241 | OP_LE,/* A B C if ((R(B) <= R(C)) ~= A) then pc++ */ | 241 | OP_LE,/* A B C if ((R(B) <= R(C)) ~= A) then pc++ */ |
242 | 242 | ||
243 | OP_EQK,/* A B C if ((R(B) == K(C)) ~= A) then pc++ */ | ||
244 | |||
243 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ | 245 | OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ |
244 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ | 246 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ |
245 | 247 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.309 2017/11/08 19:01:02 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.310 2017/11/13 15:36:52 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 | */ |
@@ -1358,6 +1358,16 @@ void luaV_execute (lua_State *L) { | |||
1358 | donextjump(ci); | 1358 | donextjump(ci); |
1359 | vmbreak; | 1359 | vmbreak; |
1360 | } | 1360 | } |
1361 | vmcase(OP_EQK) { | ||
1362 | TValue *rb = vRB(i); | ||
1363 | TValue *rc = KC(i); | ||
1364 | /* basic types do not use '__eq'; we can use raw equality */ | ||
1365 | if (luaV_equalobj(NULL, rb, rc) != GETARG_A(i)) | ||
1366 | pc++; | ||
1367 | else | ||
1368 | donextjump(ci); | ||
1369 | vmbreak; | ||
1370 | } | ||
1361 | vmcase(OP_TEST) { | 1371 | vmcase(OP_TEST) { |
1362 | if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) | 1372 | if (GETARG_C(i) ? l_isfalse(s2v(ra)) : !l_isfalse(s2v(ra))) |
1363 | pc++; | 1373 | pc++; |