ActiveScriptingホストの良くわからない動作2chで見たのだが、ASR(というパッケージではなく、ActiveScriptRuby=RScript18.dllのこと)が以下のHTAの実行に失敗し、結果的にスタックオーバーフローで死ぬ。alert('j');</script></head><body></body></html>ActiveScriptingのホスト(この場合、MSHTA)は、スクリプトが利用するホスト側オブジェクトをIActiveScript::AddNamedItemメソッドを呼び出して登録する。MSHTAの場合は、windowがそれに当たる。ASRは、この呼び出しを受けると、IActiveScriptSite::GetItemInfoメソッドを呼び出して、必要な情報を得て、Rubyのスクリプトがwindowオブジェクトを操作できるようにする。この時、スクリプトからのアクセス用にWindow、@windowの2種類の変数を用意する。それに加えて、ある時点から、JScript同様にグローバルなオブジェクト(AddNamedItemメソッド呼び出し時にSCRIPTITEM_GLOBALMEMBERSフラグが指定される)については、直接スクリプトが記述できるように(あたかもmainオブジェクトのprivateメソッドのように)登録しておく。ここでの問題とは直接関係しないが、イベントを通知するための仕組みは、ホストに対してIDispatch*を与えることで実現している。HTML要素にonclick属性を指定すると、ホストは、IActiveScriptParseProcedure::ParseProcedureTextメソッドを呼び出し、スクリプトのパース結果をCOMの呼び出し可能なオブジェクトとして要求する。onclick="alert('hello')">と書くと、alert('hello')を実行するIDispatch*をActiveScriptは生成し、それをホストへ与える。ホストはイベントを通知したくなると、該当IDispatch*のデフォルトメンバをInvokeする。ASRはこれをProcオブジェクトとして実装している。本題に戻ると、おそらく、スクリプト側での拡張を認めるためだと思うが、ホストは、AddNamedItemメソッドで設定したオブジェクトについても、IActiveScript::GetScriptDispatchメソッドを呼び出し、ActiveScript側のオブジェクトのIDispatch*を取りに来る。このとき、RubyScriptのみがMSHTAのスクリプトとして実行されていると、以下の動きとなる。windowオブジェクト用のWin32OLEオブジェクトを作成する。上記オブジェクトに保持したIDispacthEx*をホストへ返す。ASRは、この処理を、最初、以下のように実装していた。windowオブジェクト用のWin32OLEオブジェクトを作成する。指定されたRubyのオブジェクト(ホストのオブジェクトは想定外)がなければテンポラリなオブジェクトを生成し、そのIDispatch*を返す。そのため、最初Ruby側のオブジェクトを探し、次に、IActiveScriptSite::GetItemInfoを呼び出してホスト側オブジェクトを探すMSHTA上にRScriptのみしか存在しなければ、ホストはGetItemInfoに対して自分が保持する(この場合であれば)windowのIDispatchEx*を返すので、そこで終了する。ところが、JScriptが共存すると、話が異なる。ホストはJScriptに対してAddNamedItemを呼ぶ。JScriptはGetItemInfoを呼ぶ。ホストは拡張している可能性からASRのGetScriptDisaptchを呼ぶ。ASRは、上記のテンポラリオブジェクトのためにGetItemInfoを呼ぶ。ホストは拡張している可能性からASRのGetScriptDispatchを呼ぶ。ASRは、上記のテンポラリオブジェクトのために......スタックオーバーフローする。結局、ホスト側のオブジェクトとしてすでに登録されていれば、そのIDispatchEx*をGetScriptDisaptchの結果として返すことで、このループを回避できる。いう修正をしたASRを作った。msiは、たぶん、1.8.7の次期パッチ版がもうすぐリリースされると思うのでその時作ることにして、とりあえず、RScript18.dllのみのzipをダウンロードページに置いた。1.9.1の予定ASRは一応、完成した(ソース)。soleb.rbを実行すると、うまく行かない。Swinにもう少し修正が必要なようだ。(Encoding::UndefinedConversionError)となる。これはこれとして、ASRのサンプルとしての意味もあるのでsolebの真似をHTAで作ったholebというのを作ることにした。その過程で、スレッドピンポンでinstance_evalすることになったりしたのであった。これが終わったらリリースするのだが、最近、昼の仕事が忙しいのであった。