diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-08-27 13:59:39 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-08-27 13:59:39 -0300 |
commit | df13f259487459f3a28d31d76c890aa6c2d061e0 (patch) | |
tree | f354a0746530369d4dd70113c9752d019fbd200b /lvm.c | |
parent | 643188d6e58dfd3270d689230867289347260b74 (diff) | |
download | lua-df13f259487459f3a28d31d76c890aa6c2d061e0.tar.gz lua-df13f259487459f3a28d31d76c890aa6c2d061e0.tar.bz2 lua-df13f259487459f3a28d31d76c890aa6c2d061e0.zip |
First version of OP_MMBIN opcodes
In arithmetic/bitwise operators, the call to metamethods is made
in a separate opcode following the main one. (The main
opcode skips this next one when the operation succeeds.) This
change reduces slightly the size of the binary and the complexity
of the arithmetic/bitwise opcodes. It also simplfies the treatment
of errors and yeld/resume in these operations, as there are much
fewer cases to consider. (Only OP_MMBIN/OP_MMBINI/OP_MMBINK,
instead of all variants of all arithmetic/bitwise operators.)
Diffstat (limited to '')
-rw-r--r-- | lvm.c | 85 |
1 files changed, 46 insertions, 39 deletions
@@ -717,18 +717,11 @@ void luaV_finishOp (lua_State *L) { | |||
717 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | 717 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
718 | OpCode op = GET_OPCODE(inst); | 718 | OpCode op = GET_OPCODE(inst); |
719 | switch (op) { /* finish its execution */ | 719 | switch (op) { /* finish its execution */ |
720 | case OP_ADDI: case OP_SUBI: | 720 | case OP_MMBIN: case OP_MMBINI: case OP_MMBINK: { |
721 | case OP_MULI: case OP_DIVI: case OP_IDIVI: | 721 | setobjs2s(L, base + GETARG_A(*(ci->u.l.savedpc - 2)), --L->top); |
722 | case OP_MODI: case OP_POWI: | 722 | break; |
723 | case OP_ADDK: case OP_SUBK: | 723 | } |
724 | case OP_MULK: case OP_DIVK: case OP_IDIVK: | ||
725 | case OP_MODK: case OP_POWK: | ||
726 | case OP_ADD: case OP_SUB: | ||
727 | case OP_MUL: case OP_DIV: case OP_IDIV: | ||
728 | case OP_BANDK: case OP_BORK: case OP_BXORK: | ||
729 | case OP_BAND: case OP_BOR: case OP_BXOR: | ||
730 | case OP_SHLI: case OP_SHRI: case OP_SHL: case OP_SHR: | 724 | case OP_SHLI: case OP_SHRI: case OP_SHL: case OP_SHR: |
731 | case OP_MOD: case OP_POW: | ||
732 | case OP_UNM: case OP_BNOT: case OP_LEN: | 725 | case OP_UNM: case OP_BNOT: case OP_LEN: |
733 | case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: | 726 | case OP_GETTABUP: case OP_GETTABLE: case OP_GETI: |
734 | case OP_GETFIELD: case OP_SELF: { | 727 | case OP_GETFIELD: case OP_SELF: { |
@@ -804,10 +797,8 @@ void luaV_finishOp (lua_State *L) { | |||
804 | lua_Number nb; \ | 797 | lua_Number nb; \ |
805 | if (tonumberns(v1, nb)) { \ | 798 | if (tonumberns(v1, nb)) { \ |
806 | lua_Number fimm = cast_num(imm); \ | 799 | lua_Number fimm = cast_num(imm); \ |
807 | setfltvalue(s2v(ra), fop(L, nb, fimm)); \ | 800 | pc++; setfltvalue(s2v(ra), fop(L, nb, fimm)); \ |
808 | } \ | 801 | }} |
809 | else \ | ||
810 | ProtectNT(luaT_trybiniTM(L, v1, imm, flip, ra, tm)); } | ||
811 | 802 | ||
812 | 803 | ||
813 | /* | 804 | /* |
@@ -827,7 +818,7 @@ void luaV_finishOp (lua_State *L) { | |||
827 | int imm = GETARG_sC(i); \ | 818 | int imm = GETARG_sC(i); \ |
828 | if (ttisinteger(v1)) { \ | 819 | if (ttisinteger(v1)) { \ |
829 | lua_Integer iv1 = ivalue(v1); \ | 820 | lua_Integer iv1 = ivalue(v1); \ |
830 | setivalue(s2v(ra), iop(L, iv1, imm)); \ | 821 | pc++; setivalue(s2v(ra), iop(L, iv1, imm)); \ |
831 | } \ | 822 | } \ |
832 | else op_arithfI_aux(L, v1, imm, fop, tm, flip); } | 823 | else op_arithfI_aux(L, v1, imm, fop, tm, flip); } |
833 | 824 | ||
@@ -839,10 +830,8 @@ void luaV_finishOp (lua_State *L) { | |||
839 | #define op_arithf_aux(L,v1,v2,fop,tm) { \ | 830 | #define op_arithf_aux(L,v1,v2,fop,tm) { \ |
840 | lua_Number n1; lua_Number n2; \ | 831 | lua_Number n1; lua_Number n2; \ |
841 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | 832 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ |
842 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | 833 | pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ |
843 | } \ | 834 | }} |
844 | else \ | ||
845 | ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } | ||
846 | 835 | ||
847 | 836 | ||
848 | /* | 837 | /* |
@@ -862,7 +851,7 @@ void luaV_finishOp (lua_State *L) { | |||
862 | TValue *v2 = vRC(i); \ | 851 | TValue *v2 = vRC(i); \ |
863 | if (ttisinteger(v1) && ttisinteger(v2)) { \ | 852 | if (ttisinteger(v1) && ttisinteger(v2)) { \ |
864 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ | 853 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ |
865 | setivalue(s2v(ra), iop(L, i1, i2)); \ | 854 | pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ |
866 | } \ | 855 | } \ |
867 | else op_arithf_aux(L, v1, v2, fop, tm); } | 856 | else op_arithf_aux(L, v1, v2, fop, tm); } |
868 | 857 | ||
@@ -875,15 +864,13 @@ void luaV_finishOp (lua_State *L) { | |||
875 | TValue *v2 = KC(i); \ | 864 | TValue *v2 = KC(i); \ |
876 | if (ttisinteger(v1) && ttisinteger(v2)) { \ | 865 | if (ttisinteger(v1) && ttisinteger(v2)) { \ |
877 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ | 866 | lua_Integer i1 = ivalue(v1); lua_Integer i2 = ivalue(v2); \ |
878 | setivalue(s2v(ra), iop(L, i1, i2)); \ | 867 | pc++; setivalue(s2v(ra), iop(L, i1, i2)); \ |
879 | } \ | 868 | } \ |
880 | else { \ | 869 | else { \ |
881 | lua_Number n1; lua_Number n2; \ | 870 | lua_Number n1; lua_Number n2; \ |
882 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | 871 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ |
883 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | 872 | pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ |
884 | } \ | 873 | }}} |
885 | else \ | ||
886 | ProtectNT(luaT_trybinassocTM(L, v1, v2, ra, flip, tm)); } } | ||
887 | 874 | ||
888 | 875 | ||
889 | /* | 876 | /* |
@@ -894,10 +881,8 @@ void luaV_finishOp (lua_State *L) { | |||
894 | TValue *v2 = KC(i); \ | 881 | TValue *v2 = KC(i); \ |
895 | lua_Number n1; lua_Number n2; \ | 882 | lua_Number n1; lua_Number n2; \ |
896 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ | 883 | if (tonumberns(v1, n1) && tonumberns(v2, n2)) { \ |
897 | setfltvalue(s2v(ra), fop(L, n1, n2)); \ | 884 | pc++; setfltvalue(s2v(ra), fop(L, n1, n2)); \ |
898 | } \ | 885 | }} |
899 | else \ | ||
900 | ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } | ||
901 | 886 | ||
902 | 887 | ||
903 | /* | 888 | /* |
@@ -909,10 +894,8 @@ void luaV_finishOp (lua_State *L) { | |||
909 | lua_Integer i1; \ | 894 | lua_Integer i1; \ |
910 | lua_Integer i2 = ivalue(v2); \ | 895 | lua_Integer i2 = ivalue(v2); \ |
911 | if (tointegerns(v1, &i1)) { \ | 896 | if (tointegerns(v1, &i1)) { \ |
912 | setivalue(s2v(ra), op(L, i1, i2)); \ | 897 | pc++; setivalue(s2v(ra), op(L, i1, i2)); \ |
913 | } \ | 898 | }} |
914 | else \ | ||
915 | ProtectNT(luaT_trybiniTM(L, v1, i2, TESTARG_k(i), ra, tm)); } | ||
916 | 899 | ||
917 | 900 | ||
918 | /* | 901 | /* |
@@ -923,10 +906,8 @@ void luaV_finishOp (lua_State *L) { | |||
923 | TValue *v2 = vRC(i); \ | 906 | TValue *v2 = vRC(i); \ |
924 | lua_Integer i1; lua_Integer i2; \ | 907 | lua_Integer i1; lua_Integer i2; \ |
925 | if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ | 908 | if (tointegerns(v1, &i1) && tointegerns(v2, &i2)) { \ |
926 | setivalue(s2v(ra), op(L, i1, i2)); \ | 909 | pc++; setivalue(s2v(ra), op(L, i1, i2)); \ |
927 | } \ | 910 | }} |
928 | else \ | ||
929 | ProtectNT(luaT_trybinTM(L, v1, v2, ra, tm)); } | ||
930 | 911 | ||
931 | 912 | ||
932 | /* | 913 | /* |
@@ -1443,6 +1424,33 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1443 | ProtectNT(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); | 1424 | ProtectNT(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); |
1444 | vmbreak; | 1425 | vmbreak; |
1445 | } | 1426 | } |
1427 | vmcase(OP_MMBIN) { | ||
1428 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1429 | TValue *rb = vRB(i); | ||
1430 | TMS tm = (TMS)GETARG_C(i); | ||
1431 | StkId result = RA(pi); | ||
1432 | lua_assert(OP_ADD <= GET_OPCODE(pi) && GET_OPCODE(pi) <= OP_SHR); | ||
1433 | ProtectNT(luaT_trybinTM(L, s2v(ra), rb, result, tm)); | ||
1434 | vmbreak; | ||
1435 | } | ||
1436 | vmcase(OP_MMBINI) { | ||
1437 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1438 | int imm = GETARG_sB(i); | ||
1439 | TMS tm = (TMS)GETARG_C(i); | ||
1440 | int flip = GETARG_k(i); | ||
1441 | StkId result = RA(pi); | ||
1442 | ProtectNT(luaT_trybiniTM(L, s2v(ra), imm, flip, result, tm)); | ||
1443 | vmbreak; | ||
1444 | } | ||
1445 | vmcase(OP_MMBINK) { | ||
1446 | Instruction pi = *(pc - 2); /* original arith. expression */ | ||
1447 | TValue *imm = KB(i); | ||
1448 | TMS tm = (TMS)GETARG_C(i); | ||
1449 | int flip = GETARG_k(i); | ||
1450 | StkId result = RA(pi); | ||
1451 | ProtectNT(luaT_trybinassocTM(L, s2v(ra), imm, flip, result, tm)); | ||
1452 | vmbreak; | ||
1453 | } | ||
1446 | vmcase(OP_UNM) { | 1454 | vmcase(OP_UNM) { |
1447 | TValue *rb = vRB(i); | 1455 | TValue *rb = vRB(i); |
1448 | lua_Number nb; | 1456 | lua_Number nb; |
@@ -1826,4 +1834,3 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1826 | } | 1834 | } |
1827 | 1835 | ||
1828 | /* }================================================================== */ | 1836 | /* }================================================================== */ |
1829 | |||