やったことだけ書く備忘録

[続々] LuaをWebAssemblyにコンパイルして実行する話

(続きの続き) LuaでもWebAssemblyがしたかった




前回の続きです。



実行速度を改善した



前回では関数をコールするたびにlua_Stateを生成していたのですが、初期化段階でlua_Stateを生成してスクリプト本体を読み込み、関数内ではそのstateを参照しつつ実行することで実行速度が現実的なレベルになりました。具体的には、




EMSCRIPTEN_KEEPALIVE
const charhello_world() {
    
// Create new state
    
lua_StateluaL_newstate();
    
// load compiled program
    
boot_lua(L);

    
// Call Lua function
    
lua_pcall(L);
    ...
    
// close
    
lua_close(L);
}
 


と関数毎にやっていたのを、




// global state
static lua_Statewasm_lua_state NULL;

EMSCRIPTEN_KEEPALIVE
const charhello_world() {
    
// Call Lua function
    
lua_pcall(wasm_lua_state);
}

int main(void) {
    
// Create new state at global
    
wasm_lua_state luaL_newstate();
    
// load compiled program
    
boot_lua(wasm_lua_state);
    return 
0;
}
 


としました。main()はWASMがコンパイルされるタイミングで実行されるようなので、ここで初期化して使い回すことで関数のコールは劇的に速くなりました。まぁ当たり前といえば当たり前でしょうけど…。

グローバル変数は良い作法ではないと思ってますが、.cファイル自体が自動生成なのでとりあえず他からCのロジックが入る余地はなさそうで、また関数の終了時にlua_settop(wasm_lua_state, 0)としてstackを必ずクリアしているので問題なさそう(あったら教えてください)

あとlua_close()をする場所がなかったので記述していないですが、WASMってブラウザがnavigationした時に解放するんですかね。ちょっとよくわかってないです。

現場からは以上です。

« 前の記事