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

2006-06-29

細かい変更 14:51 細かい変更 - nazonoRubyist RubyでJavaScriptのためにC を含むブックマーク はてなブックマーク - 細かい変更 - nazonoRubyist RubyでJavaScriptのためにC 細かい変更 - nazonoRubyist RubyでJavaScriptのためにC のブックマークコメント

やっぱり気持ち悪かったので、JS_EvaluateScriptを呼び出す部分を Value#new からContext#eval に移した。

// jsval から SpiderMonkey::Value を作成
VALUE
rb_smjs_value_new_jsval(VALUE context, jsval value){
  VALUE retval;
  retval = rb_funcall(cJSValue, rb_intern("new"), 1, context );
  rb_smjs_value_set_jsval( retval, value );

  return retval;
}

// code を実行し、SpiderMonkey::Valueオブジェクトを返す
VALUE
rb_smjs_context_eval(VALUE self, VALUE code){
  sSMJS_Context *cs;
  Data_Get_Struct(self, sSMJS_Context, cs);

  SafeStringValue(code);
  char *source = StringValuePtr(code);

  jsval value;
  char *filename = "[null]";
  uintN lineno = 1;
  JSBool ok = JS_EvaluateScript( cs->cx, cs->globalObj, source, strlen(source),
      filename, lineno, &value);
  if (!ok) rb_smjs_raise_ruby( cs->cx );
  
  // Rubyでラップしたオブジェクトを返す
  return rb_smjs_value_new_jsval( self, value );
}

rb_smjs_raise_rubyは、「Rubyコールバック関数が呼ばれたときに発生した最後の例外値の処理」の関数で、機能説明を省いたところだが、こうなっている。

// 最後に発生したエラーの情報 
struct sSMJS_Error{
  char msg[BUFSIZ];
  int status;
  JSErrorReport report;
}SMJS_LastError;

void
rb_smjs_raise_ruby( JSContext *cx ){
  if( SMJS_LastError.status != 0 ){
    int stat = SMJS_LastError.status;
    SMJS_LastError.status = 0;
    rb_jump_tag( stat );
  }else{
    char msg[BUFSIZ];
    snprintf(msg,BUFSIZ,"%s:%d:%s",
        (SMJS_LastError.report.filename ? SMJS_LastError.report.filename : "NULL"),
        SMJS_LastError.report.lineno, 
        SMJS_LastError.msg );
    rb_raise(eJSEvalError, msg );
  }
}

これを見るとわかるかと思うが、以前やったエラーメッセージの取得も、変更した。以前はerrorreporter の中で rb_raise していたが、今回の変更で SMJS_LastError.msg と SMJS_LastEr

ror.report に内容をセットするだけにして、実際に rb_raise するのは rb_smjs_raise_ruby の中だけにした。

SpiderMonkey::eval("{x:1,y:2}")がエラーになる 14:51  SpiderMonkey::eval("{x:1,y:2}")がエラーになる - nazonoRubyist RubyでJavaScriptのためにC を含むブックマーク はてなブックマーク -  SpiderMonkey::eval("{x:1,y:2}")がエラーになる - nazonoRubyist RubyでJavaScriptのためにC  SpiderMonkey::eval("{x:1,y:2}")がエラーになる - nazonoRubyist RubyでJavaScriptのためにC のブックマークコメント

http://rubyist.g.hatena.ne.jp/nazoking/20060617#1150564493

これもなぜか x= の部分がないと値が帰ってこないのだが…

これって、SpiderMonkey 1.5 だとブロック構文とラベル(識別子)だと思われているみたい。ジャヴァスクリプターには忘れられがちだけれどJavaScriptにはラベルというものがあって

http://www.tohoho-web.com/js/statement.htm#stLabel

label1:
  for (i = 0; i < 10; i++) {
      for (j = 0; j < 10; j++) {
          if (func(i, j) {
              break label1;
          }
      }
  }

こんな感じでネストしたループから一気に抜けるために用意されている。これと間違われているのだ。だから、

js> {x:1, y:2}
typein:1: SyntaxError: invalid label:
typein:1: {x:1, y:2}
typein:1: .......^

あははー。Ruby/SpiderMonkey のようなもので使う場合は面倒な仕様だなぁ…

mal_bluemal_blue2006/07/03 04:01({x:1,y:2}) とカッコをつければオブジェクトが返りますよ。

nazokingnazoking2006/07/03 04:46をを!これは盲点でした

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