diff --git a/lvm.c b/lvm.c index 59f36e3a..25dc40f2 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 2.250 2015/08/03 20:40:26 roberto Exp roberto $ +** $Id: lvm.c,v 2.251 2015/09/08 15:41:05 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -216,11 +216,8 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, return; } t = tm; /* else repeat assignment over 'tm' */ - if (luaV_fastset(L, t, key, oldval, luaH_get, val)) { - invalidateTMcache(hvalue(t)); - setobj2t(L, cast(TValue *, oldval), val); - return; - } + if (luaV_fastset(L, t, key, oldval, luaH_get, val)) + return; /* done */ /* else loop */ } luaG_runerror(L, "settable chain too long; possible loop"); diff --git a/lvm.h b/lvm.h index ccdacd4a..b65061ac 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 2.37 2015/08/03 19:50:49 roberto Exp roberto $ +** $Id: lvm.h,v 2.38 2015/08/03 20:40:26 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -70,17 +70,27 @@ else luaV_finishget(L,t,k,v,aux); } -#define luaV_fastset(L,t,k,aux,f,v) \ +/* +** Fast track for set table. If 't' is a table and 't[k]' is not nil, +** call GC barrier, do a raw 't[k]=v', and return true; otherwise, +** return false with 'slot' equal to NULL (if 't' is not a table) or +** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro +** returns true, there is no need to 'invalidateTMcache', because the +** call is not creating a new entry. +*/ +#define luaV_fastset(L,t,k,slot,f,v) \ (!ttistable(t) \ - ? (aux = NULL, 0) \ - : (aux = f(hvalue(t), k), \ - ttisnil(aux) ? 0 \ - : (luaC_barrierback(L, hvalue(t), v), 1))) + ? (slot = NULL, 0) \ + : (slot = f(hvalue(t), k), \ + ttisnil(slot) ? 0 \ + : (luaC_barrierback(L, hvalue(t), v), \ + setobj2t(L, cast(TValue *,slot), v), \ + 1))) -#define luaV_settable(L,t,k,v) { const TValue *aux; \ - if (luaV_fastset(L,t,k,aux,luaH_get,v)) \ - { invalidateTMcache(hvalue(t)); setobj2t(L, cast(TValue *,aux), v); } \ - else luaV_finishset(L,t,k,v,aux); } + +#define luaV_settable(L,t,k,v) { const TValue *slot; \ + if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ + luaV_finishset(L,t,k,v,slot); }