diff options
| author | Mike Pall <mike> | 2011-04-10 21:41:58 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-04-10 21:41:58 +0200 |
| commit | a1f66abe4ef8ddcf07e207c77b1ae55ebac81f7e (patch) | |
| tree | c1ec86c4353e679c3ac1dcfb01f76ad9953db1fa | |
| parent | efcaef22bd5e7dc54c87e8f1a23b514fbda97d29 (diff) | |
| download | luajit-a1f66abe4ef8ddcf07e207c77b1ae55ebac81f7e.tar.gz luajit-a1f66abe4ef8ddcf07e207c77b1ae55ebac81f7e.tar.bz2 luajit-a1f66abe4ef8ddcf07e207c77b1ae55ebac81f7e.zip | |
Avoid phantom stores to proxy tables.
| -rw-r--r-- | src/lj_meta.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/lj_meta.c b/src/lj_meta.c index 22301db7..cd6fa8d3 100644 --- a/src/lj_meta.c +++ b/src/lj_meta.c | |||
| @@ -101,7 +101,7 @@ cTValue *lj_meta_tget(lua_State *L, cTValue *o, cTValue *k) | |||
| 101 | int loop; | 101 | int loop; |
| 102 | for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) { | 102 | for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) { |
| 103 | cTValue *mo; | 103 | cTValue *mo; |
| 104 | if (tvistab(o)) { | 104 | if (LJ_LIKELY(tvistab(o))) { |
| 105 | GCtab *t = tabV(o); | 105 | GCtab *t = tabV(o); |
| 106 | cTValue *tv = lj_tab_get(L, t, k); | 106 | cTValue *tv = lj_tab_get(L, t, k); |
| 107 | if (!tvisnil(tv) || | 107 | if (!tvisnil(tv) || |
| @@ -128,13 +128,22 @@ TValue *lj_meta_tset(lua_State *L, cTValue *o, cTValue *k) | |||
| 128 | int loop; | 128 | int loop; |
| 129 | for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) { | 129 | for (loop = 0; loop < LJ_MAX_IDXCHAIN; loop++) { |
| 130 | cTValue *mo; | 130 | cTValue *mo; |
| 131 | if (tvistab(o)) { | 131 | if (LJ_LIKELY(tvistab(o))) { |
| 132 | GCtab *t = tabV(o); | 132 | GCtab *t = tabV(o); |
| 133 | TValue *tv = lj_tab_set(L, t, k); | 133 | cTValue *tv = lj_tab_get(L, t, k); |
| 134 | if (!tvisnil(tv) || | 134 | if (LJ_LIKELY(!tvisnil(tv))) { |
| 135 | !(mo = lj_meta_fast(L, tabref(t->metatable), MM_newindex))) { | 135 | t->nomm = 0; /* Invalidate negative metamethod cache. */ |
| 136 | lj_gc_anybarriert(L, t); | 136 | lj_gc_anybarriert(L, t); |
| 137 | return tv; | 137 | return (TValue *)tv; |
| 138 | } else if (!(mo = lj_meta_fast(L, tabref(t->metatable), MM_newindex))) { | ||
| 139 | t->nomm = 0; /* Invalidate negative metamethod cache. */ | ||
| 140 | lj_gc_anybarriert(L, t); | ||
| 141 | if (tv != niltv(L)) | ||
| 142 | return (TValue *)tv; | ||
| 143 | if (tvisnil(k)) lj_err_msg(L, LJ_ERR_NILIDX); | ||
| 144 | else if (tvisint(k)) { setnumV(&tmp, (lua_Number)intV(k)); k = &tmp; } | ||
| 145 | else if (tvisnum(k) && tvisnan(k)) lj_err_msg(L, LJ_ERR_NANIDX); | ||
| 146 | return lj_tab_newkey(L, t, k); | ||
| 138 | } | 147 | } |
| 139 | } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_newindex))) { | 148 | } else if (tvisnil(mo = lj_meta_lookup(L, o, MM_newindex))) { |
| 140 | lj_err_optype(L, o, LJ_ERR_OPINDEX); | 149 | lj_err_optype(L, o, LJ_ERR_OPINDEX); |
