debug/minichunkspy.lua

Mon, 27 Jul 2009 03:32:13 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Mon, 27 Jul 2009 03:32:13 +0100
changeset 34
0e34461ab2a6
permissions
-rw-r--r--

Add new debug extension

34
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 -- Minichunkspy: Disassemble and reassemble chunks.
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 -- Copyright M Joonas Pihlaja 2009
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 -- MIT license
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 --
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 -- minichunkspy = require"minichunkspy"
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 --
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 -- chunk = string.dump(loadfile"blabla.lua")
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 -- disassembled_chunk = minichunkspy.disassemble(chunk)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 -- chunk = minichunkspy.assemble(disassembled_chunk)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 -- assert(minichunkspy.validate(<function or chunk>))
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 --
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 -- Tested on little-endian 32 bit platforms. Modify
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 -- the Size_t type to be a 64 bit integer to make it work
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 -- for 64 bit systems, and set BIG_ENDIAN = true for
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 -- big-endian systems.
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 local string, table, math = string, table, math
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 local ipairs, setmetatable, type, assert = ipairs, setmetatable, type, assert
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 local _ = __END_OF_GLOBALS__
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 local string_char, string_byte, string_sub = string.char, string.byte, string.sub
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 local table_concat = table.concat
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 local math_abs, math_ldexp, math_frexp = math.abs, math.ldexp, math.frexp
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 local Inf = math.huge
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 local Nan = Inf - Inf
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 local BIG_ENDIAN = false --twiddle this for your platform.
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 local function construct (class, ...)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 return class.new(class, ...)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 local mt_memo = {}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 local Field = construct{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 new =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 function (class, self)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 local self = self or {}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 local mt = mt_memo[class] or {
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 __index = class,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 __call = construct
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 mt_memo[class] = mt
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 return setmetatable(self, mt)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 local None = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 unpack = function (self, bytes, ix) return nil, ix end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 pack = function (self, val) return "" end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 local char_memo = {}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 local function char(n)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 local field = char_memo[n] or Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 unpack = function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 return string_sub(bytes, ix, ix+n-1), ix+n
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 pack = function (self, val) return string_sub(val, 1, n) end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 char_memo[n] = field
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 return field
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 local uint8 = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 unpack = function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 return string_byte(bytes, ix, ix), ix+1
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 pack = function (self, val) return string_char(val) end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 local uint32 = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 unpack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 local a,b,c,d = string_byte(bytes, ix, ix+3)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 if BIG_ENDIAN then a,b,c,d = d,c,b,a end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 return a + b*256 + c*256^2 + d*256^3, ix+4
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 pack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 function (self, val)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 assert(type(val) == "number",
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 "unexpected value type to pack as an uint32")
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 local a,b,c,d
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 d = val % 2^32
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 a = d % 256; d = (d - a) / 256
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 b = d % 256; d = (d - b) / 256
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 c = d % 256; d = (d - c) / 256
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 if BIG_ENDIAN then a,b,c,d = d,c,b,a end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 return string_char(a,b,c,d)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 local int32 = uint32{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 unpack = function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 local val, ix = uint32:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 return val < 2^32 and val or (val - 2^31), ix
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 local Byte = uint8
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 local Size_t = uint32
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 local Integer = int32
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 -- Opaque types:
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 local Number = char(8)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 local Insn = char(4)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 local Struct = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 unpack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 local val = {}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 local i,j = 1,1
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 while self[i] do
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 local field = self[i]
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 local key = field.name
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 if not key then key, j = j, j+1 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 --print("unpacking struct field", key, " at index ", ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 val[key], ix = field:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 i = i+1
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 return val, ix
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 pack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 function (self, val)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 local data = {}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 local i,j = 1,1
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 while self[i] do
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 local field = self[i]
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 local key = field.name
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 if not key then key, j = j, j+1 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 data[i] = field:pack(val[key])
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 i = i+1
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 return table_concat(data)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 local List = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 unpack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 local len, ix = Integer:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 local vals = {}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 local field = self.type
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 for i=1,len do
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 --print("unpacking list field", i, " at index ", ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 vals[i], ix = field:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 return vals, ix
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 pack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 function (self, vals)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 local len = #vals
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 local data = { Integer:pack(len) }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 local field = self.type
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 for i=1,len do
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 data[#data+1] = field:pack(vals[i])
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 return table_concat(data)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 local Boolean = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 unpack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 local val, ix = Integer:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 assert(val == 0 or val == 1,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 "unpacked an unexpected value "..val.." for a Boolean")
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 return val == 1, ix
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 pack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 function (self, val)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 assert(type(val) == "boolean",
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 "unexpected value type to pack as a Boolean")
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 return Integer:pack(val and 1 or 0)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 local String = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 unpack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 local len, ix = Integer:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 local val = nil
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 if len > 0 then
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 -- len includes trailing nul byte; ignore it
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 local string_len = len - 1
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 val = bytes:sub(ix, ix+string_len-1)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 return val, ix + len
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 pack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 function (self, val)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 assert(type(val) == "nil" or type(val) == "string",
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192 "unexpected value type to pack as a String")
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 if val == nil then
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 return Integer:pack(0)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 return Integer:pack(#val+1) .. val .. "\000"
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 local ChunkHeader = Struct{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 char(4){name = "signature"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 Byte{name = "version"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 Byte{name = "format"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 Byte{name = "endianness"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 Byte{name = "sizeof_int"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 Byte{name = "sizeof_size_t"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 Byte{name = "sizeof_insn"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 Byte{name = "sizeof_Number"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 Byte{name = "integral_flag"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 local ConstantTypes = {
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213 [0] = None,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 [1] = Boolean,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 [3] = Number,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 [4] = String,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 local Constant = Field{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 unpack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220 function (self, bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 local t, ix = Byte:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 local field = ConstantTypes[t]
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
223 assert(field, "unknown constant type "..t.." to unpack")
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
224 local v, ix = field:unpack(bytes, ix)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225 return {
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226 type = t,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227 value = v
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
228 }, ix
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
229 end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
230 pack =
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
231 function (self, val)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
232 local t, v = val.type, val.value
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
233 return Byte:pack(t) .. ConstantTypes[t]:pack(v)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
234 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
235 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 local Local = Struct{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
238 String{name = "name"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
239 Integer{name = "startpc"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
240 Integer{name = "endpc"}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
241 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
242
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
243 local Function = Struct{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
244 String{name = "name"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
245 Integer{name = "line"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
246 Integer{name = "last_line"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
247 Byte{name = "num_upvalues"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
248 Byte{name = "num_parameters"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
249 Byte{name = "is_vararg"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
250 Byte{name = "max_stack_size"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
251 List{name = "insns", type = Insn},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
252 List{name = "constants", type = Constant},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
253 List{name = "prototypes", type = nil}, --patch type below
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
254 List{name = "source_lines", type = Integer},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
255 List{name = "locals", type = Local},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
256 List{name = "upvalues", type = String},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
257 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
258 assert(Function[10].name == "prototypes",
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
259 "missed the function prototype list")
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
260 Function[10].type = Function
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
261
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
262 local Chunk = Struct{
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
263 ChunkHeader{name = "header"},
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
264 Function{name = "body"}
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
265 }
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
266
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
267 local function validate(chunk)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
268 if type(chunk) == "function" then
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
269 return validate(string.dump(chunk))
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
270 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
271 local f = Chunk:unpack(chunk, 1)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
272 local chunk2 = Chunk:pack(f)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
273
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
274 if chunk == chunk2 then return true end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
275
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
276 local i
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
277 local len = math.min(#chunk, #chunk2)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
278 for i=1,len do
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
279 local a = chunk:sub(i,i)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
280 local b = chunk:sub(i,i)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
281 if a ~= b then
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
282 return false, ("chunk roundtripping failed: "..
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
283 "first byte difference at index %d"):format(i)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
284 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
285 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
286 return false, ("chunk round tripping failed: "..
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
287 "original length %d vs. %d"):format(#chunk, #chunk2)
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
288 end
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
289
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
290 return {
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
291 disassemble = function (chunk) return Chunk:unpack(chunk, 1) end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
292 assemble = function (disassembled) return Chunk:pack(disassembled) end,
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
293 validate = validate
0e34461ab2a6 Add new debug extension
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
294 }

mercurial