I am loading different Lua scripts using LuaJ into the globals environnment as follows in Java:
globals = JmePlatform.standardGlobals();
LuaValue chunk = globals.load(new FileInputStream(luaScriptA), scriptName, "t", globals);
chunk.call();
My problem is that if for example the scriptName happens to be require, print, error, math or any other name that already exists in globals after calling
globals = JmePlatform.standardGlobals();
, the script will in fact replace/override the actual functionality such as print.
Is there any simple way to prevent this from happening?
Unfortunately a test such as:
if (globals.get(scriptName) != Globals.NIL) {
//then dont allow script load
}
will not work for me as there are cases that it should actually override an existing script, when the script is updated.
I recommend never storing libraries in the global scope, for exactly this reason. See http://www.luafaq.org/#T1.37.2 for a way of loading modules and libraries using required. I'm not sure if this works on LuaJ, but if it implements require correctly, you can make a loader function and put it in package.loaders.
Basically, you define your libraries like this:
-- foo.lua
local M = {}
function M.bar()
print("bar!")
end
return M
And import them like this:
-- main.lua
local Foo = require "foo"
Foo.bar() -- prints "bar!"
See the documentation of require for implementing the loading function.
Related
I am writing some functions for a C extension module for python and need to import a module I wrote directly in python for access to a custom python type. I use PyImport_ImportModule() in the body of my C function, then PyObject_GetAttrString() on the module to get the custom python type. This executes every time the C function is called and seems like it's not very efficient and may not be best practice. I'm looking for a way to have access to the python custom type as a PyObject* or PyTypeObject* in my source code for efficiency and I may need the type in more than one C function also.
Right now the function looks something like
static PyObject* foo(PyObject* self, PyObject* args)
{
PyObject* myPythonModule = PyImport_ImportModule("my.python.module");
if (!myPythonModule)
return NULL;
PyObject* myPythonType = PyObject_GetAttrString(myPythonModule, "MyPythonType");
if (!myPythonType) {
Py_DECREF(myPythonModule);
return NULL;
}
/* more code to create and return a MyPythonType instance */
}
To avoid retrieving myPythonType every function call I tried adding a global variable to hold the object at the top of my C file
static PyObject* myPythonType;
and initialized it in the module init function similar to the old function body
PyMODINIT_FUNC
PyInit_mymodule(void)
{
/* more initializing here */
PyObject* myPythonModule = PyImport_ImportModule("my.python.module");
if (!myPythonModule) {
/* clean-up code here */
return NULL;
}
// set the static global variable here
myPythonType = PyObject_GetAttrString(myPythonModule, "MyPythonType");
Py_DECREF(myPythonModule);
if (!myPythonType) {
/* clean-up code here */
return NULL;
/* finish initializing module */
}
which worked, however I am unsure how to Py_DECREF the global variable whenever the module is finished being used. Is there a way to do that or even a better way to solve this whole problem I am overlooking?
First, just calling import each time probably isn't as bad as you think - Python does internally keep a list of imported modules, so the second time you call it on the same module the cost is much lower. So this might be an acceptable solution.
Second, the global variable approach should work, but you're right that it doesn't get cleaned up. This is rarely a problem because modules are rarely unloaded (and most extension modules don't really support it), but it isn't great. It also won't work with isolated sub-interpreters (which isn't much of a concern now, but may become more more popular in future).
The most robust way to do it needs multi-phase initialization of your module. To quickly summarise what you should do:
You should define a module state struct containing this type of information,
Your module spec should contain the size of the module state struct,
You need to initialize this struct within the Py_mod_exec slot.
You need to create an m_free function (and ideally the other GC functions) to correctly decref your state during de-initialization.
Within a global module function, self will be your module object, and so you can get the state with PyModule_GetState(self)
How to output the contents of a function?
function a()
print("Hello,World")
end
print(func_toString(a))
I hope the result of func_toString(a) could be
function a()
print("Hello,World")
end
or just
print("Hello,World")
It is assumed that the source code is executed directly without precompiling or embedding.
How to do this?
well, it's not completely impossible, the code in some cases can be read from a lua file, for example:
function a()
print("Hello,World")
end
local function get_source_code(f)
local t = debug.getinfo (f)
if t.linedefined < 0 then print("source",t.source); return end
local name = t.source:gsub("^#","")
local i = 0
local text = {}
for line in io.lines(name) do
i=i+1
if i >= t.linedefined then text[#text+1] = line end
if i >= t.lastlinedefined then break end
end
return table.concat(text,"\n")
end
print( get_source_code(a) )
maybe that will be enough.
This is not possible from within the running Lua program.
Lua provides the debug library to inspect functions and variable. This allows you to obtain the source (the path or string where the function is defined) and the line range on which the function is defined. In the vast majority of cases this might actually be enough: Just find the first occurrence of function(...) on the first line and the first occurrence of end on the last line, then string.sub the relevant portion. This is however rather error prone; consider e.g.
function a() function b() end end
a()
func_toString(a)
since both functions are on the same line, you can't distinguish them - the debug library only provides you line info, nothing more. You could try to distinguish them by their signature since hacks exist to obtain the method signature, but that would fail here as well since both functions have the same signature. You could try gsubing them out based on their names, but remember that functions can be anonymous in Lua.
Lua also provides the string.dump function to obtain the bytecode of a function. I highly doubt that this is of any use to you; theoretically you could decompile it to get back a "Lua" representation of what the function does, but it would hardly be recognizable or readable.
I have a file setup like this:
main.lua (requires 'mydir.b' and then 'b')
b.lua
mydir/
b.so (LuaJIT C module)
From main, I do this:
function print_loaded()
for k, v in pairs(package.loaded) do print(k, v) end
end
print_loaded()
require 'mydir.b'
print_loaded()
-- This would now include 'mydir.b' instead of 'b':
local b = require 'b'
The outputs of the prints show that my call to require 'mydir.b' is setting the return value as the value of package.loaded['b'] as well as the expected package.loaded['mydir.b']. I wanted to have package.loaded['b'] left unset so that I can later require 'b' and not end up with the (in my opinion incorrectly) cached value from mydir.b.
My question is: What's a good way to deal with this?
In my case, I want to be able to copy around mydir as a subdir of any of my LuaJIT projects, and not have to worry about mydir.whatever polluting the module namespace by destroying any later requires of whatever at the parent directory level.
In anticipation of people saying, "just rename your modules!" Yes. I can do that. But I'd love to know if there's a better solution that allows me to simply not have to worry about the name collisions at all.
The problem was that I was calling luaL_register incorrectly from within my b.so's source file (b.c).
Here is the bad code that caused the problem:
static const struct luaL_reg b[] = {
/* set up a list of function pointers here */
};
int luaopen_mydir_b(lua_State *L) {
luaL_register(L, "b", b); // <-- PROBLEM HERE (see below)
return 1; // 1 = # Lua-visible return values on the stack.
}
The problem with the highlighted line is that it will specifically set package.loaded['b'] to have the return value of this module when it's loaded. This can be fixed by replacing the line with this:
luaL_register(L, "mydir.b", b);
which will set package.loaded['mydir.b'] instead, and thus leave room for later use of a module with the same name (without the mydir prefix).
I didn't realize this until long after I asked this question, when I finally got around to reading the official docs for luaL_register for Lua 5.1, which is the version LuaJIT complies with.
Let's say that I call some functions indirectly, via a variable. For example:
obj = {
on_init = function()
print "hello."
end,
on_destroy = function()
print "bye."
end,
on_do_something = function()
print "doing something."
error("Hi de hi, hi de ho!")
end,
}
local event = "do_something"
local func = obj["on_" .. event]
func()
All works fine.
However, the problem is that when the called function raises an exception (as in the code above) the error message isn't quite clear. It is thus:
lua: test.lua:13: Hi de hi, hi de ho!
stack traceback:
[C]: in function 'error'
test.lua:13: in function 'func'
test.lua:20: in main chunk
It says "in function 'func'". I'd prefer it to say "in function 'on_do_something'" instead.
I'd imagine this scenario to be very common. Is there a solution for this?
I tried calling the function thus:
obj["on_" .. event]()
But then the error message says "in function '?'", which isn't helpful either.
(I tried this code on Lua 5.1, 5.2 and LuaJIT without notable differences.)
This is a limitation of the heuristics used by Lua to provide names for functions.
In Lua, all functions are anonymous. A given function can be the value of several variables: global, local, and table fields. The Lua debug system, which is used in error handling, tries to find a reasonable name for a value based on where it came from by looking into the bytecode being executed.
See
Why is 'name' nil for debug.getinfo(1).
You have a few options. The debug module will try to produce something useful. For instance, you might be able to get the file name and line number where it was defined, if this is your own code. See
http://www.lua.org/pil/23.1.html for the list of what is available via debug module. Or, you might be able to define the functions in the module, then add them to the table:
-- module something
function a()
...
end
tt = {
fn1 = a,
...
}
Depending on where you trap the error (error handler installed via debug hook?), you could check if filename is the module where your table of functions is defined, and if it is, then use the debug module to print appropriate info based on your table structure etc; if it is not, just print the default traceback etc.
How do I call a function that needs to be called from above its creation? I read something about forward declarations, but Google isn't being helpful in this case. What is the correct syntax for this?
Lua is a dynamic language and functions are just a kind of value that can be called with the () operator. So you don't really need to forward declare the function so much as make sure that the variable in scope when you call it is the variable you think it is.
This is not an issue at all for global variables containing functions, since the global environment is the default place to look to resolve a variable name. For local functions, however, you need to make sure the local variable is already in scope at the lexical point where you need to call the value it stores, and also make sure that at run time it is really holding a value that can be called.
For example, here is a pair of mutually recursive local functions:
local a,b
a = function() return b() end
b = function() return a() end
Of course, that is also an example of using tail calls to allow infinite recursion that does nothing, but the point here is the declarations. By declaring the variables with local before either has a function stored in it, those names are known to be local variables in lexical scope of the rest of the example. Then the two functions are stored, each referring to the other variable.
You can forward declare a function by declaring its name before declaring the actual function body:
local func1
local func2 = function()
func1()
end
func1 = function()
--do something
end
However forward declarations are only necessary when declaring functions with local scope. That is generally what you want to do, but Lua also supports a syntax more like C, in which case forward declaration is not necessary:
function func2()
func1()
end
function func1()
--do something
end
Testing under the embedded lua in Freeswitch, forward declaration does not work:
fmsg("CRIT", "It worked.")
function fmsg(infotype, msg)
freeswitch.consoleLog(infotype, msg .. "\n")
end
result:
[ERR] mod_lua.cpp:203 /usr/local/freeswitch/scripts/foo.lua:1: attempt to call global 'fmsg' (a nil value)
Reversing the order does (duh) work.
To comprehend how forward referencing in Lua works compared to C, you must understand the a fundamental difference between C compilation and the Lua execution.
In C, forward referencing is a compile time mechanism. Hence if you include a forward declaration template in a C module then any of your code following will employ this template in compiling the call. You may or may not include the function implementation in the same module, in which case both declarations must be semantically identical or the compiler will error. Since this is a compile time construct, the compiled code can be executed in any order.
In Lua, forward referencing is runtime mechanism, in that the compiled function generates a function prototype internally within the code, but this is only accessible as a runtime Lua variable or value after the execution has
passed over the declaration creating a Lua closure. Here the declaration order within the source is immaterial. It is the execution order that is important: if the closure hasn't been bound to the variable yet, then the execution will throw a "nil value" exception.If you are using a local variable to hold the function value, then normal local scoping rules still apply: the local declaration must precede its use in the source and must be within scope, otherwise the compiler will compile in the wrong global or outer local reference. So forward referencing using locals as discussed in other answer will work, but only if the Protos are bound to closures before the first call is executed.
Doesn't work for me if I try to call the function before definition. I am using this Lua script in nginx conf.
lua entry thread aborted: runtime error: lua_redirect.lua:109: attempt to call global 'throwErrorIfAny' (a nil value)
Code snippet -
...
throwErrorIfAny()
...
function throwErrorIfAny()
ngx.say("request not allowed")
ngx.exit(ngx.HTTP_OK)
end
Given some other answers have also pointed out that it didn't work for them either, it is possible that forward declaration of Lua doesn't work with other tools.
PS : It works fine if I put the function definition before and then call it after wards.
If you use OOP you can call any function member prior its "definition".
local myClass = {}
local myClass_mt = { __index = myClass }
local function f1 (self)
print("f1")
self:later() --not yet "delared" local function
end
local function f2 (self)
print("f2")
self:later() --not yet "declared" local function
end
--...
--later in your source declare the "later" function:
local function later (self)
print("later")
end
function myClass.new() -- constructor
local this = {}
this = {
f1 = f1,
f2 = f2,
later = later, --you can access the "later" function through "self"
}
setmetatable(this, myClass_mt)
return this
end
local instance = myClass.new()
instance:f1()
instance:f2()
Program output:
f1
later
f2
later