Compile Lua Code, Store Bytecode Then Load and Execute It

Compile lua code, store bytecode then load and execute it

This is all very simple.

First, you load the Lua script without executing it. It does not matter if you have connected the Lua state with your exported functions; all you're doing is compiling the script file.

You could use luaL_loadfile, which uses C-standard library functions to read a file from disk and load it into the lua_State. Alternatively, you can load the file yourself into a string and use luaL_loadstring to load it into the lua_State.

Both of these functions will emit return values and compiler errors as per the documentation for lua_load.

If the compilation was successful, the lua_State now has the compiled Lua chunk as a Lua function at the top of the stack. To get the compiled binary, you must use the lua_dump function. It's rather complicated as it uses a callback interface to pass you data. See the documentation for details.

After that process, you have the compiled Lua byte code. Shove that into a file of your choice. Just remember: write it as binary, not with text translation.

When it comes time to load the byte code, all you need to do is... exactly what you did before. Well, almost. Lua has heuristics to detect that a "string" it is given is a Lua source string or byte code. So yes, you can load byte code with luaL_loadfile just like before.

The difference is that you can't use luaL_loadstring with byte code. That function expects a NULL-terminated string, which is bad. Byte code can have embedded NULL characters in it, which would screw everything up. So if you want to do the file IO yourself (because you're using a special filesystem or something), you have to use lua_load directly (or luaL_loadbuffer). Which also uses a callback interface like lua_dump. So read up on how to use it.

Keeping everything in a single lua bytecode chunk?

You can combine multiple files into a single file using luac. When run, all the chunks from the source files are executed in the order they were added to the compiled file:

$ echo "x=1"         > l1.lua
$ echo "y=2" > l2.lua
$ echo "print(x, y)" > l3.lua
$ luac -o run.luac l1.lua l2.lua l3.lua
$ lua run.luac
1 2

You can load this file into Lua from C using luaL_loadfile, which places a function on the top of the stack if it loaded succesfully. Then you can just run this function using lua_call to run all the combined compiled files.

Note that you can embed the contents of the compiled file as a string into your project, no need to keep it in external file.

Update for LuaJIT 2

As you have found, you can use the Lua Compiler in Lua to get a combined file which can be loaded as previously noted. This is a simplified version, which outputs to stdout:

-- http://lua-users.org/wiki/LuaCompilerInLua
-- compile the input file(s) passed as arguments and output them combined to stdout
local chunk = {}
for _, file in ipairs(arg) do
chunk[#chunk + 1] = assert(loadfile(file))
end
if #chunk == 1 then
chunk = chunk[1]
else
-- combine multiple input files into a single chunk
for i, func in ipairs(chunk) do
chunk[i] = ("loadstring%q(...);"):format(string.dump(func))
end
chunk = assert(loadstring(table.concat(chunk)))
end
io.write(string.dump(chunk))

For the previous sample, you can use it as follows:

$ luajit combine.lua l1.lua l2.lua l3.lua > out.ljc
$ luajit out.ljc
1 2

How can I load and execute a lua file from within another lua file

dofile "mytables.lua"

How to compile *.lua files as resource library?

I wouldn't use Lua if you've got code to hide (as it's always possible to decompile it), but you could simply do the following:

  • Compile the script files using luac. This will give you output files with precompiled object code (not machine code) in them. (This step is optional but it makes it harder to read/find the actual code in the compiled file.)
  • Write a simply tool to read those files putting them into character arrays.

The resulting code should look a bit like this:

const char firstlua_lua[] = {0x11,0x12,0x13,0x14,...};

It will use the actual bytes found in the compile lua script obviously.
You'll then be able to simply run these "strings" like any script source loaded.

compiling a c and lua program into a single executable

I thing the easiest way would be to store you program a string and then use the luaL_dostring() function to execute it.

I did not check but I'm pretty sure you can compile the Lua code with luac and store it in a char [] buffer instead of storing the script source code.
This will speed up things a bit by doing the compilation of the source code to Lua VM bytecode once for all at compile time (rather than at runtime).

Something like:

const char *luacode = "print('Hello')";
lua_State *L;
...
...

luaL_dostring (L, luacode);


Related Topics



Leave a reply



Submit