Compiled Lua scripts are pretty much the source bytecode dumped after the short header. The header documents some of the platform properties used to compile the bytecode, but the loader only verifies that the current platform has the same properties.
Unfortunately, this creates problems when loading bytecode compiled on another platform, even if it was compiled with the same version of Lua. Of course, scripts compiled by different versions of Lua cannot work, and since the Lua version number is included in the bytecode header, an attempt to load them will catch the kernel.
The simple answer is simply compiling the scripts. If Lua compiles the script itself, you only need to worry about possible version mismatches between the Lua kernels in your different builds of your application, and it's not difficult.
In fact, support for full cross-compatibility for compiled bytecode is not easy . In this letter, Mike Pall identified the following issues:
Endianess: swap output as needed.
sizeof(size_t) , affects huge string constants: check overflow when downgrading.
sizeof(int) , affects MAXARG_Bx and MAXARG_sBx : check for overflow when downgrading.
typeof(lua_Number) : easy in C, but only when the host and target adhere to the same FP standard; accuracy loss during updating (rare case); warn about non-integer numbers when downgrading to int32 .
From all the discussions I've seen about this issue on the mailing list, I see two possible viable approaches, assuming you don't want to consider sending unrelated Lua scripts.
The first will be the correction of the byte order when loading compiled scripts. This turns out to be simpler than you expected, since it can be done by replacing the low-level function that reads the script file without recompiling the kernel itself. In fact, this can even be done in pure Lua by providing the chunk reader the lua_load () function. This should work as long as the only compatibility issue with your platforms is the byte order.
Secondly, to fix the kernel itself, use the general view for compiled scripts on all platforms. This is described as possible by Luiz Henrique de Figueiredo :
.... I am convinced that the best way is to order bytes or cross-compile third-party dump / chain pairs. the ldump.c and lundump.c files are completely replaceable; they export a single, well-defined, entry point. the format of precompiled pieces is not sacred at all; you can use any format as long as ldump.c and lundump.c agree on this. (For example, Lake Richie's consideration of writing a text format for precompiled chunks.) ....
Personally, I would recommend taking seriously not to pre-compile scripts and, thus, completely avoid problems with platform portability.
Edit: I updated the bytecode header description thanks to lhf comments. I have not read this part of the Lua source yet, and I probably should have checked it before I was pretty sure what information is in the header or not.
Here is a fragment of lundump.c , which forms a copy of the header corresponding to the working platform, for comparison with the loaded bytecode. It is simply compared to memcmp() to exactly match the file header, so any mismatch causes the loader ( luaU_undump() ) to reject the file.
void luaU_header (char* h) { int x=1; memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); h+=sizeof(LUA_SIGNATURE)-1; *h++=(char)LUAC_VERSION; *h++=(char)LUAC_FORMAT; *h++=(char)*(char*)&x; *h++=(char)sizeof(int); *h++=(char)sizeof(size_t); *h++=(char)sizeof(Instruction); *h++=(char)sizeof(lua_Number); *h++=(char)(((lua_Number)0.5)==0); }
As you can see, the header is 12 bytes long and contains a signature (4 bytes, " <esc>Lua "), version and format codes, a byte flag for judging, sizes of int , size_t , Instruction and lua_Number and a flag indicating whether lua_Number integral type.
This allows most of the differences in the platform to be caught, but does not try to catch every way that the platforms can differ.
I still adhere to the recommendations made above: firstly, ship compiled sources; or second, configure ldump.c and lundump.c to save and load the common format, with the additional note that any custom format should override the LUAC_FORMAT byte of the header so as not to be confused with the stock byte code format.