От: | Evgeny.Panasyuk | ||
Дата: | 09.03.16 01:35 | ||
Оценка: |
Вот релевантный код — там например строится интрузивный стек из Rooted.All GC thing pointers stored on the stack (i.e., local variables and parameters to functions) must use the JS::Rooted<T> class.
...
SpiderMonkey makes it easy to remember to use JS::Rooted<T> types instead of a raw pointer because all of the API methods that may GC take a JS::Handle<T>, as described below.
...
All GC thing pointers that are parameters to a function must be wrapped in JS::Handle<T>. A JS::Handle<T> is a reference to a JS::Rooted<T>. All JS::Handle<T> are created implicitly by referencing a JS::Rooted<T>: It is not valid to create a JS::Handle<T> manually. Like JS::Rooted<T>, a JS::Handle<T> can be used as if it were the underlying pointer.
Since only a JS::Rooted<T> will cast to a JS::Handle<T>, the compiler will enforce correct rooting of any parameters passed to a function that may trigger GC. JS::Handle<T> exists because creating and destroying a JS::Rooted<T> is not free (though it only costs a few cycles). Thus, it makes more sense to only root the GC thing once and reuse it through an indirect reference. Like a reference, a JS::Handle is immutable: it can only ever refer to the JS::Rooted<T> that it was created for.