Atoms refactor
This gets rid of the gjs_context_get_const_string()
function (which returns a jsid
of an interned string, e.g. "name"
, given an enum value such as GJS_STRING_NAME
). It replaces it with a GjsAtoms
C++ class, which is owned by the context. GjsContextPrivate
is now made into a C++ class in order to accommodate this.
The reason we had this was because the following straightforward way of reading a JS property, let's say foo.name
JS_GetProperty(cx, foo, "name", &value)
is slow because the string "name"
has to be converted into a jsid
(which is a sort of property key that can hold either a string or an integer index). So instead we had this:
JS_GetPropertyById(cx, foo, gjs_context_get_const_string(cx, GJS_STRING_NAME), &value)
or the following convenience function as a shorthand:
gjs_object_get_property(cx, foo, GJS_STRING_NAME, &value)
And all the "const strings" (or "atoms", in SpiderMonkey terminology) were created at startup time and stored in JS::PersistentRooted
containers to protect them from garbage collection.
Now we can do this:
gjs_object_get_property(cx, foo, atoms.name(), &value);
There are two purposes of this refactor:
-
Decouple code so that the
gjs/jsapi-*.cpp
files are less dependent onGjsContext
. We want this because of #194 (closed), where we should try to link the unit tests with thegjs/jsapi-*.cpp
files directly, so that we can keep those private symbols private, while not pulling inGjsContext
. These files still depend ongjs/context-private.h
, but the idea is that we can later rewrite those functions so that you pass in aGjsAtoms&
instead of fetching the one from the context, which I'll do in a follow-up refactor. -
When I talked to the SpiderMonkey dev team they said that we should generally avoid
JS::PersistentRooted
, since it uses relatively a lot of memory. Having a class that gets traced directly by the garbage collector is less resource-intensive.