diff --git a/modules/module-lua-scripting/module.c b/modules/module-lua-scripting/module.c index be6d2cac..03afa5eb 100644 --- a/modules/module-lua-scripting/module.c +++ b/modules/module-lua-scripting/module.c @@ -53,6 +53,64 @@ execute_script (lua_State *L, struct ScriptData * s, GError ** error) return wplua_pcall (L, nargs, 0, error); } +static int +wp_lua_scripting_package_loader (lua_State *L) +{ + luaL_checktype (L, 2, LUA_TFUNCTION); + wplua_push_sandbox (L); + lua_pushvalue (L, 2); + lua_call (L, 1, 1); + return 1; +} + +static int +wp_lua_scripting_package_searcher (lua_State *L) +{ + const gchar *name = luaL_checkstring (L, 1); + g_autoptr (GError) error = NULL; + g_autofree gchar *filename = g_strdup_printf ("%s.lua", name); + g_autofree gchar *script = wp_find_file ( + WP_LOOKUP_DIR_ENV_DATA | + WP_LOOKUP_DIR_XDG_CONFIG_HOME | + WP_LOOKUP_DIR_ETC | + WP_LOOKUP_DIR_PREFIX_SHARE, + filename, "scripts/lib"); + + if (!script) { + lua_pushliteral (L, "script not found"); + return 1; + } + + /* 1. loader (function) */ + lua_pushcfunction (L, wp_lua_scripting_package_loader); + + /* 2. loader data (param to 1) */ + if (!wplua_load_path (L, script, &error)) { + lua_pop (L, 1); + lua_pushstring (L, error->message); + return 1; + } + + /* 3. script path */ + lua_pushstring (L, script); + return 3; +} + +static void +wp_lua_scripting_enable_package_searcher (lua_State *L) +{ + /* table.insert(package.searchers, 2, wp_lua_scripting_package_searcher) */ + lua_getglobal (L, "table"); + lua_getfield (L, -1, "insert"); + lua_remove (L, -2); + lua_getglobal (L, "package"); + lua_getfield (L, -1, "searchers"); + lua_remove (L, -2); + lua_pushinteger (L, 2); + lua_pushcfunction (L, wp_lua_scripting_package_searcher); + lua_call (L, 3, 0); +} + G_DECLARE_FINAL_TYPE (WpLuaScriptingPlugin, wp_lua_scripting_plugin, WP, LUA_SCRIPTING_PLUGIN, WpComponentLoader) G_DEFINE_TYPE (WpLuaScriptingPlugin, wp_lua_scripting_plugin, @@ -99,6 +157,7 @@ wp_lua_scripting_plugin_enable (WpPlugin * plugin, WpTransition * transition) lua_settable (self->L, LUA_REGISTRYINDEX); wp_lua_scripting_api_init (self->L); + wp_lua_scripting_enable_package_searcher (self->L); wplua_enable_sandbox (self->L, WP_LUA_SANDBOX_ISOLATE_ENV); /* execute scripts that were queued in for loading */ diff --git a/modules/module-lua-scripting/wplua/sandbox.lua b/modules/module-lua-scripting/wplua/sandbox.lua index 6774d835..67c40009 100644 --- a/modules/module-lua-scripting/wplua/sandbox.lua +++ b/modules/module-lua-scripting/wplua/sandbox.lua @@ -38,7 +38,7 @@ else -- full list, used for scripts ([[ _VERSION assert error ipairs next pairs print - pcall select tonumber tostring type xpcall + pcall select tonumber tostring type xpcall require table utf8 @@ -76,6 +76,8 @@ for k, v in pairs(SANDBOX_ENV) do end end +populate_env("package") + if SANDBOX_CONFIG["isolate_env"] then -- in isolate_env mode, use a separate enviornment for each loaded chunk and -- store all of them in a global table so that they are not garbage collected @@ -92,7 +94,7 @@ if SANDBOX_CONFIG["isolate_env"] then -- set it as the chunk's 1st upvalue (__ENV) debug.setupvalue(chunk, 1, env) -- execute the chunk - chunk(...) + return chunk(...) end else -- in common_env mode, use the same environment for all loaded chunks @@ -106,6 +108,6 @@ else -- set it as the chunk's 1st upvalue (__ENV) debug.setupvalue(chunk, 1, SANDBOX_COMMON_ENV) -- execute the chunk - chunk(...) + return chunk(...) end end diff --git a/modules/module-lua-scripting/wplua/wplua.c b/modules/module-lua-scripting/wplua/wplua.c index 2b8c2008..ec197196 100644 --- a/modules/module-lua-scripting/wplua/wplua.c +++ b/modules/module-lua-scripting/wplua/wplua.c @@ -23,7 +23,7 @@ _wplua_openlibs (lua_State *L) * http://www.lua.org/source/5.3/linit.c.html */ static const luaL_Reg loadedlibs[] = { {"_G", luaopen_base}, - /* {LUA_LOADLIBNAME, luaopen_package}, */ + {LUA_LOADLIBNAME, luaopen_package}, /* {LUA_COLIBNAME, luaopen_coroutine}, */ {LUA_TABLIBNAME, luaopen_table}, /* {LUA_IOLIBNAME, luaopen_io}, */ diff --git a/tests/wplua/meson.build b/tests/wplua/meson.build index c0e17840..c827aba3 100644 --- a/tests/wplua/meson.build +++ b/tests/wplua/meson.build @@ -37,3 +37,9 @@ test( args: ['monitor-rules.lua'], env: common_env, ) +test( + 'test-lua-require', + script_tester, + args: ['require.lua'], + env: common_env, +) diff --git a/tests/wplua/scripts/lib/testlib.lua b/tests/wplua/scripts/lib/testlib.lua new file mode 100644 index 00000000..0ea3b5f1 --- /dev/null +++ b/tests/wplua/scripts/lib/testlib.lua @@ -0,0 +1,9 @@ +local testlib = {} + +function testlib.test_add_ten (x) + return x + 10 +end + +Log.info("in testlib") + +return testlib diff --git a/tests/wplua/scripts/require.lua b/tests/wplua/scripts/require.lua new file mode 100644 index 00000000..a40a4ed5 --- /dev/null +++ b/tests/wplua/scripts/require.lua @@ -0,0 +1,8 @@ +local testlib = require("testlib") + +assert(type(testlib) == "table") +assert(package.loaded["testlib"] == testlib) + +local x = 1 +x = testlib.test_add_ten(x) +assert(x == 11)