]> git.lizzy.rs Git - minetest.git/commitdiff
Serialize: Use numbers for refs to work around LuaJIT limits
authorLars Mueller <appgurulars@gmx.de>
Wed, 17 Aug 2022 09:35:26 +0000 (11:35 +0200)
committerSmallJoker <mk939@ymail.com>
Sun, 11 Sep 2022 17:27:02 +0000 (19:27 +0200)
builtin/common/serialize.lua

index caf989e69fd30218a17924fefe8def06e469d549..06eb181e07858d1a27bf63f10ce6450373ca548c 100644 (file)
@@ -61,17 +61,18 @@ end
 -- Serializes Lua nil, booleans, numbers, strings, tables and even functions
 -- Tables are referenced by reference, strings are referenced by value. Supports circular tables.
 local function serialize(value, write)
-       local reference, refnum = "r1", 1
-       -- [object] = reference string
+       local reference, refnum = "1", 1
+       -- [object] = reference
        local references = {}
        -- Circular tables that must be filled using `table[key] = value` statements
        local to_fill = {}
        for object, count in pairs(count_objects(value)) do
                local type_ = type(object)
                -- Object must appear more than once. If it is a string, the reference has to be shorter than the string.
-               if count >= 2 and (type_ ~= "string" or #reference + 2 < #object) then
+               if count >= 2 and (type_ ~= "string" or #reference + 5 < #object) then
+                       write"_["
                        write(reference)
-                       write("=")
+                       write("]=")
                        if type_ == "table" then
                                write("{}")
                        elseif type_ == "function" then
@@ -85,7 +86,7 @@ local function serialize(value, write)
                                to_fill[object] = reference
                        end
                        refnum = refnum + 1
-                       reference = ("r%X"):format(refnum)
+                       reference = ("%d"):format(refnum)
                end
        end
        -- Used to decide whether we should do "key=..."
@@ -110,7 +111,9 @@ local function serialize(value, write)
                -- Reference types: table, function and string
                local ref = references[value]
                if ref then
-                       return write(ref)
+                       write"_["
+                       write(ref)
+                       return write"]"
                end
                if type_ == "string" then
                        return write(quote(value))
@@ -156,7 +159,9 @@ local function serialize(value, write)
        -- Write the statements to fill circular tables
        for table, ref in pairs(to_fill) do
                for k, v in pairs(table) do
+                       write("_[")
                        write(ref)
+                       write("]")
                        if use_short_key(k) then
                                write(".")
                                write(k)
@@ -202,7 +207,7 @@ function core.deserialize(str, safe)
        if not func then return nil, err end
 
        -- math.huge is serialized to inf, NaNs are serialized to nan by Lua
-       local env = {inf = math_huge, nan = nan}
+       local env = {inf = math_huge, nan = nan, _ = {}}
        if safe then
                env.loadstring = dummy_func
        else