以下のような感じで、うまく例外を補足できた。コメントアウトをはずすと、もっかい例外が飛んでく。
static int rua_proc_call(lua_State *L) { VALUE proc, args, retval; int i, n, status; proc = (VALUE) lua_touserdata(L, lua_upvalueindex(1)); args = rb_ary_new(); n = lua_gettop(L); for (i = 0; i < n; i++) { rb_ary_push(args, rua_torbval(L, i + 1)); } rb_ary_push(args, proc); retval = rb_protect(_rua_proc_call, args, &status); if (status != 0) { puts("大域脱出が起きた"); //rb_jump_tag(status); } rua_pushrbval(L, retval); return 1; } static int _rua_proc_call(VALUE args) { VALUE proc = rb_ary_pop(args); return rb_apply(proc, rb_intern("call"), args); }
で、例外をどうするか…
Luaの評価中に大域脱出していいのかどうかが気になる。
言語がサポートしていないみたいだし、ホスト側から例外のハンドラを渡せるようにして、握りつぶしてしまうのがいいかな?
そうすると処理に失敗したら、何でもかんでもnilを返すとか?
うーん…基本的に例外機構のない言語だと、処理の成否を常に返すのが一般的なのかな。