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) { |
