Skip to content
Permalink
Browse files
Added class loading from SEE archives. SEE utility program now allows…
… archive class path.
  • Loading branch information
James King committed Aug 17, 2013
1 parent b94782a commit 17f3e6e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
@@ -188,6 +188,7 @@ function SeeVM.new(natives, seePath)
self.classes = { }
self.natives = natives
self.natives.error = error
self.archives = { }
self.classPaths = { }
self.base.Object = self:loadClassFromAny("see.base.Object")
self.rt = self:loadClassFromAny("see.rt.Class")
@@ -273,9 +274,13 @@ function SeeVM:loadClassFromAny(name)

if class then return class end

-- Load from custom class paths
-- Load from custom class paths.
for _, classPath in pairs(self.classPaths) do
class, err = self:loadClassFromFile(fs.combine(classPath, name:gsub("%.", "/") .. ".lua"), name)
if fs.isDir(classPath) then
class, err = self:loadClassFromFile(fs.combine(classPath, name:gsub("%.", "/") .. ".lua"), name)
else
class, err = self:loadClassFromArchive(self.archives[classPath], name:gsub("%.", "/") .. ".lua", name)
end
if class then return class end
end

@@ -332,6 +337,7 @@ end
@param string:path The path to the class to load.
@param string:name The full name of the class to load.
@return table The loaded class.
@return string Error message, or nil if successful.
]]
function SeeVM:loadClassFromFile(path, name)
local fileHandle = fs.open(path, "r")
@@ -340,6 +346,29 @@ function SeeVM:loadClassFromFile(path, name)
end
local code = fileHandle.readAll()
fileHandle.close()

-- Setup class execution environment
local def, err = loadstring(code, name)
if not def then
return nil, err
end
return self:loadClass(def, getAnnotations(code), name)
end

-- TODO: Make file offset table. Currently, it takes O(N) time to find each file where N is its position in the file.
--[[
Load a class from a SEE archive.
@param string:archiveBytes The loaded archive.
@param string:path The path to the class to load.
@param string:name The full name of the class to load.
@return table The loaded class.
@return string Error message, or nil if successful.
]]
function SeeVM:loadClassFromArchive(archiveBytes, path, name)
local loc = archiveBytes:find("F" .. path .. "\0", 1, true) + #path + 2
local fin = archiveBytes:find("\0", loc) - 1
local code = archiveBytes:sub(loc, fin)

-- Setup class execution environment
local def, err = loadstring(code, name)
if not def then
@@ -19,6 +19,16 @@ local _, err = pcall(function(...)
xpcall(function() MainClass.main(vm.base.Array.new(unpack(args))) end, see.errorHandler)
end

local function runFromArchive(classPath, mainClassName, args)
local fileHandle = fs.open(classPath, "r")
vm.archives[classPath] = fileHandle.readAll()
fileHandle.close()
local MainClass = vm:loadClassFromAny(mainClassName)
if not MainClass then error("Main class not found! ") end
if not MainClass.main then error("Main method not found!") end
xpcall(function() MainClass.main(vm.base.Array.new(unpack(args))) end, see.errorHandler)
end

local function getSubDirectories(path)
local paths = { }
for _, name in pairs(fs.list(path)) do
@@ -118,7 +128,7 @@ local _, err = pcall(function(...)
if fs.isDir(classPath) then
runFromPath(classPath, mainClassName, programArgs)
else
-- TODO: Add archive reading.
runFromArchive(classPath, mainClassName, programArgs)
end
elseif op == "-p" then
-- Pack option.

0 comments on commit 17f3e6e

Please sign in to comment.