浏览代码

opcodes 'OP_GETTABUP'/'OP_SETTABUP' operate only with string keys,
so they can use fast-track table access

Roberto Ierusalimschy 8 年之前
父节点
当前提交
cb3d5dce30
共有 3 个文件被更改,包括 30 次插入10 次删除
  1. 12 2
      lcode.c
  2. 3 1
      lopcodes.h
  3. 15 7
      lvm.c

+ 12 - 2
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
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -947,12 +947,22 @@ 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
 ** 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) {
 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
   lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
   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.t = t->u.info;  /* register or upvalue index */
   t->u.ind.idx = luaK_exp2RK(fs, k);  /* R/K index for key */
   t->u.ind.idx = luaK_exp2RK(fs, k);  /* R/K index for key */
   t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;
   t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;

+ 3 - 1
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
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 ** 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_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
   (*) For comparisons, A specifies what condition the test should accept
   (true or false).
   (true or false).
 
 

+ 15 - 7
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
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -838,9 +838,14 @@ void luaV_execute (lua_State *L) {
         vmbreak;
         vmbreak;
       }
       }
       vmcase(OP_GETTABUP) {
       vmcase(OP_GETTABUP) {
+        const TValue *slot;
         TValue *upval = cl->upvals[GETARG_B(i)]->v;
         TValue *upval = cl->upvals[GETARG_B(i)]->v;
         TValue *rc = RKC(i);
         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;
         vmbreak;
       }
       }
       vmcase(OP_GETTABLE) {
       vmcase(OP_GETTABLE) {
@@ -850,10 +855,13 @@ void luaV_execute (lua_State *L) {
         vmbreak;
         vmbreak;
       }
       }
       vmcase(OP_SETTABUP) {
       vmcase(OP_SETTABUP) {
+        const TValue *slot;
         TValue *upval = cl->upvals[GETARG_A(i)]->v;
         TValue *upval = cl->upvals[GETARG_A(i)]->v;
         TValue *rb = RKB(i);
         TValue *rb = RKB(i);
         TValue *rc = RKC(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;
         vmbreak;
       }
       }
       vmcase(OP_SETUPVAL) {
       vmcase(OP_SETUPVAL) {
@@ -879,15 +887,15 @@ void luaV_execute (lua_State *L) {
         vmbreak;
         vmbreak;
       }
       }
       vmcase(OP_SELF) {
       vmcase(OP_SELF) {
-        const TValue *aux;
+        const TValue *slot;
         StkId rb = RB(i);
         StkId rb = RB(i);
         TValue *rc = RKC(i);
         TValue *rc = RKC(i);
         TString *key = tsvalue(rc);  /* key must be a string */
         TString *key = tsvalue(rc);  /* key must be a string */
         setobjs2s(L, ra + 1, rb);
         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;
         vmbreak;
       }
       }
       vmcase(OP_ADD) {
       vmcase(OP_ADD) {