diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-07-20 15:24:50 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-07-20 15:24:50 -0300 |
commit | e247c3ada3ff47a1352927e797263137f4e02e0e (patch) | |
tree | 4d2563f59472bdee4c4f58dd87cb1d8eeaf2c1b3 /lvm.c | |
parent | b5dc2f9b0c57fef5f72152973938ff5265366dcd (diff) | |
download | lua-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.c | 32 |
1 files changed, 15 insertions, 17 deletions
@@ -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 | */ |
159 | void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | 159 | void 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 | } |