C++アプリケーションにSpidermonkeyを埋め込んでいます。jsvalを渡すネイティブC++でいくつかのカスタムJavascript関数を実装する必要があります。偶発的なガベージコレクションからjsvalを保護する必要があります。私がこれを行うのは適切ですか?
(1)initルーチンの場合:
static jsval vp; // a STATIC variable, value unknown
JSBool init((JSContext *cx, uintN argc, jsval *vp) {
JS_AddValueRoot(cx, &vp);
}
(2)Javascript関数setter()を実装する1つのc ++関数で:
JSBool setter(JSContext *cx, uintN argc, jsval *vp) {
...
vp=...;// set to some JSObject and hopefully makes any previous JSObject available for gc
}
(3)Javascript関数getter()を実装する同じコンパイルユニット内の2番目のC++関数呼び出しで:
JSBool getter(JSContext *cx, uintN argc, jsval *vp) {
jsval somethingelse = vp; //directly retrieve the static value stored by setter()
....
}
私のJavascriptスクリプトは、次のような関数呼び出しを使用します。
init();
setter(...);
some_other_function_call_that_causes_gc();
getter();
setter(...);
some_other_function_call_that_causes_gc();
getter();
....
some_other_function_call_that_causes_gc();
setter(...);
some_other_function_call_that_causes_gc();
getter();
静的jsvalvpは、2つの関数呼び出しの間に渡されるjsvalの永続的なストレージであるため、JS_RemoveRoot()を呼び出さないことに注意してください。そして、jsvalに格納されている以前のJSObjectがガベージコレクションに使用できると仮定して、setter()のgcルート静的変数vpに新しい値を設定し続けます。
関数呼び出しを介して渡すことができるgcルートの一時変数を作成するこれらの適切な方法はありますか?特に、setter()が以前のJSObjectを置き換える方法は、既存のJSObjectをgcで使用できるようにする(つまり、メモリリーク/クラッシュが発生しない)ための適切な方法です。
編集:ガベージコレクションが問題であると私が信じる理由は次のとおりです:
https://developer.mozilla.org/En/SpiderMonkey/JSAPI_User_Guide
セクションJSAPIの概念、Javascriptの値:
jsval自体は、ガベージコレクタからその指示対象を保護しません
https://developer.mozilla.org/en/SpiderMonkey_Garbage_Collection_Tips
例3は、「ルートを進むにつれて」と言い、jsvalをルートに割り当てる方法を示しています。