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
LuaJIT bytecode interpreter written in Lua.
LuaJIT bytecode interpreter written in LuaJIT.

View File

@ -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
local decoded = opcodes.decode(proto.bcins[i])
local def = opcodes.defs[decoded.id]
print(def.name)
print(decoded.a)
print(decoded.d)
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]
-- 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()

View File

@ -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()

View File

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

View File

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

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
}