Performance Tips?
grilme99 opened this issue · comments
Hey,
I'm new to Fengari (and Lua VMs in general) and was wondering about some general performance tips. Here is my code (it is running in a child process):
function start() {
// Create the new Lua state
const L = lauxlib.luaL_newstate()
// Function for loading libraries
var loadLib = function (name, lib) {
lauxlib.luaL_requiref(L, fengari.to_luastring(name), lib, 1);
lua.lua_pop(L, 1);
};
// Load the string, coroutine, table, math, utf8 and base libraries
base.luaopen_base(L)
loadLib(lualib.LUA_STRLIBNAME, lualib.luaopen_string);
loadLib(lualib.LUA_COLIBNAME, lualib.luaopen_coroutine);
loadLib(lualib.LUA_TABLIBNAME, lualib.luaopen_table);
loadLib(lualib.LUA_MATHLIBNAME, lualib.luaopen_math);
loadLib(lualib.LUA_UTF8LIBNAME, lualib.luaopen_utf8);
// Set globals
flua_setglobals(L, {
// Wait function
wait: (sec) => {
sec = (sec || 0.05).clamp(0.05, Number.MAX_SAFE_INTEGER)
setTimeout(() => {
lua_resume(L, null, 0)
}, sec * 1000)
return lua_yield(L, 0)
}
})
lua.lua_atnativeerror(L, L => {
console.log(lua.lua_touserdata(L, 1))
return 1
})
let execute = (code) => {
// Run script
lauxlib.luaL_loadstring(L, fengari.to_luastring(code))
lua_resume(L, null, 0)
}
process.on('message', data => {
data = data.toString()
if (data === 'stop') {
lua.lua_close(L)
return process.exit(0)
} else {
execute(data)
}
})
}
Do you have any advice on making this more efficient or just speeding it up in general?
I don't have any general advice to share here. This might be a better question for reddit or the lua mailing list?
How do I do error checking? Currently, it doesn't check for errors in Lua itself.
How do I do error checking? Currently, it doesn't check for errors in Lua itself.
lua_resume
returns an error code: do it the same as you would in normal lua.
Sorry, I'm fairly new to this type of thing. What would I do in normal Lua?
For example, say my script is:
print('Hello world'
That should error, but currently, all I get in the console is: TypeError: Cannot read property '4' of null
. How would I get a proper error?
How are you calling into lua? In your above example you use luaL_loadstring
followed by lua_resume
: have a look at their return values!
When everything is correct, they both return 0
, however when I do print('Hello world'
, luaL_loadstring
returns 3
and lua_resume
returns 2
. How can I extract useful information from this?
See https://www.lua.org/manual/5.3/manual.html#luaL_loadstring
This function returns the same results as lua_load.
The return values of lua_load are:
- LUA_OK: no errors;
- LUA_ERRSYNTAX: syntax error during precompilation;
- LUA_ERRMEM: memory allocation (out-of-memory) error;
- LUA_ERRGCMM: error while running a __gc metamethod. (This error has no relation with the chunk being loaded. It is generated by the garbage collector.)
What is the best way to extract a proper error message that I can print to the console, though?
The same way you do in normal lua.
Otherwise, it pushes an error message.
i.e. after you get a non LUA_OK
return value, the error value is on the stack. If it is a string (it might not be!) you could use lua_tostring(L, -1)
to get the string, then you probably want to convert it to a javascript string, and pop the error from the stack.
Okay, well I kind of have it working now. Here is my code:
if (ok !== lua.LUA_OK) {
console.log("Error: %s\n", lua.lua_tojsstring(L, -1))
lua_pop(L, 1)
}
When I run the same script as before, it outputs Error: attempt to call a string value
, but it should output something like [string "<eval>"]:1: ')' expected near '<eof>'
. How do I fix that?
My guess is you only checked the return of lua_resume, not luaL_loadfile (you should check both)
You have to check and act on it before doing the lua_resume
.
// process.send(`${lua.lua_tojsstring(L, -1)}`.red)
Why is that commented out? Perhaps that is why it doesn't output anything?
I fixed it, I miss that bit!
I have another small issue.
let ok2 = lua_resume(L, null, 0)
if (ok2 !== lua.LUA_OK) {
process.send(`${lua.lua_tojsstring(L, -1)}`.red)
lua_pop(L, -1)
return
}
For some reason, even though there aren't any errors in the code, it will output 1
as an error when running this code:
while true do
print('hi')
wait(1)
end
It fixed itself if I remove
if (ok2 !== lua.LUA_OK) {
process.send(`${lua.lua_tojsstring(L, -1)}`.red)
lua_pop(L, -1)
return
}
so I'm guessing thats whats causing it.
You should probably look at the implementation of your wait
function.