Compare commits
No commits in common. "a65b94e483767a7e6425cb747d6ca1d89215f4ff" and "8beb98dd715bf64b7c2a8a4c3f517dc7d05c568b" have entirely different histories.
a65b94e483
...
8beb98dd71
|
|
@ -1,14 +0,0 @@
|
||||||
local readbc = require('readbc')
|
|
||||||
local opcodes = require('opcodes')
|
|
||||||
|
|
||||||
fp = io.open('tests/test1.luo')
|
|
||||||
header = readbc.read_header(fp)
|
|
||||||
proto = readbc.read_proto(fp)
|
|
||||||
|
|
||||||
for i = 1, #proto.bcins do
|
|
||||||
local decoded = opcodes.decode(proto.bcins[i])
|
|
||||||
local def = opcodes.defs[decoded.id]
|
|
||||||
print(def.name)
|
|
||||||
print(decoded.a)
|
|
||||||
print(decoded.d)
|
|
||||||
end
|
|
||||||
|
|
@ -2,5 +2,4 @@ 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)
|
||||||
proto = readbc.read_proto(fp)
|
print(header.name)
|
||||||
print(#proto.bcins)
|
|
||||||
|
|
|
||||||
95
opcodes.lua
95
opcodes.lua
|
|
@ -1,95 +0,0 @@
|
||||||
local bit = require('bit')
|
|
||||||
|
|
||||||
local function opcode(id, name, a, b, c, metamethod)
|
|
||||||
return {
|
|
||||||
id=id,
|
|
||||||
name=name,
|
|
||||||
a=a,
|
|
||||||
b=b,
|
|
||||||
c=c,
|
|
||||||
methametod=metamethod,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
local function gen_opcodes(tbl)
|
|
||||||
res = {}
|
|
||||||
for i = 1, #tbl do
|
|
||||||
res[tbl[i].id] = {
|
|
||||||
name = tbl[i].name,
|
|
||||||
a = tbl[i].a,
|
|
||||||
b = tbl[i].b,
|
|
||||||
c = tbl[i].c,
|
|
||||||
metamethod = tbl[i].metamethod,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
return res
|
|
||||||
end
|
|
||||||
|
|
||||||
local Mode = {
|
|
||||||
none = 0,
|
|
||||||
dst = 1,
|
|
||||||
base = 2,
|
|
||||||
var = 3,
|
|
||||||
rbase = 4,
|
|
||||||
uv = 5,
|
|
||||||
lit = 6,
|
|
||||||
lits = 7,
|
|
||||||
pri = 8,
|
|
||||||
num = 9,
|
|
||||||
str = 10,
|
|
||||||
tab = 11,
|
|
||||||
func = 12,
|
|
||||||
jump = 13,
|
|
||||||
cdata = 14,
|
|
||||||
max = 15,
|
|
||||||
none = 15, -- same as max
|
|
||||||
}
|
|
||||||
|
|
||||||
local Metamethod = {
|
|
||||||
index = 0,
|
|
||||||
newindex = 1,
|
|
||||||
gc = 2,
|
|
||||||
mode = 3,
|
|
||||||
eq = 4,
|
|
||||||
len = 5,
|
|
||||||
lt = 6,
|
|
||||||
le = 7,
|
|
||||||
concat = 8,
|
|
||||||
call = 9,
|
|
||||||
add = 10,
|
|
||||||
sub = 11,
|
|
||||||
mul = 12,
|
|
||||||
div = 13,
|
|
||||||
mod = 14,
|
|
||||||
pow = 15,
|
|
||||||
unm = 16,
|
|
||||||
metatable = 17,
|
|
||||||
tostring = 18,
|
|
||||||
}
|
|
||||||
|
|
||||||
local Opcodes_defs = gen_opcodes {
|
|
||||||
opcode(37, 'POW', Mode.dst, Mode.none, Mode.lits, Metamethod.none),
|
|
||||||
opcode(41, 'KSHORT', Mode.dst, Mode.var, Mode.var, Metamethod.pow),
|
|
||||||
opcode(75, 'RET0', Mode.rbase, Mode.none, Mode.lit, Mode.none),
|
|
||||||
}
|
|
||||||
|
|
||||||
local function decode(ins)
|
|
||||||
-- TODO: endianess
|
|
||||||
local id = bit.band(ins, 0xff)
|
|
||||||
local a = bit.band(ins, 0xff00) / 0x100
|
|
||||||
local b = bit.band(ins, 0xff0000) / 0x10000
|
|
||||||
local c = bit.band(ins, 0xff000000) / 0x1000000
|
|
||||||
local d = bit.band(ins, 0xffff0000) / 0x10000
|
|
||||||
return {
|
|
||||||
id = id,
|
|
||||||
a = a,
|
|
||||||
b = b,
|
|
||||||
c = c,
|
|
||||||
d = d,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
|
||||||
defs = Opcodes_defs,
|
|
||||||
decode = decode,
|
|
||||||
}
|
|
||||||
97
readbc.lua
97
readbc.lua
|
|
@ -5,53 +5,13 @@ 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 = read_u8(fp)
|
local uleb_byte = string.byte(fp:read(1))
|
||||||
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
|
||||||
|
|
@ -62,8 +22,8 @@ local function read_uleb128(fp)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function read_header(fp)
|
local function read_header(fp)
|
||||||
local magic = read_u8n(fp, 3)
|
local magic = { string.byte(fp:read(3), 1, 3) }
|
||||||
local version = read_u8(fp)
|
local version = string.byte(fp:read(1))
|
||||||
local flags = read_uleb128(fp)
|
local flags = read_uleb128(fp)
|
||||||
|
|
||||||
local name
|
local name
|
||||||
|
|
@ -83,57 +43,6 @@ 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,
|
|
||||||
framesize = framesize,
|
|
||||||
numuv = numuv,
|
|
||||||
numkgc = numkgc,
|
|
||||||
numkn = numkn,
|
|
||||||
numbc = numbc,
|
|
||||||
debugInfo = debugInfo,
|
|
||||||
bcins = bcins,
|
|
||||||
uvdata = uvdata,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
72
vm.lua
72
vm.lua
|
|
@ -1 +1,73 @@
|
||||||
|
local funcbc = require('jit.util').funcbc
|
||||||
|
|
||||||
|
function opcode(id, name, a, b, c, metamethod)
|
||||||
|
return {
|
||||||
|
id=id,
|
||||||
|
name=name,
|
||||||
|
a=a,
|
||||||
|
b=b,
|
||||||
|
c=c,
|
||||||
|
methametod=metamethod,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function gen_opcodes(tbl)
|
||||||
|
length = #tbl
|
||||||
|
res = {}
|
||||||
|
for i=1,length do
|
||||||
|
res[i] = i+1
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
Mode = {
|
||||||
|
none = 0,
|
||||||
|
dst = 1,
|
||||||
|
base = 2,
|
||||||
|
var = 3,,
|
||||||
|
rbase = 4,
|
||||||
|
uv = 5,
|
||||||
|
lit = 6,
|
||||||
|
lits = 7,
|
||||||
|
pri = 8,
|
||||||
|
num = 9,
|
||||||
|
str = 10,
|
||||||
|
tab = 11,
|
||||||
|
func = 12,
|
||||||
|
jump = 13,
|
||||||
|
cdata = 14,
|
||||||
|
max = 15,
|
||||||
|
none = 15, -- same as max
|
||||||
|
}
|
||||||
|
|
||||||
|
Metamethod = {
|
||||||
|
index = 0,
|
||||||
|
newindex = 1,
|
||||||
|
gc = 2,
|
||||||
|
mode = 3,
|
||||||
|
eq = 4,
|
||||||
|
len = 5,
|
||||||
|
lt = 6,
|
||||||
|
le = 7,
|
||||||
|
concat = 8,
|
||||||
|
call = 9,
|
||||||
|
add = 10,
|
||||||
|
sub = 11,
|
||||||
|
mul = 12,
|
||||||
|
div = 13,
|
||||||
|
mod = 14,
|
||||||
|
pow = 15,
|
||||||
|
unm = 16,
|
||||||
|
metatable = 17,
|
||||||
|
tostring = 18,
|
||||||
|
}
|
||||||
|
|
||||||
|
Opcodes = gen_opcodes {
|
||||||
|
opcode(37, 'POW', Mode.dst, Mode.none, Mode.lits, Metamethod.none),
|
||||||
|
opcode(41, 'KSHORT', Mode.dst, Mode.var, Mode.var, Metamethod.pow),
|
||||||
|
}
|
||||||
|
|
||||||
|
print(Opcodes[1])
|
||||||
|
ins, m = funcbc(test1, 3) -- TODO: what is m?
|
||||||
|
print(ins)
|
||||||
|
print(m)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue