我正在将 Spidermonkey 嵌入到我的 C++ 应用程序中。我需要在本机 C++ 中实现一些传递 jsval 的自定义 Javascript 函数。我需要防止 jsval 被意外垃圾收集。我这样做是否合适:
(1) 在初始化例程中:
static jsval vp; // a STATIC variable, value unknown
JSBool init((JSContext *cx, uintN argc, jsval *vp) {
JS_AddValueRoot(cx, &vp);
}
(2) 在一个实现 Javascript 函数 setter() 的 C++ 函数中:
JSBool setter(JSContext *cx, uintN argc, jsval *vp) {
...
vp=...;// set to some JSObject and hopefully makes any previous JSObject available for gc
}
(3) 在同一编译单元内的第二个 C++ 函数调用中实现 Javascript 函数 getter():
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();
请注意,我从未调用 JS_RemoveRoot() ,因为静态 jsval 副总裁是我在两个函数调用之间传递的 jsval 的永久存储。而且,我不断在 setter() 中将新值设置到 gc 根静态变量 vp 中,假设存储在 jsval 中的任何先前的 JSObject 将可用于垃圾回收。
这些是创建可以跨函数调用传递的 gc root 临时变量的正确方法吗?特别是,我的 setter() 替换以前的 JSObject 的方式是使现有 JSObject 可用于 gc 的正确方法(即没有内存泄漏/崩溃)。
编辑:我认为垃圾收集是一个问题的原因是:
https://developer.mozilla.org/En/SpiderMonkey/JSAPI_User_Guide https://developer.mozilla.org/En/SpiderMonkey/JSAPI_User_Guide
在 JSAPI 概念、Javascript 值部分下:
jsval 本身并不能保护其所指对象免受垃圾的影响
集电极
https://developer.mozilla.org/en/SpiderMonkey_Garbage_Collection_Tips https://developer.mozilla.org/en/SpiderMonkey_Garbage_Collection_Tips
示例 3 表示“边走边扎根" 并展示了如何将 jsval 分配给根。