Add ability to serialize metatables

This commit is contained in:
Jasmijn Wellner 2020-12-26 14:22:57 +01:00
parent d30f0c7aca
commit 02476589e3
4 changed files with 23 additions and 3 deletions

View File

@ -188,15 +188,18 @@ end
local function write_table(value, seen) local function write_table(value, seen)
local classkey local classkey
local metatable = getmetatable(value)
local classname = (class_name_registry[value.class] -- MiddleClass local classname = (class_name_registry[value.class] -- MiddleClass
or class_name_registry[value.__baseclass] -- SECL or class_name_registry[value.__baseclass] -- SECL
or class_name_registry[getmetatable(value)] -- hump.class or class_name_registry[metatable] -- hump.class
or class_name_registry[value.__class__] -- Slither or class_name_registry[value.__class__] -- Slither
or class_name_registry[value.__class]) -- Moonscript class or class_name_registry[value.__class]) -- Moonscript class
if classname then if classname then
classkey = classkey_registry[classname] classkey = classkey_registry[classname]
Buffer_write_byte(242) Buffer_write_byte(242)
serialize_value(classname, seen) serialize_value(classname, seen)
elseif metatable then
Buffer_write_byte(253)
else else
Buffer_write_byte(240) Buffer_write_byte(240)
end end
@ -218,6 +221,9 @@ local function write_table(value, seen)
serialize_value(v, seen) serialize_value(v, seen)
end end
end end
if metatable then
serialize_value(metatable, seen)
end
end end
local function write_cdata(value, seen) local function write_cdata(value, seen)
@ -304,7 +310,7 @@ local function deserialize_value(seen)
elseif t < 240 then elseif t < 240 then
--small resource --small resource
return add_to_seen(resource_registry[Buffer_read_string(t - 224)], seen) return add_to_seen(resource_registry[Buffer_read_string(t - 224)], seen)
elseif t == 240 then elseif t == 240 or t == 253 then
--table --table
local v = add_to_seen({}, seen) local v = add_to_seen({}, seen)
local len = deserialize_value(seen) local len = deserialize_value(seen)
@ -316,6 +322,9 @@ local function deserialize_value(seen)
local key = deserialize_value(seen) local key = deserialize_value(seen)
v[key] = deserialize_value(seen) v[key] = deserialize_value(seen)
end end
if t == 253 then
setmetatable(v, deserialize_value(seen))
end
return v return v
elseif t == 241 then elseif t == 241 then
--long resource --long resource

5
cases/metatable.lua Normal file
View File

@ -0,0 +1,5 @@
-- test metatables
local metatable = {__mode = 'k', foo={1,2,3,4,5,6,7,8,10,11,12}}
metatable.__index = metatable
return setmetatable({test=true}, metatable), 10000, 3

View File

@ -192,4 +192,4 @@ function love.draw()
love.graphics.print(results_max, 780 - love.graphics.getFont():getWidth(results_max), i * 20) love.graphics.print(results_max, 780 - love.graphics.getFont():getWidth(results_max), i * 20)
love.graphics.print(resultname .." (smaller is better; try left, right, R, escape)", 100, i * 20 + 20) love.graphics.print(resultname .." (smaller is better; try left, right, R, escape)", 100, i * 20 + 20)
end end
end end

View File

@ -335,4 +335,10 @@ describe("bitser", function()
it("can read and write simple multiple cdata of the same ctype without getting confused", function() it("can read and write simple multiple cdata of the same ctype without getting confused", function()
test_serdeser({ffi.new('double', 42.5), ffi.new('double', 12), ffi.new('double', 0.01)}) test_serdeser({ffi.new('double', 42.5), ffi.new('double', 12), ffi.new('double', 0.01)})
end) end)
it("can read and write metatables", function()
local t = setmetatable({foo="foo"}, {__index = {bar="bar"}})
test_serdeser(t)
assert.are.same(getmetatable(t), getmetatable(serdeser(t)))
assert.are.same(serdeser(t).bar, "bar")
end)
end) end)