@Steppers I still couldn’t get your code to output anything. The variable D, which is a table has a size of 0. I added some code so I could use some info from it. In the function undump(bin) I create a table of the format codes. I do a hex dump of the bytecode file and if you triple tap the screen, I use the format code table I created from your code to format the bytecode information. I’m still looking for a 5.4 file format that explains what each byte or group of byte represent.
viewer.mode=FULLSCREEN
function setup()
fill(255)
showHexDump=true
tab={1}
dx,dy=0,0
textMode(LEFT)
font("Courier-Oblique")
bytecode = string.dump(function(n)
a=1
b=2
c=3
d=a+b+c
for z=a,b do
print(z)
end
return n*2 end)
local usableDump = undump(bytecode)
end
function draw()
background(0)
if showHexDump then
hexDump(bytecode,1,#bytecode)
else
dumpTab()
end
end
local undumpFunction -- forward declaration
local function undumpByte(D)
return D:undump("B")
end
local function undumpInteger(D)
return D:undump("j")
end
local function undumpNumber(D)
return D:undump("n")
end
local function undumpLiteral(D, len)
return D:undump("c" .. len)
end
local function undumpSize(D)
local v = 0
repeat
local b = D:undump("B")
v = (v << 7) | (b & 0x7F)
until (b & 0x80) > 0
return v
end
local undumpInt = undumpSize
local function undumpString(D)
local len = undumpSize(D)
if len == 0 then
return ""
else
return undumpLiteral(D, len-1)
end
end
local function undumpCode(D)
local size = undumpInt(D)
local code = {}
for i=1,size do
code[i] = D:undump("I4")
end
return code
end
local function undumpConstants(D)
local size = undumpInt(D)
local constants = {}
for i=1,size do
local t = undumpByte(D)
local switch = {
[0x00] = function() -- nil
return nil
end,
[0x01] = function() -- false
return false
end,
[0x11] = function() -- true
return true
end,
[0x03] = function() -- int
return undumpInteger(D)
end,
[0x13] = function() -- float
return undumpNumber(D)
end,
[0x04] = function() -- short string
return undumpString(D)
end,
[0x14] = function() -- long string
return undumpString(D)
end
}
constants[i] = switch[t]()
end
return constants
end
local function undumpProtos(D)
local size = undumpInt(D)
local protos = {}
for i=1,size do
protos[i] = undumpFunction(D)
end
return protos
end
local function undumpUpvalues(D)
local size = undumpInt(D)
local upvalues = {}
for i=1,size do
upvalues[i] = {
instack = undumpByte(D),
idx = undumpByte(D),
kind = undumpByte(D)
}
end
return upvalues
end
local function undumpDebug(D, f)
local sizelineinfo = undumpInt(D)
if sizelineinfo == 0 then
f.lineinfo = ""
else
f.lineinfo = undumpLiteral(D, sizelineinfo)
end
local sizeabslineinfo = undumpInt(D)
f.abslineinfo = {}
for i=1,sizeabslineinfo do
f.abslineinfo[i] = {
["pc"] = undumpInt(D),
["line"] = undumpInt(D)
}
end
local sizelocvars = undumpInt(D)
f.locvars = {}
for i=1,sizelocvars do
f.locvars[i] = {
varname = undumpString(D),
startpc = undumpInt(D),
endpc = undumpInt(D)
}
end
local sizeupvalues = undumpInt(D)
for i=1,sizeupvalues do
f.upvalues[i].name = undumpString(D)
end
end
undumpFunction = function(D)
local f = {}
f.source = undumpString(D)
f.linedefined = undumpInt(D)
f.lastlinedefined = undumpInt(D)
f.numparams = undumpByte(D)
f.is_vararg = undumpByte(D)
f.maxstacksize = undumpByte(D)
f.code = undumpCode(D)
f.constants = undumpConstants(D)
f.upvalues = undumpUpvalues(D)
f.protos = undumpProtos(D)
undumpDebug(D, f)
return f
end
local function undumpHeader(D)
assert(undumpLiteral(D, 4) == "\x1bLua") -- signature
assert(undumpByte(D) == 0x54) -- version
assert(undumpByte(D) == 0x00) -- official?
assert(undumpLiteral(D, 6) == "\x19\x93\r\n\x1a\n") -- random data?
assert(undumpByte(D) == 4) -- instruction size
assert(undumpByte(D) == 8) -- integer size
assert(undumpByte(D) == 8) -- float size
assert(undumpInteger(D) == 0x5678) -- integer value
assert(undumpNumber(D) == 370.5) -- float value
end
-- Undumps a binary code blob to a useful structure
function undump(bin)
local D = {
i = 0,
undump = function(self, fmt)
local v, i = string.unpack(fmt, bin, self.i)
self.i = i
table.insert(tab,i) -- added table for format values
return v
end
}
undumpHeader(D)
undumpByte(D) -- numupvalues
return undumpFunction(D)
end
function hexDump(str,st,en)
fill(255)
local x,y,v=0,1,0
for z=st,en do
x=x+1
if x>10 then
x=1
y=y+1
end
v=str:byte(z,z)
if v>31 and v<127 then
text(string.format("%02x-%s ",v,str:sub(z,z)),100+x*50,HEIGHT-20*y)
else
text(string.format("%02x-",v),100+x*50,HEIGHT-20*y)
end
end
end
function dumpTab()
local y=2,s,e,v1
for z=1,#tab-1 do
s=tab[z]
e=tab[z+1]
str=""
y=y+1
text(string.format("%3d - %-3d",s,e-1),50+dx,HEIGHT-20*y+dy)
for a=s,e-1 do
v1=bytecode:byte(a,a)
if v1>31 and v1<127 then
str=str..string.format("%02x-%s ",v1,bytecode:sub(a,a))
else
str=str..string.format("%02x ",v1)
end
end
text(string.format("%s",str),180+dx,HEIGHT-20*y+dy)
end
end
function touched(t)
if t.state==BEGAN and t.tapCount==3 then
showHexDump=not showHexDump
end
if t.state==CHANGED then
dx=dx+t.deltaX
if dx>5 then
dx=5
end
dy=dy+t.deltaY
if dy<0 then
dy=0
end
end
end