Skip to content

Small references to long resources become garbled when multiple fields reference the same function(s) #39

@Krunklehorn

Description

@Krunklehorn

Bit of a heisenbug here. The results are non-deterministic in my project, but for this example, creating a list of five different functions ordered first-to-last-to-first gives consistent results.

local bitser = require "modules.bitser"

local function FOO() end
local function BAR() end
local function GEE() end
local function CAR() end
local function YAG() end

local funcName = {
    [FOO] = "FOO()",
    [BAR] = "BAR()",
    [GEE] = "GEE()",
    [CAR] = "CAR()",
    [YAG] = "YAG()"
}

bitser.register("long.resource.name.FOO", FOO)
bitser.register("long.resource.name.BAR", BAR)
bitser.register("long.resource.name.GEE", GEE)
bitser.register("long.resource.name.CAR", CAR)
bitser.register("long.resource.name.YAG", YAG)
        
local data_before = {
    FOO, BAR, GEE, CAR, YAG, CAR, GEE, BAR, FOO
}

local dump = bitser.dumps(data_before)
local data_after = bitser.loads(dump)

print("Result...")
for i, v in ipairs(data_before) do
    print(i, "Before:", funcName[v], v, "After:", funcName[data_after[i]], data_after[i]) end

Output:

Result...
1       Before: FOO()   function: 0x02a815d295c0        After:  FOO()   function: 0x02a815d295c0
2       Before: BAR()   function: 0x02a815d2e418        After:  BAR()   function: 0x02a815d2e418
3       Before: GEE()   function: 0x02a815d2e448        After:  GEE()   function: 0x02a815d2e448
4       Before: CAR()   function: 0x02a815d2e478        After:  CAR()   function: 0x02a815d2e478
5       Before: YAG()   function: 0x02a815d2e4a8        After:  YAG()   function: 0x02a815d2e4a8
6       Before: CAR()   function: 0x02a815d2e478        After:  GEE()   function: 0x02a815d2e448
7       Before: GEE()   function: 0x02a815d2e448        After:  nil     long.resource.name.BAR
8       Before: BAR()   function: 0x02a815d2e418        After:  BAR()   function: 0x02a815d2e418
9       Before: FOO()   function: 0x02a815d295c0        After:  nil     long.resource.name.FOO

Below is a basic log of the deserialize function, showing the relevant operations and contents of the 'seen' table...

bitser.deserialize()...
241     long resource           2       long.resource.name.FOO  function: 0x02a815d295c0
241     long resource           4       long.resource.name.BAR  function: 0x02a815d2e418
241     long resource           6       long.resource.name.GEE  function: 0x02a815d2e448
241     long resource           8       long.resource.name.CAR  function: 0x02a815d2e478
241     long resource           10      long.resource.name.YAG  function: 0x02a815d2e4a8
132     small reference         6       function: 0x02a815d2e448
131     small reference         5       long.resource.name.BAR
130     small reference         4       function: 0x02a815d2e418
129     small reference         3       long.resource.name.FOO
1       table: 0x02a815d35580
2       function: 0x02a815d295c0
3       long.resource.name.FOO
4       function: 0x02a815d2e418
5       long.resource.name.BAR
6       function: 0x02a815d2e448
7       long.resource.name.GEE
8       function: 0x02a815d2e478
9       long.resource.name.CAR
10      function: 0x02a815d2e4a8
11      long.resource.name.YAG

From what I gather the serializer and deserializer don't seem to agree on how the small references should be recorded. In my project I noticed larger index errors for larger tables with more functions, so the error seems to be compounding.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions