| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: lcode.c,v 1.12 2023/04/16 20:46:17 nikita Exp $ */ | | 1 | /* $NetBSD: lcode.c,v 1.13 2023/04/17 19:19:00 nikita Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | ** Id: lcode.c | | 4 | ** Id: lcode.c |
5 | ** Code generator for Lua | | 5 | ** Code generator for Lua |
6 | ** See Copyright Notice in lua.h | | 6 | ** See Copyright Notice in lua.h |
7 | */ | | 7 | */ |
8 | | | 8 | |
9 | #define lcode_c | | 9 | #define lcode_c |
10 | #define LUA_CORE | | 10 | #define LUA_CORE |
11 | | | 11 | |
12 | #include "lprefix.h" | | 12 | #include "lprefix.h" |
13 | | | 13 | |
14 | | | 14 | |
| @@ -1416,27 +1416,30 @@ static void finishbinexpval (FuncState * | | | @@ -1416,27 +1416,30 @@ static void finishbinexpval (FuncState * |
1416 | e1->k = VRELOC; /* all those operations are relocatable */ | | 1416 | e1->k = VRELOC; /* all those operations are relocatable */ |
1417 | luaK_fixline(fs, line); | | 1417 | luaK_fixline(fs, line); |
1418 | luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */ | | 1418 | luaK_codeABCk(fs, mmop, v1, v2, event, flip); /* to call metamethod */ |
1419 | luaK_fixline(fs, line); | | 1419 | luaK_fixline(fs, line); |
1420 | } | | 1420 | } |
1421 | | | 1421 | |
1422 | | | 1422 | |
1423 | /* | | 1423 | /* |
1424 | ** Emit code for binary expressions that "produce values" over | | 1424 | ** Emit code for binary expressions that "produce values" over |
1425 | ** two registers. | | 1425 | ** two registers. |
1426 | */ | | 1426 | */ |
1427 | static void codebinexpval (FuncState *fs, OpCode op, | | 1427 | static void codebinexpval (FuncState *fs, OpCode op, |
1428 | expdesc *e1, expdesc *e2, int line) { | | 1428 | expdesc *e1, expdesc *e2, int line) { |
1429 | int v2 = luaK_exp2anyreg(fs, e2); /* both operands are in registers */ | | 1429 | int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */ |
| | | 1430 | /* 'e1' must be already in a register or it is a constant */ |
| | | 1431 | lua_assert((VNIL <= e1->k && e1->k <= VKSTR) || |
| | | 1432 | e1->k == VNONRELOC || e1->k == VRELOC); |
1430 | lua_assert(OP_ADD <= op && op <= OP_SHR); | | 1433 | lua_assert(OP_ADD <= op && op <= OP_SHR); |
1431 | finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, | | 1434 | finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, |
1432 | cast(TMS, (op - OP_ADD) + TM_ADD)); | | 1435 | cast(TMS, (op - OP_ADD) + TM_ADD)); |
1433 | } | | 1436 | } |
1434 | | | 1437 | |
1435 | | | 1438 | |
1436 | /* | | 1439 | /* |
1437 | ** Code binary operators with immediate operands. | | 1440 | ** Code binary operators with immediate operands. |
1438 | */ | | 1441 | */ |
1439 | static void codebini (FuncState *fs, OpCode op, | | 1442 | static void codebini (FuncState *fs, OpCode op, |
1440 | expdesc *e1, expdesc *e2, int flip, int line, | | 1443 | expdesc *e1, expdesc *e2, int flip, int line, |
1441 | TMS event) { | | 1444 | TMS event) { |
1442 | int v2 = int2sC(cast_int(e2->u.ival)); /* immediate operand */ | | 1445 | int v2 = int2sC(cast_int(e2->u.ival)); /* immediate operand */ |
| @@ -1503,39 +1506,39 @@ static void codecommutative (FuncState * | | | @@ -1503,39 +1506,39 @@ static void codecommutative (FuncState * |
1503 | int flip = 0; | | 1506 | int flip = 0; |
1504 | if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ | | 1507 | if (tonumeral(e1, NULL)) { /* is first operand a numeric constant? */ |
1505 | swapexps(e1, e2); /* change order */ | | 1508 | swapexps(e1, e2); /* change order */ |
1506 | flip = 1; | | 1509 | flip = 1; |
1507 | } | | 1510 | } |
1508 | if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */ | | 1511 | if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */ |
1509 | codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD); | | 1512 | codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD); |
1510 | else | | 1513 | else |
1511 | codearith(fs, op, e1, e2, flip, line); | | 1514 | codearith(fs, op, e1, e2, flip, line); |
1512 | } | | 1515 | } |
1513 | | | 1516 | |
1514 | | | 1517 | |
1515 | /* | | 1518 | /* |
1516 | ** Code bitwise operations; they are all associative, so the function | | 1519 | ** Code bitwise operations; they are all commutative, so the function |
1517 | ** tries to put an integer constant as the 2nd operand (a K operand). | | 1520 | ** tries to put an integer constant as the 2nd operand (a K operand). |
1518 | */ | | 1521 | */ |
1519 | static void codebitwise (FuncState *fs, BinOpr opr, | | 1522 | static void codebitwise (FuncState *fs, BinOpr opr, |
1520 | expdesc *e1, expdesc *e2, int line) { | | 1523 | expdesc *e1, expdesc *e2, int line) { |
1521 | int flip = 0; | | 1524 | int flip = 0; |
1522 | int v2; | | 1525 | int v2; |
1523 | OpCode op; | | 1526 | OpCode op; |
1524 | if (e1->k == VKINT && luaK_exp2RK(fs, e1)) { | | 1527 | if (e1->k == VKINT && luaK_exp2K(fs, e1)) { |
1525 | swapexps(e1, e2); /* 'e2' will be the constant operand */ | | 1528 | swapexps(e1, e2); /* 'e2' will be the constant operand */ |
1526 | flip = 1; | | 1529 | flip = 1; |
1527 | } | | 1530 | } |
1528 | else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) { /* no constants? */ | | 1531 | else if (!(e2->k == VKINT && luaK_exp2K(fs, e2))) { /* no constants? */ |
1529 | op = cast(OpCode, opr + OP_ADD); | | 1532 | op = cast(OpCode, opr + OP_ADD); |
1530 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ | | 1533 | codebinexpval(fs, op, e1, e2, line); /* all-register opcodes */ |
1531 | return; | | 1534 | return; |
1532 | } | | 1535 | } |
1533 | v2 = e2->u.info; /* index in K array */ | | 1536 | v2 = e2->u.info; /* index in K array */ |
1534 | op = cast(OpCode, opr + OP_ADDK); | | 1537 | op = cast(OpCode, opr + OP_ADDK); |
1535 | lua_assert(ttisinteger(&fs->f->k[v2])); | | 1538 | lua_assert(ttisinteger(&fs->f->k[v2])); |
1536 | finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, | | 1539 | finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, |
1537 | cast(TMS, opr + TM_ADD)); | | 1540 | cast(TMS, opr + TM_ADD)); |
1538 | } | | 1541 | } |
1539 | | | 1542 | |
1540 | | | 1543 | |
1541 | /* | | 1544 | /* |
| @@ -1576,27 +1579,27 @@ static void codeeq (FuncState *fs, BinOp | | | @@ -1576,27 +1579,27 @@ static void codeeq (FuncState *fs, BinOp |
1576 | int r1, r2; | | 1579 | int r1, r2; |
1577 | int im; | | 1580 | int im; |
1578 | int isfloat = 0; /* not needed here, but kept for symmetry */ | | 1581 | int isfloat = 0; /* not needed here, but kept for symmetry */ |
1579 | OpCode op; | | 1582 | OpCode op; |
1580 | if (e1->k != VNONRELOC) { | | 1583 | if (e1->k != VNONRELOC) { |
1581 | lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); | | 1584 | lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT); |
1582 | swapexps(e1, e2); | | 1585 | swapexps(e1, e2); |
1583 | } | | 1586 | } |
1584 | r1 = luaK_exp2anyreg(fs, e1); /* 1st expression must be in register */ | | 1587 | r1 = luaK_exp2anyreg(fs, e1); /* 1st expression must be in register */ |
1585 | if (isSCnumber(e2, &im, &isfloat)) { | | 1588 | if (isSCnumber(e2, &im, &isfloat)) { |
1586 | op = OP_EQI; | | 1589 | op = OP_EQI; |
1587 | r2 = im; /* immediate operand */ | | 1590 | r2 = im; /* immediate operand */ |
1588 | } | | 1591 | } |
1589 | else if (luaK_exp2RK(fs, e2)) { /* 1st expression is constant? */ | | 1592 | else if (luaK_exp2RK(fs, e2)) { /* 2nd expression is constant? */ |
1590 | op = OP_EQK; | | 1593 | op = OP_EQK; |
1591 | r2 = e2->u.info; /* constant index */ | | 1594 | r2 = e2->u.info; /* constant index */ |
1592 | } | | 1595 | } |
1593 | else { | | 1596 | else { |
1594 | op = OP_EQ; /* will compare two registers */ | | 1597 | op = OP_EQ; /* will compare two registers */ |
1595 | r2 = luaK_exp2anyreg(fs, e2); | | 1598 | r2 = luaK_exp2anyreg(fs, e2); |
1596 | } | | 1599 | } |
1597 | freeexps(fs, e1, e2); | | 1600 | freeexps(fs, e1, e2); |
1598 | e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ)); | | 1601 | e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ)); |
1599 | e1->k = VJMP; | | 1602 | e1->k = VJMP; |
1600 | } | | 1603 | } |
1601 | | | 1604 | |
1602 | | | 1605 | |
| @@ -1641,27 +1644,28 @@ void luaK_infix (FuncState *fs, BinOpr o | | | @@ -1641,27 +1644,28 @@ void luaK_infix (FuncState *fs, BinOpr o |
1641 | } | | 1644 | } |
1642 | case OPR_ADD: case OPR_SUB: | | 1645 | case OPR_ADD: case OPR_SUB: |
1643 | #ifndef _KERNEL | | 1646 | #ifndef _KERNEL |
1644 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: | | 1647 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: |
1645 | case OPR_MOD: case OPR_POW: | | 1648 | case OPR_MOD: case OPR_POW: |
1646 | #else /* _KERNEL */ | | 1649 | #else /* _KERNEL */ |
1647 | case OPR_MUL: case OPR_IDIV: | | 1650 | case OPR_MUL: case OPR_IDIV: |
1648 | case OPR_MOD: | | 1651 | case OPR_MOD: |
1649 | #endif /* _KERNEL */ | | 1652 | #endif /* _KERNEL */ |
1650 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | | 1653 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
1651 | case OPR_SHL: case OPR_SHR: { | | 1654 | case OPR_SHL: case OPR_SHR: { |
1652 | if (!tonumeral(v, NULL)) | | 1655 | if (!tonumeral(v, NULL)) |
1653 | luaK_exp2anyreg(fs, v); | | 1656 | luaK_exp2anyreg(fs, v); |
1654 | /* else keep numeral, which may be folded with 2nd operand */ | | 1657 | /* else keep numeral, which may be folded or used as an immediate |
| | | 1658 | operand */ |
1655 | break; | | 1659 | break; |
1656 | } | | 1660 | } |
1657 | case OPR_EQ: case OPR_NE: { | | 1661 | case OPR_EQ: case OPR_NE: { |
1658 | if (!tonumeral(v, NULL)) | | 1662 | if (!tonumeral(v, NULL)) |
1659 | luaK_exp2RK(fs, v); | | 1663 | luaK_exp2RK(fs, v); |
1660 | /* else keep numeral, which may be an immediate operand */ | | 1664 | /* else keep numeral, which may be an immediate operand */ |
1661 | break; | | 1665 | break; |
1662 | } | | 1666 | } |
1663 | case OPR_LT: case OPR_LE: | | 1667 | case OPR_LT: case OPR_LE: |
1664 | case OPR_GT: case OPR_GE: { | | 1668 | case OPR_GT: case OPR_GE: { |
1665 | int dummy, dummy2; | | 1669 | int dummy, dummy2; |
1666 | if (!isSCnumber(v, &dummy, &dummy2)) | | 1670 | if (!isSCnumber(v, &dummy, &dummy2)) |
1667 | luaK_exp2anyreg(fs, v); | | 1671 | luaK_exp2anyreg(fs, v); |