diff options
Diffstat (limited to 'lcode.c')
-rw-r--r-- | lcode.c | 52 |
1 files changed, 42 insertions, 10 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.141 2017/11/30 15:37:16 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.142 2017/12/04 17:41:30 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 | */ |
@@ -1196,6 +1196,15 @@ static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) { | |||
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | 1198 | ||
1199 | static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2, | ||
1200 | int pc, int line) { | ||
1201 | freeexps(fs, e1, e2); | ||
1202 | e1->u.info = pc; | ||
1203 | e1->k = VRELOCABLE; /* all those operations are relocatable */ | ||
1204 | luaK_fixline(fs, line); | ||
1205 | } | ||
1206 | |||
1207 | |||
1199 | /* | 1208 | /* |
1200 | ** Emit code for binary expressions that "produce values" | 1209 | ** Emit code for binary expressions that "produce values" |
1201 | ** (everything but logical operators 'and'/'or' and comparison | 1210 | ** (everything but logical operators 'and'/'or' and comparison |
@@ -1209,10 +1218,8 @@ static void codebinexpval (FuncState *fs, OpCode op, | |||
1209 | expdesc *e1, expdesc *e2, int line) { | 1218 | expdesc *e1, expdesc *e2, int line) { |
1210 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ | 1219 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ |
1211 | int v1 = luaK_exp2anyreg(fs, e1); | 1220 | int v1 = luaK_exp2anyreg(fs, e1); |
1212 | freeexps(fs, e1, e2); | 1221 | int pc = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */ |
1213 | e1->u.info = luaK_codeABC(fs, op, 0, v1, v2); /* generate opcode */ | 1222 | finishbinexpval(fs, e1, e2, pc, line); |
1214 | e1->k = VRELOCABLE; /* all those operations are relocatable */ | ||
1215 | luaK_fixline(fs, line); | ||
1216 | } | 1223 | } |
1217 | 1224 | ||
1218 | 1225 | ||
@@ -1223,10 +1230,8 @@ static void codebini (FuncState *fs, OpCode op, | |||
1223 | expdesc *e1, expdesc *e2, int k, int line) { | 1230 | expdesc *e1, expdesc *e2, int k, int line) { |
1224 | int v2 = cast_int(e2->u.ival); /* immediate operand */ | 1231 | int v2 = cast_int(e2->u.ival); /* immediate operand */ |
1225 | int v1 = luaK_exp2anyreg(fs, e1); | 1232 | int v1 = luaK_exp2anyreg(fs, e1); |
1226 | freeexp(fs, e1); | 1233 | int pc = codeABsC(fs, op, 0, v1, v2, k); /* generate opcode */ |
1227 | e1->u.info = codeABsC(fs, op, 0, v1, v2, k); /* generate opcode */ | 1234 | finishbinexpval(fs, e1, e2, pc, line); |
1228 | e1->k = VRELOCABLE; /* all those operations are relocatable */ | ||
1229 | luaK_fixline(fs, line); | ||
1230 | } | 1235 | } |
1231 | 1236 | ||
1232 | 1237 | ||
@@ -1265,6 +1270,33 @@ static void codecommutative (FuncState *fs, OpCode op, | |||
1265 | 1270 | ||
1266 | 1271 | ||
1267 | /* | 1272 | /* |
1273 | ** Code bitwise operations; they are all associative, so the function | ||
1274 | ** tries to put an integer constant as the 2nd operand (a K operand). | ||
1275 | */ | ||
1276 | static void codebitwise (FuncState *fs, BinOpr opr, | ||
1277 | expdesc *e1, expdesc *e2, int line) { | ||
1278 | int inv = 0; | ||
1279 | int v1, v2, pc; | ||
1280 | OpCode op; | ||
1281 | if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { | ||
1282 | swapexps(e1, e2); /* 'e2' will be the constant operand */ | ||
1283 | inv = 1; | ||
1284 | } | ||
1285 | else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ | ||
1286 | op = cast(OpCode, opr - OPR_BAND + OP_BAND); | ||
1287 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ | ||
1288 | return; | ||
1289 | } | ||
1290 | v1 = luaK_exp2anyreg(fs, e1); | ||
1291 | v2 = e2->u.info; /* index in K array */ | ||
1292 | op = cast(OpCode, opr - OPR_BAND + OP_BANDK); | ||
1293 | lua_assert(ttisinteger(&fs->f->k[v2])); | ||
1294 | pc = luaK_codeABCk(fs, op, 0, v1, v2, inv); | ||
1295 | finishbinexpval(fs, e1, e2, pc, line); | ||
1296 | } | ||
1297 | |||
1298 | |||
1299 | /* | ||
1268 | ** Code shift operators. If second operand is constant, use immediate | 1300 | ** Code shift operators. If second operand is constant, use immediate |
1269 | ** operand (negating it if shift is in the other direction). | 1301 | ** operand (negating it if shift is in the other direction). |
1270 | */ | 1302 | */ |
@@ -1468,7 +1500,7 @@ void luaK_posfix (FuncState *fs, BinOpr opr, | |||
1468 | } | 1500 | } |
1469 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { | 1501 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: { |
1470 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) | 1502 | if (!constfolding(fs, opr + LUA_OPADD, e1, e2)) |
1471 | codebinexpval(fs, cast(OpCode, opr + OP_ADD), e1, e2, line); | 1503 | codebitwise(fs, opr, e1, e2, line); |
1472 | break; | 1504 | break; |
1473 | } | 1505 | } |
1474 | case OPR_SHL: { | 1506 | case OPR_SHL: { |