Implement enough to read bytecode instructions
This commit is contained in:
parent
8beb98dd71
commit
d800d334dc
|
|
@ -2,4 +2,5 @@ local readbc = require('readbc')
|
||||||
|
|
||||||
fp = io.open('tests/test1.luo')
|
fp = io.open('tests/test1.luo')
|
||||||
header = readbc.read_header(fp)
|
header = readbc.read_header(fp)
|
||||||
print(header.name)
|
proto = readbc.read_proto(fp)
|
||||||
|
print(#proto.bcins)
|
||||||
|
|
|
||||||
97
readbc.lua
97
readbc.lua
|
|
@ -5,13 +5,53 @@ local bit=require('bit')
|
||||||
local HEADER_MAGIC = {27, string.byte('L'), string.byte('J')}
|
local HEADER_MAGIC = {27, string.byte('L'), string.byte('J')}
|
||||||
local HEADER_FLAG_STRIP = 0x02
|
local HEADER_FLAG_STRIP = 0x02
|
||||||
|
|
||||||
|
local function read_u8(fp)
|
||||||
|
return string.byte(fp:read(1))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_u16(fp)
|
||||||
|
-- TODO: endianess
|
||||||
|
local b1 = read_u8(fp)
|
||||||
|
local b2 = read_u8(fp)
|
||||||
|
|
||||||
|
return bit.bor(b2*0x100, b1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_u32(fp)
|
||||||
|
-- TODO: endianess
|
||||||
|
local h1 = read_u16(fp)
|
||||||
|
local h2 = read_u16(fp)
|
||||||
|
|
||||||
|
return bit.bor(h2*0x10000, h1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_u8n(fp, n)
|
||||||
|
return { string.byte(fp:read(n), 1, n) }
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_u16n(fp, n)
|
||||||
|
local res = {}
|
||||||
|
for i = 1, n do
|
||||||
|
res[i] = read_u16(fp)
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
local function read_u32n(fp, n)
|
||||||
|
local res = {}
|
||||||
|
for i = 1, n do
|
||||||
|
res[i] = read_u32(fp)
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
local function read_uleb128(fp)
|
local function read_uleb128(fp)
|
||||||
local last_byte = false
|
local last_byte = false
|
||||||
local res = 0
|
local res = 0
|
||||||
local shift = 0
|
local shift = 0
|
||||||
-- the bytes are read from the LSB to the MSB
|
-- the bytes are read from the LSB to the MSB
|
||||||
while not last_byte do
|
while not last_byte do
|
||||||
local uleb_byte = string.byte(fp:read(1))
|
local uleb_byte = read_u8(fp)
|
||||||
res = bit.bor(res, bit.lshift(bit.band(uleb_byte, 0x7f), shift))
|
res = bit.bor(res, bit.lshift(bit.band(uleb_byte, 0x7f), shift))
|
||||||
|
|
||||||
if bit.band(uleb_byte, 0x80) == 0 then
|
if bit.band(uleb_byte, 0x80) == 0 then
|
||||||
|
|
@ -22,8 +62,8 @@ local function read_uleb128(fp)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function read_header(fp)
|
local function read_header(fp)
|
||||||
local magic = { string.byte(fp:read(3), 1, 3) }
|
local magic = read_u8n(fp, 3)
|
||||||
local version = string.byte(fp:read(1))
|
local version = read_u8(fp)
|
||||||
local flags = read_uleb128(fp)
|
local flags = read_uleb128(fp)
|
||||||
|
|
||||||
local name
|
local name
|
||||||
|
|
@ -43,6 +83,57 @@ local function read_header(fp)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function read_proto(fp)
|
local function read_proto(fp)
|
||||||
|
local length = read_uleb128(fp)
|
||||||
|
-- if the the last read proto was the last one
|
||||||
|
-- we have reached the end marker, which is a zero
|
||||||
|
-- this overlaps with a uleb128 zero representation
|
||||||
|
if length == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- read proto header
|
||||||
|
local flags = read_u8(fp)
|
||||||
|
local numparams = read_u8(fp)
|
||||||
|
local framesize = read_u8(fp)
|
||||||
|
local numuv = read_u8(fp)
|
||||||
|
local numkgc = read_uleb128(fp)
|
||||||
|
local numkn = read_uleb128(fp)
|
||||||
|
local numbc = read_uleb128(fp)
|
||||||
|
|
||||||
|
local debugLen = 0
|
||||||
|
local debugInfo = nil
|
||||||
|
|
||||||
|
if bit.band(flags, HEADER_FLAG_STRIP) ~= 0 then
|
||||||
|
debugLen = read_uleb128(fp)
|
||||||
|
|
||||||
|
-- TODO: is this correct?
|
||||||
|
if debugLen ~= 0 then
|
||||||
|
local firstLine = read_uleb128(fp)
|
||||||
|
local numLine = read_uleb128(fp)
|
||||||
|
debugInfo = {
|
||||||
|
firstLine = firstLine,
|
||||||
|
numLine = numLine,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local bcins = read_u32n(fp, numbc)
|
||||||
|
local uvdata = read_u16n(fp, numuv)
|
||||||
|
-- local kgc
|
||||||
|
-- local numkn
|
||||||
|
|
||||||
|
return {
|
||||||
|
flags = flags,
|
||||||
|
numparams = numparams,
|
||||||
|
framsize = framesize,
|
||||||
|
numuv = numuv,
|
||||||
|
numkgc = numkgc,
|
||||||
|
numkn = numkn,
|
||||||
|
numbc = numbc,
|
||||||
|
debugInfo = debugInfo,
|
||||||
|
bcins = bcins,
|
||||||
|
uvdata = uvdata,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue