aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-07-20 15:24:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-07-20 15:24:50 -0300
commite247c3ada3ff47a1352927e797263137f4e02e0e (patch)
tree4d2563f59472bdee4c4f58dd87cb1d8eeaf2c1b3 /lvm.c
parentb5dc2f9b0c57fef5f72152973938ff5265366dcd (diff)
downloadlua-e247c3ada3ff47a1352927e797263137f4e02e0e.tar.gz
lua-e247c3ada3ff47a1352927e797263137f4e02e0e.tar.bz2
lua-e247c3ada3ff47a1352927e797263137f4e02e0e.zip
implementation of fast track for gettable operations
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/lvm.c b/lvm.c
index 164fe476..4cb557f9 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.246 2015/06/25 14:00:01 roberto Exp roberto $ 2** $Id: lvm.c,v 2.247 2015/07/04 16:31:03 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*/
@@ -153,30 +153,28 @@ static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
153 153
154 154
155/* 155/*
156** Main function for table access (invoking metamethods if needed). 156** Complete a table access: if 't' is a table, 'tm' has its metamethod;
157** Compute 'val = t[key]' 157** otherwise, 'tm' is NULL.
158*/ 158*/
159void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { 159void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
160 const TValue *tm) {
160 int loop; /* counter to avoid infinite loops */ 161 int loop; /* counter to avoid infinite loops */
162 lua_assert(tm != NULL || !ttistable(t));
161 for (loop = 0; loop < MAXTAGLOOP; loop++) { 163 for (loop = 0; loop < MAXTAGLOOP; loop++) {
162 const TValue *tm; 164 if (tm == NULL) { /* no metamethod (from a table)? */
163 if (ttistable(t)) { /* 't' is a table? */ 165 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
164 Table *h = hvalue(t); 166 luaG_typeerror(L, t, "index"); /* no metamethod */
165 const TValue *res = luaH_get(h, key); /* do a primitive get */
166 if (!ttisnil(res) || /* result is not nil? */
167 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
168 setobj2s(L, val, res); /* result is the raw get */
169 return;
170 }
171 /* else will try metamethod */
172 } 167 }
173 else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
174 luaG_typeerror(L, t, "index"); /* no metamethod */
175 if (ttisfunction(tm)) { /* metamethod is a function */ 168 if (ttisfunction(tm)) { /* metamethod is a function */
176 luaT_callTM(L, tm, t, key, val, 1); 169 luaT_callTM(L, tm, t, key, val, 1); /* call it */
177 return; 170 return;
178 } 171 }
179 t = tm; /* else repeat access over 'tm' */ 172 t = tm; /* else repeat access over 'tm' */
173 if (luaV_fastget(L,t,key,tm,luaH_get)) { /* try fast track */
174 setobj2s(L, val, tm); /* done */
175 return;
176 }
177 /* else repeat */
180 } 178 }
181 luaG_runerror(L, "gettable chain too long; possible loop"); 179 luaG_runerror(L, "gettable chain too long; possible loop");
182} 180}