This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
CoolisTheName007's profile picture

setmetatable(a,{__index=a_table}) vs getmetatable(a).__index=a_table

Started by CoolisTheName007, 22 December 2012 - 05:59 AM
CoolisTheName007 #1
Posted 22 December 2012 - 06:59 AM
Methods in the title, respectively, set a function, or a table, to the __index field of a metatable.
This is inconsistent and non-standard behavior. Plus, I traced this to the following override in bios.lua:

local nativesetmetatable = setmetatable
function setmetatable( _o, _t )
if _t and type(_t) == "table" then
  local idx = rawget( _t, "__index" )
  if idx and type( idx ) == "table" then
   rawset( _t, "__index", function( t, k ) return idx[k] end )
  end
  local newidx = rawget( _t, "__newindex" )
  if newidx and type( newidx ) == "table" then
   rawset( _t, "__newindex", function( t, k, v ) newidx[k] = v end )
  end
end
return nativesetmetatable( _o, _t )
end

Since users can bypass it by using the second method (however replacing the setmetatable version by the original has a wrapping cost), I ask why is this replacement here?
EDIT: maybe it's for changing one error to another, e.g. table->table->table… to function->function->function…. Why?
Sebra #2
Posted 22 December 2012 - 08:32 PM
First method substitute metatable, second - change it.
First method will remove previous settings, second will not work without metatable assigned already.

Meaning of this hook evades me. ;)/> Isn`t it a patch for LuaJ problem?
CoolisTheName007 #3
Posted 23 December 2012 - 12:49 AM
Meaning of this hook evades me. ;)/> Isn`t it a patch for LuaJ problem?
Will test by removing the 'patch'.
Cloudy #4
Posted 23 December 2012 - 01:36 AM
It is a patch for the future persistence. In dan's own words:



[12:33] <@dan200> hmm, it was there to fix a jna thing
[12:34] <@dan200> pluto couldnt serialise if there were cfunctions on the stack
[12:35] <@Cloudy> thought as much
[12:35] <@dan200> and setmetatable( { __index = table } ) created a cfunction internally
[12:35] <@dan200> could remove it, but it would have to come back when pluto does
CoolisTheName007 #5
Posted 23 December 2012 - 02:20 AM
snip
I see. But if the second method is still possible to execute, I suppose it doesn't affect future serialization. So a more consistent method would be:


local nativesetmetatable = setmetatable
function setmetatable( _o, _t )
if _t and type(_t) == "table" then
  local idx = rawget( _t, "__index" )
  local newidx=rawget( _t, "__newindex" )
  rawset(_t,"__index",nil)
  rawset(_t,"__newindex",nil)
  local r= nativesetmetatable( _o, _t )
  rawset(_t,"__index",idx)
  rawset(_t,"__newindex",newidx)
  local meta=getmetatable(_o)
  rawset(meta,"__index",idx)
  rawset(meta,"__newindex",newidx)
  return r
else
return nativesetmetatable( _o, _t )
end
end

I tested with a bunch of code of my scheduler (which uses a lot of oo) and got no problems.
Guess CC-emu does not let anyone edit the bios? Have to find it…
EDIT: found it, but I'm not managing to get CC-emu to run after:
-de-compressing computercraft.jar
-editing the bios.lua
-compressing to computercraft.rar and changing the extension to jar

Probably I will finally get CC into a MC install.
But, then again, this fix can be made by replacing setmetatable (in _G) by this version, which I did, and it seems to work fine. But it's an extra wrapping.
CoolisTheName007 #6
Posted 23 December 2012 - 07:51 AM
Closing this matter with a quote from IRC from dan200:
[18:49]
<dan200> CoolisTheName007: ah, it's too late to change it

[18:49] <CoolisTheName007> np
[18:50] <CoolisTheName007> but do you think it breaks serialization?

[18:50] <dan200> CoolisTheName007: i've already given 1.48 to the ftb team, and htey're getting ready to deploy it
[18:50] <CoolisTheName007> ok, np, I can wrap around it if necessary
Cloudy #7
Posted 23 December 2012 - 08:19 AM
-compressing to computercraft.rar and changing the extension to jar

You do realise jars are zips right? :P/>
CoolisTheName007 #8
Posted 23 December 2012 - 08:20 AM
snip
I shall get informed. Thank you.