Improve inspect and add skeleton for VM

This commit is contained in:
Enrico Lumetti 2022-05-08 09:56:37 +02:00
parent a78851c220
commit e76d2cb187
7 changed files with 111 additions and 19 deletions

View File

@ -1,3 +1,3 @@
# microLua # microLua
LuaJIT bytecode interpreter written in Lua. LuaJIT bytecode interpreter written in LuaJIT.

View File

@ -1,15 +1,59 @@
local readbc = require('readbc') local readbc = require('readbc')
local opcodes = require('opcodes') local opcodes = require('opcodes')
fp = io.open('tests/test1.luo') local function inspect_proto(proto)
header = readbc.read_header(fp) print('\n-- proto --')
proto = readbc.read_proto(fp) -- print('Debug: ' .. proto.debug)
fp:close() 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 --')
local decoded = opcodes.decode(proto.bcins[i]) for i = 1, #proto.bcins do
local def = opcodes.defs[decoded.id] local decoded = opcodes.decode(proto.bcins[i])
print(def.name) if opcodes.defs[decoded.id] ~= nil then
print(decoded.a) local def = opcodes.defs[decoded.id]
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 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()

View File

@ -1,8 +1,12 @@
local readbc = require('readbc') local readbc = require('readbc')
local vm = require('vm')
local VM = vm.VM
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) proto = readbc.read_proto(fp)
fo:close() fp:close()
print(#proto.bcins) vm = VM.new()
vm:set_proto(proto)
vm:run()

View File

@ -77,8 +77,8 @@ local function decode(ins)
-- TODO: endianess -- TODO: endianess
local id = bit.band(ins, 0xff) local id = bit.band(ins, 0xff)
local a = bit.band(ins, 0xff00) / 0x100 local a = bit.band(ins, 0xff00) / 0x100
local b = bit.band(ins, 0xff0000) / 0x10000 local c = bit.band(ins, 0xff0000) / 0x10000
local c = bit.band(ins, 0xff000000) / 0x1000000 local b = bit.band(ins, 0xff000000) / 0x1000000
local d = bit.band(ins, 0xffff0000) / 0x10000 local d = bit.band(ins, 0xffff0000) / 0x10000
return { return {
id = id, id = id,
@ -91,5 +91,6 @@ end
return { return {
defs = Opcodes_defs, defs = Opcodes_defs,
Mode = Mode,
decode = decode, decode = decode,
} }

View File

@ -3,7 +3,7 @@
local bit=require('bit') 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 FLAG_STRIP = 0x02
local function read_u8(fp) local function read_u8(fp)
return string.byte(fp:read(1)) return string.byte(fp:read(1))
@ -67,9 +67,12 @@ local function read_header(fp)
local flags = read_uleb128(fp) local flags = read_uleb128(fp)
local name local name
if bit.band(flags, HEADER_FLAG_STRIP) ~= 0 then local stripped
if bit.band(flags, FLAG_STRIP) ~= 0 then
stripped = true
name = '' name = ''
else else
stripped = false
local nameLen = read_uleb128(fp) local nameLen = read_uleb128(fp)
name = fp:read(nameLen) name = fp:read(nameLen)
end end
@ -77,7 +80,7 @@ local function read_header(fp)
return { return {
magic = magic, magic = magic,
version = version, version = version,
flags = flags, stripped = stripped,
name = name, name = name,
} }
end end
@ -103,7 +106,7 @@ local function read_proto(fp)
local debugLen = 0 local debugLen = 0
local debugInfo = nil local debugInfo = nil
if bit.band(flags, HEADER_FLAG_STRIP) ~= 0 then if bit.band(flags, FLAG_STRIP) ~= 0 then
debugLen = read_uleb128(fp) debugLen = read_uleb128(fp)
-- TODO: is this correct? -- TODO: is this correct?

4
tests/test2.lua Normal file
View File

@ -0,0 +1,4 @@
local x = 1
local y = 2
local z = x^y
return z

36
vm.lua
View File

@ -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
}