diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-24 17:26:39 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-04-24 17:26:39 -0300 |
commit | cb3d5dce30089512085f78a0bef79e30ef732e30 (patch) | |
tree | 0459a127a7a7641a0a8f5eec7558db1432730e6d | |
parent | 2caecf1b3efdbee4e08888a04143421589d6143b (diff) | |
download | lua-cb3d5dce30089512085f78a0bef79e30ef732e30.tar.gz lua-cb3d5dce30089512085f78a0bef79e30ef732e30.tar.bz2 lua-cb3d5dce30089512085f78a0bef79e30ef732e30.zip |
opcodes 'OP_GETTABUP'/'OP_SETTABUP' operate only with string keys,
so they can use fast-track table access
-rw-r--r-- | lcode.c | 14 | ||||
-rw-r--r-- | lopcodes.h | 4 | ||||
-rw-r--r-- | lvm.c | 22 |
3 files changed, 30 insertions, 10 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 2.112 2016/12/22 13:08:50 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.113 2017/04/20 19:53:55 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 | */ |
@@ -948,11 +948,21 @@ static void codenot (FuncState *fs, expdesc *e) { | |||
948 | 948 | ||
949 | 949 | ||
950 | /* | 950 | /* |
951 | ** Check whether expression 'e' is a literal string | ||
952 | */ | ||
953 | static int isKstr (FuncState *fs, expdesc *e) { | ||
954 | return (e->k == VK && ttisstring(&fs->f->k[e->u.info])); | ||
955 | } | ||
956 | |||
957 | |||
958 | /* | ||
951 | ** Create expression 't[k]'. 't' must have its final result already in a | 959 | ** Create expression 't[k]'. 't' must have its final result already in a |
952 | ** register or upvalue. | 960 | ** register or upvalue. Upvalues can only be indexed by literal strings. |
953 | */ | 961 | */ |
954 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | 962 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { |
955 | lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL)); | 963 | lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL)); |
964 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */ | ||
965 | luaK_exp2anyreg(fs, t); /* put it in a register */ | ||
956 | t->u.ind.t = t->u.info; /* register or upvalue index */ | 966 | t->u.ind.t = t->u.info; /* register or upvalue index */ |
957 | t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */ | 967 | t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */ |
958 | t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL; | 968 | t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.149 2016/07/19 17:12:21 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.150 2017/04/20 19:53:55 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -255,6 +255,8 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ | |||
255 | 255 | ||
256 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. | 256 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. |
257 | 257 | ||
258 | (*) In OP_GETTABUP, OP_SETTABUP, and OP_SELF, the index must be a string. | ||
259 | |||
258 | (*) For comparisons, A specifies what condition the test should accept | 260 | (*) For comparisons, A specifies what condition the test should accept |
259 | (true or false). | 261 | (true or false). |
260 | 262 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.270 2017/04/11 18:41:09 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.271 2017/04/20 19:53:55 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 | */ |
@@ -838,9 +838,14 @@ void luaV_execute (lua_State *L) { | |||
838 | vmbreak; | 838 | vmbreak; |
839 | } | 839 | } |
840 | vmcase(OP_GETTABUP) { | 840 | vmcase(OP_GETTABUP) { |
841 | const TValue *slot; | ||
841 | TValue *upval = cl->upvals[GETARG_B(i)]->v; | 842 | TValue *upval = cl->upvals[GETARG_B(i)]->v; |
842 | TValue *rc = RKC(i); | 843 | TValue *rc = RKC(i); |
843 | gettableProtected(L, upval, rc, ra); | 844 | TString *key = tsvalue(rc); /* key must be a string */ |
845 | if (luaV_fastget(L, upval, key, slot, luaH_getstr)) { | ||
846 | setobj2s(L, ra, slot); | ||
847 | } | ||
848 | else Protect(luaV_finishget(L, upval, rc, ra, slot)); | ||
844 | vmbreak; | 849 | vmbreak; |
845 | } | 850 | } |
846 | vmcase(OP_GETTABLE) { | 851 | vmcase(OP_GETTABLE) { |
@@ -850,10 +855,13 @@ void luaV_execute (lua_State *L) { | |||
850 | vmbreak; | 855 | vmbreak; |
851 | } | 856 | } |
852 | vmcase(OP_SETTABUP) { | 857 | vmcase(OP_SETTABUP) { |
858 | const TValue *slot; | ||
853 | TValue *upval = cl->upvals[GETARG_A(i)]->v; | 859 | TValue *upval = cl->upvals[GETARG_A(i)]->v; |
854 | TValue *rb = RKB(i); | 860 | TValue *rb = RKB(i); |
855 | TValue *rc = RKC(i); | 861 | TValue *rc = RKC(i); |
856 | settableProtected(L, upval, rb, rc); | 862 | TString *key = tsvalue(rb); /* key must be a string */ |
863 | if (!luaV_fastset(L, upval, key, slot, luaH_getstr, rc)) | ||
864 | Protect(luaV_finishset(L, upval, rb, rc, slot)); | ||
857 | vmbreak; | 865 | vmbreak; |
858 | } | 866 | } |
859 | vmcase(OP_SETUPVAL) { | 867 | vmcase(OP_SETUPVAL) { |
@@ -879,15 +887,15 @@ void luaV_execute (lua_State *L) { | |||
879 | vmbreak; | 887 | vmbreak; |
880 | } | 888 | } |
881 | vmcase(OP_SELF) { | 889 | vmcase(OP_SELF) { |
882 | const TValue *aux; | 890 | const TValue *slot; |
883 | StkId rb = RB(i); | 891 | StkId rb = RB(i); |
884 | TValue *rc = RKC(i); | 892 | TValue *rc = RKC(i); |
885 | TString *key = tsvalue(rc); /* key must be a string */ | 893 | TString *key = tsvalue(rc); /* key must be a string */ |
886 | setobjs2s(L, ra + 1, rb); | 894 | setobjs2s(L, ra + 1, rb); |
887 | if (luaV_fastget(L, rb, key, aux, luaH_getstr)) { | 895 | if (luaV_fastget(L, rb, key, slot, luaH_getstr)) { |
888 | setobj2s(L, ra, aux); | 896 | setobj2s(L, ra, slot); |
889 | } | 897 | } |
890 | else Protect(luaV_finishget(L, rb, rc, ra, aux)); | 898 | else Protect(luaV_finishget(L, rb, rc, ra, slot)); |
891 | vmbreak; | 899 | vmbreak; |
892 | } | 900 | } |
893 | vmcase(OP_ADD) { | 901 | vmcase(OP_ADD) { |