Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

What is LASM's Floating Point Format?

Asked by 6 years ago

Hello fellow Robloxians!

Perhaps you can help me with a problem. Right now I'm working on Byte Spy v3 (you can check out v2 here: https://www.roblox.com/library/127231254/Byte-Spy-v2-0) which is much simpler and more efficient. I also plan on adding some new features. For those of you who do not know, it is a LASM (Lua assembly language, the Lua virtual machine language, output of string.dump) disassembler.

Right now I'm running into a problem adding double precision floating point to string converter into it. v2 didn't include it, so I can't just look at how I did it before. To test the functionality I've parsed a dump of the main parser function which has two numbers in it, 1 and 4, which are represented as floating points in the dump. Here is what they are:

0x 00 00 00 00 00 00 F0 3F
0x 00 00 00 00 00 00 10 40

I'm not sure which is 1 and which is 4, but I assume the bottom number is 1 since its raw value is smaller. Looking on Wikipedia (the source of all truth, despite what your English teacher said) at https://en.wikipedia.org/wiki/Double-precision_floating-point_format a 1 should look like:

0 01111111111 0000000000000000000000000000000000000000000000000000

Why does the 1 presented by dump and the 1 presented by Wikipedia differ? Is Roblox using a different floating point format than IEE 754?

For those that want it, here is the code (note, it is in a module, and starts at line 84):

return function(func)
    func = string.dump(func)
    func = setmetatable({func:byte(1, func:len())}, dump)
    func.header = {
        {name = "Header signiture",         value = string.char(func:nextBytes(4))};
        {name = "Version number",       value = func:nextNumber(1)};
        {name = "Format Version",       value = func:nextNumber(1)};
        {name = "Endianness flag",      value = func:nextNumber(1)};
        {name = "Size of int",          value = func:nextNumber(1)};
        {name = "Size of size_t",       value = func:nextNumber(1)};
        {name = "Size of Instruction",  value = func:nextNumber(1)};
        {name = "Size of lua_Number",   value = func:nextNumber(1)};
        {name = "Integral flag",        value = func:nextNumber(1)};
    }
    return {
        {name = "Header",           value = func.header};
        {name = "Main Function",    value = func:nextChunk()};
    }
end

And the output of Byte Spy v3:


[Header] = { [Header signiture] = Lua [Version number] = 81 [Format Version] = 0 [Endianness flag] = 1 [Size of int] = 4 [Size of size_t] = 4 [Size of Instruction] = 4 [Size of lua_Number] = 8 [Integral flag] = 0 } [Main Function] = { [Source Name] = "=Workspace.Parser" [Line first defined] = 83 [Line last defined] = 101 [Number of upvalues] = 1 [Number of parameters] = 1 [Number of is_vararg flag] = 0 [Maximum stack size] = 14 [Instructions] = { [0] = GETGLOBAL, 1, 0 [1] = GETTABLE, 1, 1, 257 [2] = MOVE, 2, 0 [3] = CALL, 1, 2, 2 [4] = MOVE, 0, 1 [5] = GETGLOBAL, 1, 2 [6] = NEWTABLE, 2, 0, 0 [7] = SELF, 3, 0, 259 [8] = LOADK, 5, 4 [9] = SELF, 6, 0, 261 [10] = CALL, 6, 2, 0 [11] = CALL, 3, 0, 0 [12] = SETLIST, 2, 0, 1 [13] = GETUPVAL, 3, 0 [14] = CALL, 1, 3, 2 [15] = MOVE, 0, 1 [16] = NEWTABLE, 1, 9, 0 [17] = NEWTABLE, 2, 0, 2 [18] = SETTABLE, 2, 263, 264 [19] = GETGLOBAL, 3, 0 [20] = GETTABLE, 3, 3, 266 [21] = SELF, 4, 0, 267 [22] = LOADK, 6, 12 [23] = CALL, 4, 3, 0 [24] = CALL, 3, 0, 2 [25] = SETTABLE, 2, 265, 3 [26] = NEWTABLE, 3, 0, 2 [27] = SETTABLE, 3, 263, 269 [28] = SELF, 4, 0, 270 [29] = LOADK, 6, 4 [30] = CALL, 4, 3, 2 [31] = SETTABLE, 3, 265, 4 [32] = NEWTABLE, 4, 0, 2 [33] = SETTABLE, 4, 263, 271 [34] = SELF, 5, 0, 270 [35] = LOADK, 7, 4 [36] = CALL, 5, 3, 2 [37] = SETTABLE, 4, 265, 5 [38] = NEWTABLE, 5, 0, 2 [39] = SETTABLE, 5, 263, 272 [40] = SELF, 6, 0, 270 [41] = LOADK, 8, 4 [42] = CALL, 6, 3, 2 [43] = SETTABLE, 5, 265, 6 [44] = NEWTABLE, 6, 0, 2 [45] = SETTABLE, 6, 263, 273 [46] = SELF, 7, 0, 270 [47] = LOADK, 9, 4 [48] = CALL, 7, 3, 2 [49] = SETTABLE, 6, 265, 7 [50] = NEWTABLE, 7, 0, 2 [51] = SETTABLE, 7, 263, 274 [52] = SELF, 8, 0, 270 [53] = LOADK, 10, 4 [54] = CALL, 8, 3, 2 [55] = SETTABLE, 7, 265, 8 [56] = NEWTABLE, 8, 0, 2 [57] = SETTABLE, 8, 263, 275 [58] = SELF, 9, 0, 270 [59] = LOADK, 11, 4 [60] = CALL, 9, 3, 2 [61] = SETTABLE, 8, 265, 9 [62] = NEWTABLE, 9, 0, 2 [63] = SETTABLE, 9, 263, 276 [64] = SELF, 10, 0, 270 [65] = LOADK, 12, 4 [66] = CALL, 10, 3, 2 [67] = SETTABLE, 9, 265, 10 [68] = NEWTABLE, 10, 0, 2 [69] = SETTABLE, 10, 263, 277 [70] = SELF, 11, 0, 270 [71] = LOADK, 13, 4 [72] = CALL, 11, 3, 2 [73] = SETTABLE, 10, 265, 11 [74] = SETLIST, 1, 9, 1 [75] = SETTABLE, 0, 262, 1 [76] = NEWTABLE, 1, 2, 0 [77] = NEWTABLE, 2, 0, 2 [78] = SETTABLE, 2, 263, 278 [79] = GETTABLE, 3, 0, 262 [80] = SETTABLE, 2, 265, 3 [81] = NEWTABLE, 3, 0, 2 [82] = SETTABLE, 3, 263, 279 [83] = SELF, 4, 0, 280 [84] = CALL, 4, 2, 2 [85] = SETTABLE, 3, 265, 4 [86] = SETLIST, 1, 2, 1 [87] = RETURN, 1, 2 [88] = RETURN, 0, 1 } [Constants] = { [0] = "string" [1] = "dump" [2] = "setmetatable" [3] = "byte" [4] = 330945 * 2^0 [5] = "len" [6] = "header" [7] = "name" [8] = "Header signiture" [9] = "value" [10] = "char" [11] = "nextBytes" [12] = 99504 * 2^0 [13] = "Version number" [14] = "nextNumber" [15] = "Format Version" [16] = "Endianness flag" [17] = "Size of int" [18] = "Size of size_t" [19] = "Size of Instruction" [20] = "Size of lua_Number" [21] = "Integral flag" [22] = "Header" [23] = "Main Function" [24] = "nextChunk" } [Prototypes] = { } [Source Line Positions] = { [0] = 84 [1] = 84 [2] = 84 [3] = 84 [4] = 84 [5] = 85 [6] = 85 [7] = 85 [8] = 85 [9] = 85 [10] = 85 [11] = 85 [12] = 85 [13] = 85 [14] = 85 [15] = 85 [16] = 86 [17] = 86 [18] = 87 [19] = 87 [20] = 87 [21] = 87 [22] = 87 [23] = 87 [24] = 87 [25] = 87 [26] = 87 [27] = 88 [28] = 88 [29] = 88 [30] = 88 [31] = 88 [32] = 88 [33] = 89 [34] = 89 [35] = 89 [36] = 89 [37] = 89 [38] = 89 [39] = 90 [40] = 90 [41] = 90 [42] = 90 [43] = 90 [44] = 90 [45] = 91 [46] = 91 [47] = 91 [48] = 91 [49] = 91 [50] = 91 [51] = 92 [52] = 92 [53] = 92 [54] = 92 [55] = 92 [56] = 92 [57] = 93 [58] = 93 [59] = 93 [60] = 93 [61] = 93 [62] = 93 [63] = 94 [64] = 94 [65] = 94 [66] = 94 [67] = 94 [68] = 94 [69] = 95 [70] = 95 [71] = 95 [72] = 95 [73] = 95 [74] = 96 [75] = 96 [76] = 97 [77] = 97 [78] = 98 [79] = 98 [80] = 98 [81] = 98 [82] = 99 [83] = 99 [84] = 99 [85] = 99 [86] = 100 [87] = 100 [88] = 101 } [Locals] = { [0] = "func" } [Upvalues] = { [0] = "dump" } }
0
Have you considered that you're parsing the dump wrong? 2eggnog 981 — 6y

Answer this question