# HG changeset patch # User jbe # Date 1427059537 -3600 # Node ID 4e69ce9a6365bb34531b206d9b9df1d4036ebeb9 # Parent 4dc2ec12643c6ccc39847e765d7b38e5d9e70d0b Mechanism to load, compile, and cache Lua code from the filesystem diff -r 4dc2ec12643c -r 4e69ce9a6365 framework/bin/mcp.lua --- a/framework/bin/mcp.lua Sun Mar 22 20:39:13 2015 +0100 +++ b/framework/bin/mcp.lua Sun Mar 22 22:25:37 2015 +0100 @@ -20,6 +20,36 @@ _ENV = setmetatable({}, global_metatable) --[[-- +lua_func = -- compiled Lua function +loadcached( + filename -- path to a Lua source or byte-code file +) + +Loads, compiles and caches a Lua chunk. If the file does not exist, nil and an error string are returned. Otherwise the file is loaded, compiled, and cached. The cached value (i.e. the compiled function) is returned. An error is raised if the compilation was not successful. + +--]]-- +do + local cache = {} + function loadcached(filename) + local file, read_error = io.open(filename, "r") + if file then + local filedata = assert(file:read("*a")) + assert(file:close()) + local func, compile_error = load(filedata, "=" .. filename, nil, _ENV) + if func then + cache[filename] = func + return func + else + error(compile_error, 0) + end + else + return nil, read_error + end + end +end +--//-- + +--[[-- WEBMCP_MODE A constant set to "listen" in case of a network request, or set to "interactive" in case of interactive mode. @@ -139,17 +169,10 @@ setmetatable(self, autoloader_mt) end local function try_exec(filename) - local file = io.open(filename, "r") - if file then - local filedata = file:read("*a") - io.close(file) - local func, errmsg = load(filedata, "=" .. filename, nil, _ENV) - if func then - func() - return true - else - error(errmsg, 0) - end + local func = loadcached(filename) + if func then + func() + return true else return false end diff -r 4dc2ec12643c -r 4e69ce9a6365 framework/env/execute/chunk.lua --- a/framework/env/execute/chunk.lua Sun Mar 22 20:39:13 2015 +0100 +++ b/framework/env/execute/chunk.lua Sun Mar 22 22:25:37 2015 +0100 @@ -1,7 +1,7 @@ --[[-- return_value = -- return value of executed chunk execute.chunk{ - file_path = file_path, -- path to a lua source or byte-code file + file_path = file_path, -- path to a Lua source or byte-code file app = app, -- app name to use or the current will be used module = module, -- module where chunk is located chunk = chunk -- name of chunk (filename without .lua extension) @@ -35,7 +35,7 @@ WEBMCP_BASE_PATH, 'app', app, module, chunk .. '.lua' ) - local func, load_errmsg = loadfile(file_path, nil, _ENV) + local func, load_errmsg = loadcached(file_path) if not func then error('Could not load file "' .. file_path .. '": ' .. load_errmsg) end diff -r 4dc2ec12643c -r 4e69ce9a6365 framework/env/execute/file_path.lua --- a/framework/env/execute/file_path.lua Sun Mar 22 20:39:13 2015 +0100 +++ b/framework/env/execute/file_path.lua Sun Mar 22 22:25:37 2015 +0100 @@ -1,7 +1,7 @@ --[[-- status_code = -- status code returned by the executed lua file (a string) execute.file_path{ - file_path = file_path, -- path to a lua source or byte-code file + file_path = file_path, -- path to a Lua source or byte-code file id = id, -- id to be returned by param.get_id(...) during execution params = params -- parameters to be returned by param.get(...) during execution } @@ -14,7 +14,7 @@ local file_path = args.file_path local id = args.id local params = args.params - local func, load_errmsg = loadfile(file_path, nil, _ENV) + local func, load_errmsg = loadcached(file_path) if not func then error('Could not load file "' .. file_path .. '": ' .. load_errmsg) end diff -r 4dc2ec12643c -r 4e69ce9a6365 framework/env/execute/load_chunk.lua --- a/framework/env/execute/load_chunk.lua Sun Mar 22 20:39:13 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ ---[[-- -return_value = -- return value of executed chunk -execute.load_chunk{ - file_path = file_path, -- path to a lua source or byte-code file - app = app, -- app name to use or the current will be used - module = module, -- module where chunk is located - chunk = chunk -- filename of lua file to load (including filename extension) - id = id, -- id to be returned by param.get_id(...) during execution - params = params -- parameters to be returned by param.get(...) during execution -} - -NOTE: execute.load_chunk{...} is DEPRECATED and replaced by execute.chunk{...}. Both functions differ in interpretation of argument "chunk" regarding the filename extenstion '.lua'. - -This function loads and executes a lua file specified by a given path or constructs a path to load from the module and chunk name. - ---]]-- - -function execute.load_chunk(args) - local chunk_name - if args.chunk then - chunk_name = string.match(args.chunk, "^(.*)%.lua$") - if not chunk_name then - error('"chunk_name" does not end with \'.lua\'') - end - end - return execute.chunk{ - file_path = args.file_path, - app = args.app, - module = args.module, - chunk = chunk_name, - id = args.id, - params = args.params - } -end diff -r 4dc2ec12643c -r 4e69ce9a6365 framework/env/locale/_get_translation_table.lua --- a/framework/env/locale/_get_translation_table.lua Sun Mar 22 20:39:13 2015 +0100 +++ b/framework/env/locale/_get_translation_table.lua Sun Mar 22 22:25:37 2015 +0100 @@ -9,12 +9,9 @@ return translation_table end local filename = encode.file_path(WEBMCP_BASE_PATH, "locale", "translations." .. language_code .. ".lua") - local func - if _ENV then - func = assert(loadfile(filename), nil, {}) - else - func = assert(loadfile(filename)) - setfenv(func, {}) + local func, load_errmsg = loadcached(filename) + if not func then + error('Could not load translation file "' .. filename .. '": ' .. load_errmsg) end translation_table = func() if type(translation_table) ~= "table" then