nazonoRubyist RubyでJavaScriptのためにC このページをアンテナに追加 RSSフィード

2006-06-26

JS_SetErrorReporter 14:44 JS_SetErrorReporter - nazonoRubyist RubyでJavaScriptのためにC を含むブックマーク はてなブックマーク - JS_SetErrorReporter - nazonoRubyist RubyでJavaScriptのためにC JS_SetErrorReporter - nazonoRubyist RubyでJavaScriptのためにC のブックマークコメント

エラーメッセージの取得である。

SpiderMonkeyにはJS_SetErrorReporterというAPIが用意されているので、これで設定するのだろう。

//エラーレポート
void
rb_smjs_context_errorhandle(
    JSContext *cx, 
    const char *message, 
    JSErrorReport *report){
  rb_raise(eJSEvalError,"%s:%d:%s", (report->filename ? report->filename : "NULL"), report->lineno, message );
}


static VALUE
rb_smjs_context_initialize(VALUE self){
  :
  // エラーレポーターを設定
  JS_SetErrorReporter(cs->cx, rb_smjs_context_errorhandle );
  
  return Qnil;
}

とりあえずこんな感じにしたところ、

irb(main):003:0> SpiderMonkey::eval(" hoge'")
SpiderMonkey::EvalError: [null]:1:SyntaxError: unterminated string literal
        from (irb):3:in `eval'
        from (irb):3

お、上手くエラーがつかめているようだ。今まではどこで何のエラーが出ているのかわからなかったのだ。上のエラーだと、1行目で SyntaxErrorが出ている、ということまでわかる。

本当ならSpiderMonkey::SyntaxError などを設定すべきだが、当面はこれで。エラーの種類のつかみ方がよくわからないのもある。


で、これで見たところ、WikiParserが動かないのは htmlescape という関数がない、ということのようだ。htmlescape だから多分

function htmlencode(txt){ 
  return txt.replace(/\&/g,'&amp;').replace(/\</g,'&lt;')
    .replace(/>/g,'&gt').replace(/"/g,'&quot;')
}

こんなかんじのはず。で、実行してみると動いた!感動


しかし、ErrorReporter から rb_raise しちゃっていいのだろうか?なんかよくない気がするなぁ…

(1)Ruby → (2)SpiderMonkey::eval → (3)JS_ScriptEvaluate → (4)Javascriptインタプリタ → (5)実行(複雑にスタック積んだり) → (6)エラー発生 → (7)rb_raise

すると、(7)からJavaScriptインタプリタ内での処理をすべて無視して (1)まで戻ってしまう… (7)では、エラー内容をラップしたJavaScriptの例外をthrowし、(3)でキャッチして処理が戻った後で rb_raise すべきだろう。しかしJavaScriptの例外をCで投げる方法・受ける方法がわからない上にエラーレポーターで投げていいのかどうかもわからないので、後回しに…

あ、そうか、受けられれば、投げるのはいらないんだ…でも受け方がわからないので後回し

トラックバック - http://rubyist.g.hatena.ne.jp/nazoking/20060626