Subj : Re: JS_AddRoot & finalize problem To : anton muhin From : Brendan Eich Date : Thu Jul 22 2004 01:22 pm anton muhin wrote: > Hello, dear gurus! > > I have the following problem that I still cannot solve after googling & > documentation reading. > > I want to store in private data a reference (intenationally vagous term) > to JS Array. Here the way I go: > > In construct object: > > JSObject * const a = JS_NewArrayObject(cx, nElements, elements); > > JSObject * * root = new (JSObject*)(a); > JS_AddRoot(cx, root); > > if (!JS_SetPrivate(cx, obj, root)) { > JS_RemoveRoot(cx, root); > return JS_FALSE; > } > > return JS_TRUE; > > In finalizer: > > JSObject * * root = (JSOBject**)JS_GetPrivate(cx, obj); > > JS_RemoveRoot(cx, root); > > delete root; > > However, in this case finalizer isn't get called!!! The GC root protects the array, and I bet you have a reference from an element in a (one of the jsvals in the |elements| vector in your code) that refers to |obj|, directly or indirectly. Instead of using a root *and* private data, you should simply store the array object, |a|, be a slot in the object. You don't need to allocate the private data slot, so remove JSCLASS_HAS_PRIVATE from your JSClass flags. Instead, add JSCLASS_HAS_RESERVED_SLOTS(1), and use JS_Get- and JS_SetReservedSlot with reserved slot index 0. Don't forget to use JSVAL_TO_OBJECT on Get and OBJECT_TO_JSVAL on Set. /be .