diff options
-rw-r--r-- | lvm.c | 68 |
1 files changed, 51 insertions, 17 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.277 2017/05/05 17:16:11 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.278 2017/05/08 16:08:01 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 | */ |
@@ -118,10 +118,9 @@ int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) { | |||
118 | 118 | ||
119 | 119 | ||
120 | /* | 120 | /* |
121 | ** Try to convert a 'for' limit to an integer, preserving the | 121 | ** Try to convert a 'for' limit to an integer, preserving the semantics |
122 | ** semantics of the loop. | 122 | ** of the loop. (The following explanation assumes a non-negative step; |
123 | ** (The following explanation assumes a non-negative step; it is valid | 123 | ** it is valid for negative steps mutatis mutandis.) |
124 | ** for negative steps mutatis mutandis.) | ||
125 | ** If the limit can be converted to an integer, rounding down, that is | 124 | ** If the limit can be converted to an integer, rounding down, that is |
126 | ** it. | 125 | ** it. |
127 | ** Otherwise, check whether the limit can be converted to a number. If | 126 | ** Otherwise, check whether the limit can be converted to a number. If |
@@ -807,6 +806,19 @@ void luaV_finishOp (lua_State *L) { | |||
807 | Protect(luaV_finishset(L,t,k,v,slot)); } | 806 | Protect(luaV_finishset(L,t,k,v,slot)); } |
808 | 807 | ||
809 | 808 | ||
809 | /* | ||
810 | ** Predicate for integer fast track in GET/SETTABLE. | ||
811 | ** (Strings are usually constant and therefore coded with | ||
812 | ** GET/SETFIELD). Check that index is an integer, "table" is | ||
813 | ** a table, index is in the array part, and value is not nil | ||
814 | ** (otherwise it will need metamethods). Use 'n' and 't' for | ||
815 | ** for caching the integer and table values. | ||
816 | */ | ||
817 | #define fastintindex(tbl,idx,t,n) \ | ||
818 | (ttisinteger(idx) && ttistable(tbl) && \ | ||
819 | (n = l_castS2U(ivalue(idx)) - 1u, t = hvalue(tbl), \ | ||
820 | n < t->sizearray) && !ttisnil(&t->array[n])) | ||
821 | |||
810 | 822 | ||
811 | void luaV_execute (lua_State *L) { | 823 | void luaV_execute (lua_State *L) { |
812 | CallInfo *ci = L->ci; | 824 | CallInfo *ci = L->ci; |
@@ -889,7 +901,12 @@ void luaV_execute (lua_State *L) { | |||
889 | vmcase(OP_GETTABLE) { | 901 | vmcase(OP_GETTABLE) { |
890 | StkId rb = RB(i); | 902 | StkId rb = RB(i); |
891 | TValue *rc = RC(i); | 903 | TValue *rc = RC(i); |
892 | gettableProtected(L, rb, rc, ra); | 904 | Table *t; lua_Unsigned n; |
905 | if (fastintindex(rb, rc, t, n)) { | ||
906 | setobj2s(L, ra, &t->array[n]); | ||
907 | } | ||
908 | else | ||
909 | gettableProtected(L, rb, rc, ra); | ||
893 | vmbreak; | 910 | vmbreak; |
894 | } | 911 | } |
895 | vmcase(OP_GETI) { | 912 | vmcase(OP_GETI) { |
@@ -930,7 +947,12 @@ void luaV_execute (lua_State *L) { | |||
930 | vmcase(OP_SETTABLE) { | 947 | vmcase(OP_SETTABLE) { |
931 | TValue *rb = RB(i); | 948 | TValue *rb = RB(i); |
932 | TValue *rc = RKC(i); | 949 | TValue *rc = RKC(i); |
933 | settableProtected(L, ra, rb, rc); | 950 | Table *t; lua_Unsigned n; |
951 | if (fastintindex(ra, rb, t, n)) { | ||
952 | setobj2t(L, &t->array[n], rc); | ||
953 | } | ||
954 | else | ||
955 | settableProtected(L, ra, rb, rc); | ||
934 | vmbreak; | 956 | vmbreak; |
935 | } | 957 | } |
936 | vmcase(OP_SETI) { | 958 | vmcase(OP_SETI) { |
@@ -1205,21 +1227,33 @@ void luaV_execute (lua_State *L) { | |||
1205 | vmbreak; | 1227 | vmbreak; |
1206 | } | 1228 | } |
1207 | vmcase(OP_LT) { | 1229 | vmcase(OP_LT) { |
1208 | Protect( | 1230 | TValue *rb = RKB(i); |
1209 | if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) | 1231 | TValue *rc = RKC(i); |
1210 | pc++; | 1232 | int res; |
1211 | else | 1233 | if (ttisinteger(rb) && ttisinteger(rc)) |
1212 | donextjump(ci); | 1234 | res = (ivalue(rb) < ivalue(rc)); |
1235 | else Protect( | ||
1236 | res = luaV_lessthan(L, rb, rc); | ||
1213 | ) | 1237 | ) |
1238 | if (res != GETARG_A(i)) | ||
1239 | pc++; | ||
1240 | else | ||
1241 | donextjump(ci); | ||
1214 | vmbreak; | 1242 | vmbreak; |
1215 | } | 1243 | } |
1216 | vmcase(OP_LE) { | 1244 | vmcase(OP_LE) { |
1217 | Protect( | 1245 | TValue *rb = RKB(i); |
1218 | if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) | 1246 | TValue *rc = RKC(i); |
1219 | pc++; | 1247 | int res; |
1220 | else | 1248 | if (ttisinteger(rb) && ttisinteger(rc)) |
1221 | donextjump(ci); | 1249 | res = (ivalue(rb) <= ivalue(rc)); |
1250 | else Protect( | ||
1251 | res = luaV_lessequal(L, rb, rc); | ||
1222 | ) | 1252 | ) |
1253 | if (res != GETARG_A(i)) | ||
1254 | pc++; | ||
1255 | else | ||
1256 | donextjump(ci); | ||
1223 | vmbreak; | 1257 | vmbreak; |
1224 | } | 1258 | } |
1225 | vmcase(OP_TEST) { | 1259 | vmcase(OP_TEST) { |