Improve inspect and add skeleton for VM
This commit is contained in:
parent
a78851c220
commit
e76d2cb187
|
|
@ -1,3 +1,3 @@
|
|||
# microLua
|
||||
|
||||
LuaJIT bytecode interpreter written in Lua.
|
||||
LuaJIT bytecode interpreter written in LuaJIT.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,59 @@
|
|||
local readbc = require('readbc')
|
||||
local opcodes = require('opcodes')
|
||||
|
||||
fp = io.open('tests/test1.luo')
|
||||
header = readbc.read_header(fp)
|
||||
proto = readbc.read_proto(fp)
|
||||
fp:close()
|
||||
local function inspect_proto(proto)
|
||||
print('\n-- proto --')
|
||||
-- print('Debug: ' .. proto.debug)
|
||||
print('Params: ' .. proto.numparams)
|
||||
print('Frame Size: ' .. proto.framesize)
|
||||
print('#Upvalues: ' .. proto.numuv)
|
||||
print('#kgc: ' .. proto.numkgc)
|
||||
print('#bcins: ' .. proto.numbc)
|
||||
|
||||
for i = 1, #proto.bcins do
|
||||
print('-- bytecode --')
|
||||
for i = 1, #proto.bcins do
|
||||
local decoded = opcodes.decode(proto.bcins[i])
|
||||
if opcodes.defs[decoded.id] ~= nil then
|
||||
local def = opcodes.defs[decoded.id]
|
||||
print(def.name)
|
||||
print(decoded.a)
|
||||
print(decoded.d)
|
||||
-- check for ABC or AD format
|
||||
if def.b == opcodes.Mode.none then
|
||||
print(string.format('%s\t A: %s\tB: %s\t C: %s', def.name, decoded.a, decoded.b, decoded.c))
|
||||
else
|
||||
print(string.format('%s\t A: %s\tD: %s', def.name, decoded.a, decoded.d))
|
||||
end
|
||||
else
|
||||
print('UNKNOWN OPCODE')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function inspect(fp)
|
||||
local header = readbc.read_header(fp)
|
||||
|
||||
print('-- header --')
|
||||
print('Name: ' .. header.name)
|
||||
print(string.format('Bytecode Version: %s', header.version))
|
||||
print('Stripped: ' .. (header.stripped and 'yes' or 'no'))
|
||||
|
||||
local proto = readbc.read_proto(fp)
|
||||
while proto ~= nil do
|
||||
inspect_proto(proto)
|
||||
proto = readbc.read_proto(fp)
|
||||
end
|
||||
end
|
||||
|
||||
local arg = {...}
|
||||
if arg[1] == nil then
|
||||
print('Please pass a LuaJIT bytecode file as command line argument')
|
||||
return 1
|
||||
end
|
||||
|
||||
local fp = io.open(arg[1])
|
||||
if fp == nil then
|
||||
print('Could not open path ' .. arg[1])
|
||||
return 1
|
||||
end
|
||||
|
||||
inspect(fp)
|
||||
|
||||
fp:close()
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
local readbc = require('readbc')
|
||||
local vm = require('vm')
|
||||
local VM = vm.VM
|
||||
|
||||
fp = io.open('tests/test1.luo')
|
||||
header = readbc.read_header(fp)
|
||||
proto = readbc.read_proto(fp)
|
||||
fo:close()
|
||||
fp:close()
|
||||
|
||||
print(#proto.bcins)
|
||||
vm = VM.new()
|
||||
vm:set_proto(proto)
|
||||
vm:run()
|
||||
|
|
|
|||
|
|
@ -77,8 +77,8 @@ 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 c = bit.band(ins, 0xff0000) / 0x10000
|
||||
local b = bit.band(ins, 0xff000000) / 0x1000000
|
||||
local d = bit.band(ins, 0xffff0000) / 0x10000
|
||||
return {
|
||||
id = id,
|
||||
|
|
@ -91,5 +91,6 @@ end
|
|||
|
||||
return {
|
||||
defs = Opcodes_defs,
|
||||
Mode = Mode,
|
||||
decode = decode,
|
||||
}
|
||||
|
|
|
|||
11
readbc.lua
11
readbc.lua
|
|
@ -3,7 +3,7 @@
|
|||
local bit=require('bit')
|
||||
|
||||
local HEADER_MAGIC = {27, string.byte('L'), string.byte('J')}
|
||||
local HEADER_FLAG_STRIP = 0x02
|
||||
local FLAG_STRIP = 0x02
|
||||
|
||||
local function read_u8(fp)
|
||||
return string.byte(fp:read(1))
|
||||
|
|
@ -67,9 +67,12 @@ local function read_header(fp)
|
|||
local flags = read_uleb128(fp)
|
||||
|
||||
local name
|
||||
if bit.band(flags, HEADER_FLAG_STRIP) ~= 0 then
|
||||
local stripped
|
||||
if bit.band(flags, FLAG_STRIP) ~= 0 then
|
||||
stripped = true
|
||||
name = ''
|
||||
else
|
||||
stripped = false
|
||||
local nameLen = read_uleb128(fp)
|
||||
name = fp:read(nameLen)
|
||||
end
|
||||
|
|
@ -77,7 +80,7 @@ local function read_header(fp)
|
|||
return {
|
||||
magic = magic,
|
||||
version = version,
|
||||
flags = flags,
|
||||
stripped = stripped,
|
||||
name = name,
|
||||
}
|
||||
end
|
||||
|
|
@ -103,7 +106,7 @@ local function read_proto(fp)
|
|||
local debugLen = 0
|
||||
local debugInfo = nil
|
||||
|
||||
if bit.band(flags, HEADER_FLAG_STRIP) ~= 0 then
|
||||
if bit.band(flags, FLAG_STRIP) ~= 0 then
|
||||
debugLen = read_uleb128(fp)
|
||||
|
||||
-- TODO: is this correct?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
local x = 1
|
||||
local y = 2
|
||||
local z = x^y
|
||||
return z
|
||||
36
vm.lua
36
vm.lua
|
|
@ -1 +1,37 @@
|
|||
local opcodes = require('opcodes')
|
||||
|
||||
local function set_proto(self, proto)
|
||||
self.proto = proto
|
||||
end
|
||||
|
||||
local function step(self)
|
||||
if self.pc >= self.proto.numbc then
|
||||
return false
|
||||
end
|
||||
local ins = self.proto.bcins[self.pc+1]
|
||||
local decop = opcodes.decode(ins)
|
||||
print(opcodes.defs[decop.id].name)
|
||||
|
||||
self.pc = self.pc + 1
|
||||
return true
|
||||
end
|
||||
|
||||
local function run(self)
|
||||
while self:step() do
|
||||
end
|
||||
end
|
||||
|
||||
local VM = {
|
||||
new = function()
|
||||
return {
|
||||
set_proto = set_proto,
|
||||
step = step,
|
||||
run = run,
|
||||
pc = 0,
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
return {
|
||||
VM = VM
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue