[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Weird behavior with metatables (bug?)
- From: Mike Pall <mikelu-1108@...>
- Date: Tue, 9 Aug 2011 15:28:47 +0200
Cuero Bugot wrote:
> While playing around I found a weird behavior with metatables. I
> did not find notes about it in the manual so I guess this is a bug.
>
> meta={}
> setmetatable(meta, meta)
> meta.__newindex=function(t, key, value) print("set", t, key, value) end
> proxy = setmetatable({}, meta)
>
> Then if you type:
> proxy.test = 42
> it does not call the metamethod __newindex().
>
> I tested it against official Lua 5.1.4 release and against 5.1.4 +
> all official patches, it has the same behavior.
Yes, this is a bug in Lua 5.1 and 5.2 in luaV_settable. The order
of the metamethod caching and table operations is wrong if a table
is its own metatable:
- luaH_set() invalidates the metamethod cache of the table.
- luaH_set() sets a key for __newindex, but with a nil value.
- fasttm() goes to luaT_gettm since there's a metatable, but the
cache is invalidated.
- luaT_gettm() looks up the __newindex key, but finds a nil value.
- luaT_gettm() sets the cache bit indicating 'no __newindex'.
- luaV_settable() sets the value for the __newindex key.
End result: there's a __newindex metamethod, but the metamethod
cache indicates there's none. Subsequent stores won't call the
metamethod.
[Note that LuaJIT 2.0 doesn't have that bug. And it doesn't create
unused keys in proxy tables, too.]
--Mike