diff options
| author | ruki <[email protected]> | 2026-07-18 00:03:53 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-07-18 00:03:53 +0800 |
| commit | 1dee1ac4425bc1792bf79bffd329f92080580cc8 (patch) | |
| tree | 4a2379f884d59cc052d61756d1c7d1249ac7d146 | |
| parent | 831d2df02925c3744786790df47dea9184437649 (diff) | |
improve sandbox to fork raw script
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/sandbox/sandbox.lua | 13 | ||||
| -rw-r--r-- | xmake/core/sandbox/sandbox.lua | 93 | ||||
| -rw-r--r-- | xmake/modules/private/utils/batchcmds.lua | 10 |
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 |
