environments, error messages, and stack traces, oh my!

Changed the way processes are launched.
multishell.openTab and kernel.run now accept the current environment as a parameter.
That new process inherits a copy of the passed environment.
Reduces complexity as the calling process is not required to create a suitable env.
Stack traces have been greatly improved and now include the stack for coroutines that error.
This commit is contained in:
kepler155c@gmail.com
2020-05-11 17:25:58 -06:00
parent bd911e80e8
commit 8279c1ae12
16 changed files with 151 additions and 187 deletions

View File

@@ -255,7 +255,7 @@ function page.packetSlide:eventHandler(event)
page:setFocus(page.packetGrid)
elseif event.type == 'packet_lua' then
multishell.openTab({ path = 'sys/apps/Lua.lua', args = { self.currentPacket.message }, focused = true })
multishell.openTab(_ENV, { path = 'sys/apps/Lua.lua', args = { self.currentPacket.message }, focused = true })
elseif event.type == 'prev_packet' then
local c = self.currentPacket

View File

@@ -12,6 +12,7 @@ local page = UI.Page {
buttons = {
{ text = 'Activate', event = 'activate' },
{ text = 'Terminate', event = 'terminate' },
{ text = 'Inspect', event = 'inspect' },
},
},
grid = UI.ScrollingGrid {
@@ -49,6 +50,12 @@ local page = UI.Page {
multishell.setFocus(t.uid)
elseif event.type == 'terminate' then
multishell.terminate(t.uid)
elseif event.type == 'inspect' then
multishell.openTab(_ENV, {
path = 'sys/apps/Lua.lua',
args = { t },
focused = true,
})
end
end
if event.type == 'quit' then

View File

@@ -110,7 +110,7 @@ page = UI.Page {
self.grid:draw()
elseif event.type == 'grid_select' then
multishell.openTab({
multishell.openTab(_ENV, {
path = 'sys/apps/Lua.lua',
args = { event.selected.raw },
focused = true,

View File

@@ -1,5 +1,3 @@
_G.requireInjector(_ENV)
local Event = require('opus.event')
local Util = require('opus.util')

View File

@@ -31,21 +31,14 @@ local function snmpConnection(socket)
socket:write('pong')
elseif msg.type == 'script' then
local env = kernel.makeEnv()
local fn, err = load(msg.args, 'script', nil, env)
if fn then
kernel.run({
fn = fn,
env = env,
title = 'script',
})
else
_G.printError(err)
end
kernel.run(_ENV, {
chunk = msg.args,
title = 'script',
})
elseif msg.type == 'scriptEx' then
local s, m = pcall(function()
local env = kernel.makeEnv()
local env = kernel.makeEnv(_ENV)
local fn, m = load(msg.args, 'script', nil, env)
if not fn then
error(m)

View File

@@ -41,12 +41,12 @@ local function telnetHost(socket, mode)
end
end
local shellThread = kernel.run({
local shellThread = kernel.run(_ENV, {
window = win,
title = mode .. ' client',
hidden = true,
fn = function()
Util.run(kernel.makeEnv(), Alt.get('shell'), table.unpack(termInfo.program))
Util.run(kernel.makeEnv(_ENV), Alt.get('shell'), table.unpack(termInfo.program))
if socket.queue then
socket:write(socket.queue)
end

View File

@@ -6,16 +6,6 @@ local fs = _G.fs
local settings = _G.settings
local shell = _ENV.shell
local sandboxEnv = { }
for k,v in pairs(_ENV) do
sandboxEnv[k] = v
end
sandboxEnv.package = nil
sandboxEnv.require = nil
sandboxEnv.arg = nil
sandboxEnv._ENV = nil
sandboxEnv.shell = shell
_G.requireInjector(_ENV)
local trace = require('opus.trace')
@@ -51,7 +41,7 @@ local function run(...)
local args = tokenise(...)
local command = table.remove(args, 1) or error('No such program')
local isUrl = not not command:match("^(https?:)")
local env = shell.makeEnv()
local env = shell.makeEnv(_ENV)
local path, loadFn
if isUrl then
@@ -64,7 +54,7 @@ local function run(...)
local fn, err = loadFn(path, env)
if not fn then
error(err)
error(err, -1)
end
if _ENV.multishell then
@@ -287,13 +277,9 @@ function shell.getRunningInfo()
return tProgramStack[#tProgramStack]
end
function shell.setEnv(name, value)
_ENV[name] = value
sandboxEnv[name] = value
end
function shell.makeEnv()
local env = setmetatable(Util.shallowCopy(sandboxEnv), { __index = _G })
-- convenience function for making a runnable env
function shell.makeEnv(env)
env = setmetatable(Util.shallowCopy(env), { __index = _G })
_G.requireInjector(env)
return env
end
@@ -321,7 +307,6 @@ function shell.newTab(tabInfo, ...)
if path then
tabInfo.path = path
tabInfo.env = shell.makeEnv()
tabInfo.args = args
tabInfo.title = fs.getName(path):match('([^%.]+)')
@@ -329,25 +314,21 @@ function shell.newTab(tabInfo, ...)
table.insert(tabInfo.args, 1, tabInfo.path)
tabInfo.path = 'sys/apps/shell.lua'
end
return _ENV.multishell.openTab(tabInfo)
return _ENV.multishell.openTab(_ENV, tabInfo)
end
return nil, 'No such program'
end
function shell.openTab(...)
-- needs to use multishell.launch .. so we can run with stock multishell
local tWords = tokenise( ... )
local sCommand = tWords[1]
if sCommand then
local sPath = shell.resolveProgram(sCommand)
if sPath == "sys/apps/shell.lua" then
return _ENV.multishell.launch(shell.makeEnv(), sPath, table.unpack(tWords, 2))
else
return _ENV.multishell.launch(shell.makeEnv(), "sys/apps/shell.lua", sCommand, table.unpack(tWords, 2))
end
if not _ENV.multishell then
function shell.newTab()
error('Multishell is not available')
end
end
function shell.openTab(...)
return shell.newTab({ }, ...)
end
function shell.openForegroundTab( ... )
return shell.newTab({ focused = true }, ...)
end