commit cb3d5dce30089512085f78a0bef79e30ef732e30
parent 2caecf1b3efdbee4e08888a04143421589d6143b
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 24 Apr 2017 17:26:12 -0300
opcodes 'OP_GETTABUP'/'OP_SETTABUP' operate only with string keys,
so they can use fast-track table access
Diffstat:
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/lcode.c b/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 2.112 2016/12/22 13:08:50 roberto Exp roberto $
+** $Id: lcode.c,v 2.113 2017/04/20 19:53:55 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -948,11 +948,21 @@ static void codenot (FuncState *fs, expdesc *e) {
/*
+** Check whether expression 'e' is a literal string
+*/
+static int isKstr (FuncState *fs, expdesc *e) {
+ return (e->k == VK && ttisstring(&fs->f->k[e->u.info]));
+}
+
+
+/*
** Create expression 't[k]'. 't' must have its final result already in a
-** register or upvalue.
+** register or upvalue. Upvalues can only be indexed by literal strings.
*/
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
+ if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non string? */
+ luaK_exp2anyreg(fs, t); /* put it in a register */
t->u.ind.t = t->u.info; /* register or upvalue index */
t->u.ind.idx = luaK_exp2RK(fs, k); /* R/K index for key */
t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;
diff --git a/lopcodes.h b/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.149 2016/07/19 17:12:21 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.150 2017/04/20 19:53:55 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -255,6 +255,8 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
(*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
+ (*) In OP_GETTABUP, OP_SETTABUP, and OP_SELF, the index must be a string.
+
(*) For comparisons, A specifies what condition the test should accept
(true or false).
diff --git a/lvm.c b/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.270 2017/04/11 18:41:09 roberto Exp roberto $
+** $Id: lvm.c,v 2.271 2017/04/20 19:53:55 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -838,9 +838,14 @@ void luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_GETTABUP) {
+ const TValue *slot;
TValue *upval = cl->upvals[GETARG_B(i)]->v;
TValue *rc = RKC(i);
- gettableProtected(L, upval, rc, ra);
+ TString *key = tsvalue(rc); /* key must be a string */
+ if (luaV_fastget(L, upval, key, slot, luaH_getstr)) {
+ setobj2s(L, ra, slot);
+ }
+ else Protect(luaV_finishget(L, upval, rc, ra, slot));
vmbreak;
}
vmcase(OP_GETTABLE) {
@@ -850,10 +855,13 @@ void luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_SETTABUP) {
+ const TValue *slot;
TValue *upval = cl->upvals[GETARG_A(i)]->v;
TValue *rb = RKB(i);
TValue *rc = RKC(i);
- settableProtected(L, upval, rb, rc);
+ TString *key = tsvalue(rb); /* key must be a string */
+ if (!luaV_fastset(L, upval, key, slot, luaH_getstr, rc))
+ Protect(luaV_finishset(L, upval, rb, rc, slot));
vmbreak;
}
vmcase(OP_SETUPVAL) {
@@ -879,15 +887,15 @@ void luaV_execute (lua_State *L) {
vmbreak;
}
vmcase(OP_SELF) {
- const TValue *aux;
+ const TValue *slot;
StkId rb = RB(i);
TValue *rc = RKC(i);
TString *key = tsvalue(rc); /* key must be a string */
setobjs2s(L, ra + 1, rb);
- if (luaV_fastget(L, rb, key, aux, luaH_getstr)) {
- setobj2s(L, ra, aux);
+ if (luaV_fastget(L, rb, key, slot, luaH_getstr)) {
+ setobj2s(L, ra, slot);
}
- else Protect(luaV_finishget(L, rb, rc, ra, aux));
+ else Protect(luaV_finishget(L, rb, rc, ra, slot));
vmbreak;
}
vmcase(OP_ADD) {