CからLua: Luaのコンパイル済みのコードを実行

CのプログラムからLuaバイトコードを実行してみます。
組み込みで使用する場合、組み込んだLuaに期待するのは実行環境のみという場合が多いのではないでしょうか。あらかじめコンパイルしたLuaバイトコードのファイルを作っておき、必要なファイルのみを読み込んで、組み込んだLuaに実行させる。そうすれば、パースやコンパイルに必要な時間と容量をカットできてうまうまです。
Luaはそういった使用を当然のごとく考慮してあるようで、luaL_loadbuffer()にバイトコードを直接渡せば実行できてしまいます。

// run_loaded_bytecode.c 
// メモリ上にロード済みのバイトコードを実行する
#include <stdio.h>

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

// "print([[Hello World!]]"のみが書かれたスクリプトファイルをバイトコードにしたデータ
const unsigned char loaded_bytecode[] = {
	0x1B, 0x4C, 0x75, 0x61, 0x51, 0x00, 0x01, 0x04, 0x04, 0x04, 0x08, 0x00, 0x0A, 0x00, 0x00, 0x00,
	0x40, 0x74, 0x65, 0x73, 0x74, 0x2E, 0x6C, 0x75, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x41, 0x40,
	0x00, 0x00, 0x1C, 0x40, 0x00, 0x01, 0x1E, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x06,
	0x00, 0x00, 0x00, 0x70, 0x72, 0x69, 0x6E, 0x74, 0x00, 0x04, 0x0D, 0x00, 0x00, 0x00, 0x48, 0x65,
	0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

int main()
{
	lua_State *L;
	
	// 開始処理
	L = lua_open();
	luaL_openlibs(L);
	// 実行するLuaスクリプトをロード
	if (luaL_loadbuffer(L, loaded_bytecode, sizeof(loaded_bytecode), "hello")) {
		fprintf(stderr, "luaL_loadbuffer()でエラー.\n");
		return -1;
	}
	// ロードされている関数を実行
	if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
		fprintf(stderr, "lua_pcall()でエラー.\n");
		return -1;
	}
	// 終了処理
	lua_close(L);

	return 0;
}

で、これをコンパイル&実行。実行時に指定したスクリプトを実行します。
(環境はmsysで、Luaのヘッダファイルへのインクルードパスが通っていること、liblua.aへのライブラリパスが通っていることを前提としてます)

~:$ gcc run_loaded_bytecode.c -llua
~:$ ./a.exe
Hello World!

できたできた。
ただ、できあがったファイルにはコンパイル用の関数なども含まれてしまっているので、完全に不要であれば、Luaのetcディレクトリにある"noparser.c"を参考にして不要なものをカットする必要があります。
また、Luaのバージョン5.1から、ネイティブのエンディアンバイトコードにしか対応しなくなったため注意が必要です。つまり、リトルエンディアンの環境で作ったバイトコードは、ビックエンディアンの環境のLuaでは実行できない。一般的なWindowsのPCで作ったバイトコードは、PS3, XBOX360, Wii, PSP, DSでは実行できないってことです。
とはいえ、そこはソースコードが完全に公開されているLuaですから、自分で対応してしまえば問題ありません。intのサイズが違うとかならめんどうそうですが、エンディアンの違い程度ならなんとでもなるはず。