ActiveScript Engine初期化の試行錯誤

うごかないスクリプトエンジンが諦められないので、テストプログラム用意してがんばってみた.
まず、PythonScriptが吹っ飛ぶ原因を探ってみたところ、なんとGetTypeInfoでAddRefしてないのが原因だった.そりゃ吹っ飛んでも仕方ない.ひどい濡れ衣だったねPythonScript・・・
SetScriptSiteで死亡する現象は、PythonScriptに初期化手順の依存性があることが分かった.
スクリプトエンジンを生成したあと、パーザのInitNewを呼び出すまでSCRIPTSTATE_STARTED設定ではなく、SCRIPTSTATE_INITIALIZED設定か何もしないのがポイント.InitNewより後にSCRIPTSTATE_STARTED(接続するオブジェクトがある場合はSCRIPTSTATE_CONNECTED)に切り替えてスクリプトを読み込む.これで上手く動作してくれた.
次はPHPScript.参照が上手くいかない原因はInitNewにあった.InitNewより前にAddNamedItemしても,InitNewが初期化を担っていて,登録されたアイテムを消去してしまうらしい.順序を入れ換えて,InitNewよりあとでアイテムを登録するようにしたら,ちゃんと認識してくれた.
RubyScriptで,SCRIPTSTATE_INITIALIZED・SCRIPTSTATE_STARTED以外のステートでアイテムが登録されない仕様は既に把握しているので,これら全てに上手く対応する初期化手順は多分こんな感じになると思われる.

  1. スクリプトエンジンを生成
  2. スクリプトエンジンにスクリプトサイトを登録
  3. スクリプトエンジンからパーザを取得
  4. (SCRIPTSTATE_INITIALIZEDに設定)
  5. ActiveScriptParser::InitNewでパーザを初期化
  6. SCRIPTSTATE_INITIALIZED・SCRIPTSTATE_STARTEDに設定
  7. 名前付きアイテムを登録
  8. (SCRIPTSTATE_STARTED・SCRIPTSTATE_CONNECTEDに設定)
  9. パーザにスクリプトを食べさせる

InitNewやスクリプト投入前後のステート設定は入れ替わっても構わない.
ただ,これらはテストプログラム上での動作なので,LimeChatに組み込んだ場合,どうなるのかはまだ試していない.LimeChatの初期化シーケンスはこれに従っているわけがないので,先日書いた初期化シーケンス再生は使えない.記録するのは名前付きアイテムだけで,後は独自の初期化シーケンスを実行する必要がありそうだ.
あと,RubyScript(ActiveScriptRuby)のソースコードを精査してて分かったこと.
CRScriptCore::GetScriptDispatchと言うメソッドの実装が,投げられた名前がグローバルメンバ(グローバルメンバ名として登録されている名前か,もしくは名前がNULLい)ならstd::mapからディスパッチャを拾う風になっているんだけど,VC++8だとstd::map::findにNULL食わせるとクラッシュするんだよね.GetOuterDispatchする前までを,NULLじゃないという条件分岐で囲うことで上手く動くようになるらしい.

その後

やっぱり動かない。PHPScriptはメッセージパッシングで通信してるみたいだけどそこで上手くいってないとか,PythonScriptはリリース版だと何故かSetScriptSiteのディスパッチに失敗するとか,とにかく訳が分からないことになってた.一体何が悪さしてるのかさっぱり分からない・・・