TryCatch のスコープではまること
V8 における文字列の評価処理は、だいたい次のような流れをとります。
const char* lpszScript = ...; HandleScope handle_scope; TryCatch try_catch; Local<Script> script = Script::Compile(String::New(lpszScript)); if (script.IsEmpty()) { ReportException(try_catch.Exception()); } else { Local<Value> result = script->Run(); if (result.IsEmpty()) { ReportException(try_catch.Exception()); } else { Print(result); } }
コマンド入力だったらこんなのでよいかもしれませんが、スクリプトをファイルから読み込ませるような関数を書いている場合、その場で ReportException を呼ぶより、外に例外を投げる方が設計上好ましいように思われます。とにかくそこからは例外で脱出して、インタプリタのトップレベルによって一度だけ例外を報告させることができるからです。
V8 でコールバックが例外を投げる場合は、ThrowException() という関数を使ってそのまま return するように求められていますが、上のコードをそのまま流用したりして、直感的にはだいたいこんな感じで書いてしまいがちです。
HandleScope handle_scope; TryCatch try_catch; Local<Script> script = Script::Compile(String::New(lpszScript)); if (script.IsEmpty()) { return ThrowException(try_catch.Exception()); } Local<Value> result = script->Run(); if (result.IsEmpty()) { return ThrowException(try_catch.Exception()); }
実はこれは正しく動きません。
続きを読むWeak handle にも Dispose の愛の手を
http://groups.google.com/group/v8-users/browse_thread/thread/d0c8bd822ce21f9e
http://d.hatena.ne.jp/tossy-2/20090123/1232653840
最近の v8-users のログを見たらちょうど話題にあがっていたので、ちょっとエントリ修正。
上記エントリでデストラクタの呼び出しを GC 任せにする手法が導入されていますが、weak handle にするために作った Persistent
ということで、正しくはコールバックを次のように書く必要があるそうです。
static void hoge_Destructor(v8::Persistent<v8::Value> handle, void* parameter) { delete static_cast<hoge*>(parameter); // ...など handle.Dispose(); // ここでハンドルを解放する }
V8 のバージョンがあがったようです
昨日コミットされた r1243 で、バージョン文字列が 1.0.0 になったようです。
ライブラリをビルドしなおして、テスト用のアプリのほうも…とおもったら winmm.lib (timeGetTime() のため)が追加ライブラリに入ってなくてこけたり。前はなんでリンク通ってたんだろう?
V8 向け ActiveXObject、なんとか動いた
というわけで、先日からごそごそとやっている V8 用 COM/OLE 対応コードですが、なんか別の URL を使ってみたら動きました。悲しすぎる。
要するにどういうものかというと、OLE オートメーションに対応しているオブジェクトを Javascript コードからオブジェクトとして触ることができます。逆に、Javascript オブジェクト(と関数)を dispatch interface として COM 側からアクセスすることができるようになります。
まだ JS オブジェクトの export の動作検証や ITypeInfo 関係のコードなどは書いていないのですが、相手が動的言語のオブジェクトなのである程度手抜きしてもいい…のかなあ。
ActiveXObject with V8 (続き)
Locale の問題とかいろいろ修正していたら、なんとなく動くようになった気がしますが、よくわからないエラーが出ているのでまだまだのようです。。。
> var o = new ActiveXObject('Msxml2.XMLHTTP') > o [ActiveXObject@021D3A68] > o.open function open() { [native code] } > o.open('GET', 'http://www.google.com/', false) > o.readyState 1 > o.send() Error: アクセスが拒否されました。 > o.readyState 4 > o.status 0 > o.statusText Unknown
コールバックもできるよ!
> o.abort() > o.readyState 0 > o.onreadystatechange = function() { print('readyState = ' + o.readyState) } function () { print('readyState = ' + o.readyState) } > o.open('GET', 'http://www.google.com/', false) [readyState = 1] > o.send() [readyState = 1] [readyState = 4] Error: アクセスが拒否されました。
非同期モードはまだ動かないようです。