summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-07-18 00:03:53 +0800
committerruki <[email protected]>2026-07-18 00:03:53 +0800
commit1dee1ac4425bc1792bf79bffd329f92080580cc8 (patch)
tree4a2379f884d59cc052d61756d1c7d1249ac7d146
parent831d2df02925c3744786790df47dea9184437649 (diff)
improve sandbox to fork raw script
-rw-r--r--xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua13
-rw-r--r--xmake/core/sandbox/sandbox.lua93
-rw-r--r--xmake/modules/private/utils/batchcmds.lua10
3 files changed, 66 insertions, 50 deletions
diff --git a/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua b/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua
index 0a9cae170..7303e901e 100644
--- a/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua
+++ b/xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua
@@ -134,6 +134,19 @@ function sandbox_core_sandbox.filter(script)
return instance:filter()
end
+-- fork a new sandbox and bind a raw script
+function sandbox_core_sandbox.fork(script)
+ local instance = sandbox.instance()
+ if not instance then
+ raise("cannot get sandbox instance!")
+ end
+ local newinst, errors = instance:fork(script)
+ if not newinst then
+ raise(errors)
+ end
+ return newinst
+end
+
-- get all builtin modules
function sandbox_core_sandbox.builtin_modules()
return sandbox.builtin_modules()
diff --git a/xmake/core/sandbox/sandbox.lua b/xmake/core/sandbox/sandbox.lua
index 3be8975d0..13e598b73 100644
--- a/xmake/core/sandbox/sandbox.lua
+++ b/xmake/core/sandbox/sandbox.lua
@@ -105,43 +105,13 @@ function sandbox._new()
instance:_api_register_builtin(module_name, module)
end
- -- bind instance to the public script envirnoment
- instance:bind(instance._PUBLIC)
+ -- bind the public script envirnoment
+ instance:_bindenv(instance._PUBLIC)
return instance
end
--- new a sandbox instance with the given script
-function sandbox.new(script, opt)
- opt = opt or {}
-
- -- new instance
- local self = sandbox._new()
- assert(self and self._PUBLIC and self._PRIVATE)
-
- self._PRIVATE._FILTER = opt.filter
- self._PRIVATE._ROOTDIR = opt.rootdir
- self._PRIVATE._NAMESPACE = opt.namespace
-
- -- invalid script?
- if type(script) ~= "function" then
- return nil, "invalid script!"
- end
-
- -- bind public scope
- setfenv(script, self._PUBLIC)
-
- -- save script
- self._PRIVATE._SCRIPT = script
- return self
-end
-
--- load script in the sandbox
-function sandbox.call(script, ...)
- return utils.trycall(script, sandbox._traceback, ...)
-end
-
--- bind self instance to the given script or envirnoment
-function sandbox:bind(script_or_env)
+-- bind the given script or envirnoment and the self instance
+function sandbox:_bindenv(script_or_env)
-- get envirnoment
local env = script_or_env
@@ -150,20 +120,18 @@ function sandbox:bind(script_or_env)
end
-- bind instance to the script envirnoment
- setmetatable(env, { __index = function (tbl, key)
- if type(key) == "string" and key == "_SANDBOX" and rawget(tbl, "_SANDBOX_READABLE") then
- return self
- end
- return rawget(tbl, key)
+ setmetatable(env, { __index = function (tbl, key)
+ if type(key) == "string" and key == "_SANDBOX" and rawget(tbl, "_SANDBOX_READABLE") then
+ return self
end
- , __newindex = function (tbl, key, val)
- if type(key) == "string" and (key == "_SANDBOX" or key == "_SANDBOX_READABLE") then
- return
- end
- rawset(tbl, key, val)
- end})
-
- -- ok
+ return rawget(tbl, key)
+ end,
+ __newindex = function (tbl, key, val)
+ if type(key) == "string" and (key == "_SANDBOX" or key == "_SANDBOX_READABLE") then
+ return
+ end
+ rawset(tbl, key, val)
+ end})
return script_or_env
end
@@ -250,6 +218,36 @@ function sandbox:api_register_builtin(name, func)
sandbox._api_register_builtin(self, name, func)
end
+-- new a sandbox instance with the given script
+function sandbox.new(script, opt)
+ opt = opt or {}
+
+ -- new instance
+ local self = sandbox._new()
+ assert(self and self._PUBLIC and self._PRIVATE)
+
+ self._PRIVATE._FILTER = opt.filter
+ self._PRIVATE._ROOTDIR = opt.rootdir
+ self._PRIVATE._NAMESPACE = opt.namespace
+
+ -- invalid script?
+ if type(script) ~= "function" then
+ return nil, "invalid script!"
+ end
+
+ -- bind public scope
+ setfenv(script, self._PUBLIC)
+
+ -- save script
+ self._PRIVATE._SCRIPT = script
+ return self
+end
+
+-- call script in the sandbox
+function sandbox.call(script, ...)
+ return utils.trycall(script, sandbox._traceback, ...)
+end
+
-- get current instance in the sandbox modules
function sandbox.instance(script)
@@ -331,6 +329,5 @@ function sandbox.builtin_modules()
return builtin_modules
end
-
-- return module
return sandbox
diff --git a/xmake/modules/private/utils/batchcmds.lua b/xmake/modules/private/utils/batchcmds.lua
index a22879a81..2c80574a5 100644
--- a/xmake/modules/private/utils/batchcmds.lua
+++ b/xmake/modules/private/utils/batchcmds.lua
@@ -28,6 +28,7 @@ import("core.theme.theme")
import("core.tool.linker")
import("core.tool.compiler")
import("core.language.language")
+import("core.sandbox.sandbox")
import("utils.run_script")
import("utils.progress", {alias = "progress_utils"})
import("utils.binary.rpath", {alias = "rpath_utils"})
@@ -131,7 +132,11 @@ function _runcmd_call(cmd, opt)
local func = cmd.func
if func then
if not opt.dryrun then
- func(table.unpack(cmd.argv), cmd.opt)
+ local argv = table.clone(cmd.argv)
+ if cmd.opt then
+ table.insert(argv, cmd.opt)
+ end
+ func(table.unpack(argv))
end
end
end
@@ -323,7 +328,8 @@ end
-- add command: call lua function
function batchcmds:call(func, argv, opt)
- table.insert(self:cmds(), {kind = "call", func = func, argv = argv, opt = opt})
+ sandbox.fork(func)
+ table.insert(self:cmds(), {kind = "call", func = func, argv = argv, opt = opt})
end
-- add command: compile source files