After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 777962 - Switch to SpiderMonkey 38
Switch to SpiderMonkey 38
Status: RESOLVED FIXED
Product: gjs
Classification: Bindings
Component: general
1.47.x
Other All
: Normal enhancement
: ---
Assigned To: Philip Chimento
gjs-maint
Depends on: 776966
Blocks: 778639 778641
 
 
Reported: 2017-01-31 01:22 UTC by Philip Chimento
Modified: 2017-02-15 04:06 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
build: Build with mozjs38 (1.54 KB, patch)
2017-01-31 01:24 UTC, Philip Chimento
committed Details | Review
docs: Overview of new JS features in NEWS (3.88 KB, patch)
2017-01-31 01:24 UTC, Philip Chimento
committed Details | Review
js: AutoValueVector's [] operator is rooted (7.44 KB, patch)
2017-01-31 01:24 UTC, Philip Chimento
committed Details | Review
js: Adapt to new JS_NewObject() API (20.50 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Adapt to new JS_DefinePropertyById() API (6.88 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Rename JS_CallHeapFooTracer() (3.90 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Discontinue JSClass stubs (13.56 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Adapt to new JS_SetErrorReporter() API (2.57 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
constructor-proxy: Adapt to new js::DirectProxyHandler API (2.67 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
runtime: Adapt to new JSFinalizeCallback (1.69 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Adapt to new mozilla::Maybe API (6.22 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Adapt to new signature of resolve operation (38.59 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
none Details | Review
js: Accommodate both Latin-1 and two-byte strings (13.28 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
none Details | Review
js: JSNative accessors in JS_DefineProperty() (4.13 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Fix misc APIs for mozjs38 (1.57 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
committed Details | Review
js: Various SpiderMonkey 38 improvements (3.19 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
none Details | Review
WIP - object: Update weak pointers after GC (7.88 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
none Details | Review
WIP - importer: Switch to eager enumeration (12.23 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
none Details | Review
WIP - importer: Switch back to lazy enumeration (7.33 KB, patch)
2017-01-31 01:25 UTC, Philip Chimento
none Details | Review
js: Various SpiderMonkey 38 improvements (3.94 KB, patch)
2017-02-06 06:18 UTC, Philip Chimento
committed Details | Review
jsapi-util-root: Re-enable test (1.17 KB, patch)
2017-02-11 06:07 UTC, Philip Chimento
committed Details | Review
WIP - js: Update weak pointers after GC (10.18 KB, patch)
2017-02-13 23:36 UTC, Philip Chimento
none Details | Review
WIP - importer: Switch to eager enumeration (12.76 KB, patch)
2017-02-13 23:36 UTC, Philip Chimento
none Details | Review
WIP - importer: Switch back to lazy enumeration (7.33 KB, patch)
2017-02-13 23:37 UTC, Philip Chimento
none Details | Review
js: Adapt to new signature of resolve operation (38.97 KB, patch)
2017-02-14 01:30 UTC, Philip Chimento
committed Details | Review
js: Accommodate both Latin-1 and two-byte strings (13.24 KB, patch)
2017-02-14 01:30 UTC, Philip Chimento
committed Details | Review
WIP - js: Update weak pointers after GC (10.28 KB, patch)
2017-02-14 01:58 UTC, Philip Chimento
committed Details | Review
WIP - importer: Switch to eager enumeration (12.78 KB, patch)
2017-02-14 01:58 UTC, Philip Chimento
committed Details | Review
WIP - importer: Switch back to lazy enumeration (7.89 KB, patch)
2017-02-14 01:58 UTC, Philip Chimento
committed Details | Review

Description Philip Chimento 2017-01-31 01:22:37 UTC
This bug will hold all the patches that can only be committed all at once, after the switch.
Comment 1 Philip Chimento 2017-01-31 01:24:44 UTC
Created attachment 344601 [details] [review]
build: Build with mozjs38

Requires updating our includes. The function used from OldDebugAPI.h was
simply moved into jsapi.h, and some functions were separated out into
js/Conversions.h.
Comment 2 Philip Chimento 2017-01-31 01:24:47 UTC
Created attachment 344602 [details] [review]
docs: Overview of new JS features in NEWS

Distilled from SpiderMonkey's documentation.
Comment 3 Philip Chimento 2017-01-31 01:24:50 UTC
Created attachment 344603 [details] [review]
js: AutoValueVector's [] operator is rooted

Previously, the [] operator of JS::AutoValueVector would give you a raw
pointer, and if you wanted a rooted value you had to call the handleAt()
method. In SpiderMonkey 38, that method is removed, and the [] operator
gives you a rooted value.
Comment 4 Philip Chimento 2017-01-31 01:25:00 UTC
Created attachment 344604 [details] [review]
js: Adapt to new JS_NewObject() API

JS_NewObject() does not take a prototype parameter anymore, that has been
split into a different function, JS_NewObjectWithGivenProto(). Passing
JS::NullPtr() as prototype means "Look in the global object for a
prototype that matches the given class" and that is now the only possible
behaviour for JS_NewObject().

Both JS_NewObject() and JS_NewObjectWithGivenProto() have had their
global object parameter made optional, so in the cases where we were
passing JS::NullPtr() there, then we simply leave it out.
Comment 5 Philip Chimento 2017-01-31 01:25:03 UTC
Created attachment 344605 [details] [review]
js: Adapt to new JS_DefinePropertyById() API

Like JS_DefineProperty() could already, JS_DefinePropertyById() is now
overloaded to take several types as the property value. This allows us to
pass rooted objects directly in, in order to avoid creating temporary
JS::Values.
Comment 6 Philip Chimento 2017-01-31 01:25:07 UTC
Created attachment 344606 [details] [review]
js: Rename JS_CallHeapFooTracer()

The various flavours of JS_CallHeapFooTracer() are now called
JS_CallFooTracer() in SpiderMonkey 38.
Comment 7 Philip Chimento 2017-01-31 01:25:11 UTC
Created attachment 344607 [details] [review]
js: Discontinue JSClass stubs

JSClass now simply takes NULL to indicate that an operation should
default to a stub function.
Comment 8 Philip Chimento 2017-01-31 01:25:15 UTC
Created attachment 344608 [details] [review]
js: Adapt to new JS_SetErrorReporter() API

JS_SetErrorReporter() now acts on a JSRuntime, not a JSContext.
(JSRuntime and JSContext will be merged in a future version of
SpiderMonkey anyway.)
Comment 9 Philip Chimento 2017-01-31 01:25:18 UTC
Created attachment 344609 [details] [review]
constructor-proxy: Adapt to new js::DirectProxyHandler API

Callability is no longer indicated with the bizarre setDefaultClass()
method, but instead by overriding the isCallable() and isConstructor()
methods; and some signatures have changed.
Comment 10 Philip Chimento 2017-01-31 01:25:22 UTC
Created attachment 344610 [details] [review]
runtime: Adapt to new JSFinalizeCallback

JSFinalizeCallback now allows a user-data parameter, so we can get rid of
some fiddling with runtime private data.
Comment 11 Philip Chimento 2017-01-31 01:25:26 UTC
Created attachment 344611 [details] [review]
js: Adapt to new mozilla::Maybe API

mozilla::Maybe now has a bool operator so we don't have to compare against
.empty(), and we can construct values with mozilla::Some(). The API is
still fairly verbose and will be improved even further in later
SpiderMonkey releases.
Comment 12 Philip Chimento 2017-01-31 01:25:30 UTC
Created attachment 344612 [details] [review]
js: Adapt to new signature of resolve operation

JSNewResolveOp and JSResolveOp are merged in SpiderMonkey 38. There is
only one signature, so no need to distinguish the two with the
JSCLASS_NEW_RESOLVE flag.

Converting from the old JSNewResolveOp callback to the new JSResolveOp
callback is a matter of making sure that *resolved is set whenever the
callback returns true. (The equivalent of *resolved = true before this
change was objp.set(obj) on the passed-in MutableHandleObject.)
Comment 13 Philip Chimento 2017-01-31 01:25:34 UTC
Created attachment 344613 [details] [review]
js: Accommodate both Latin-1 and two-byte strings

Starting with SpiderMonkey 38, strings can be stored internally in the
JS engine as either Latin-1 or two bytes per character (sort-of-UTF-16).
When operating on the characters directly, we must check
JS_StringHasLatin1Chars() and use the appropriate accessors depending on
how they are stored.

Additionally, since the string's characters are still owned by the
string and may get moved around during garbage collection, we cannot use
any JSAPI functions that might trigger a GC while maintaining a pointer
to the string's characters. To enforce this, we must construct a
JS::AutoCheckCannotGC object, which will cause a crash if a GC starts
while it is in scope.
Comment 14 Philip Chimento 2017-01-31 01:25:38 UTC
Created attachment 344614 [details] [review]
js: JSNative accessors in JS_DefineProperty()

In JS_DefineProperty(), the getter and setter parameters must now be of
type JSNative. We have already switched to JSNative accessors everywhere,
but there are a few macros that must change in order to ensure everything
is cast to the right type.
Comment 15 Philip Chimento 2017-01-31 01:25:42 UTC
Created attachment 344615 [details] [review]
js: Fix misc APIs for mozjs38

This commit adapts to a few miscellaneous API changes in mozjs38 that
don't fit anywhere else.
Comment 16 Philip Chimento 2017-01-31 01:25:46 UTC
Created attachment 344616 [details] [review]
js: Various SpiderMonkey 38 improvements

Here are two places where SpiderMonkey 38 offers a better API than the
one we were using.

The third spot, we could use JS::CallArgs::requireAtLeast(), but there is
an issue with the visibility of that symbol in the shared library. Add a
link to the Mozilla bug for that.
Comment 17 Philip Chimento 2017-01-31 01:25:50 UTC
Created attachment 344617 [details] [review]
WIP - object: Update weak pointers after GC

The only place where we currently maintain a weak pointer is object.cpp,
where a GObject is associated with its JS wrapper object. In SpiderMonkey
38, we have to call JS_UpdateWeakPointerAfterGC on weak pointers, every
garbage collection cycle, in case the garbage collector moves them.

This is one way to do it, another way might be to add a separate callback
for each object with JS_AddWeakPointerCallback() instead of one callback
that processes all the weak pointers it knows about.

FIXME: The weak pointer list might have to have a lock.
Comment 18 Philip Chimento 2017-01-31 01:25:54 UTC
Created attachment 344618 [details] [review]
WIP - importer: Switch to eager enumeration

Enumeration of just the keys, without defining properties, has been
removed from the public API in SpiderMonkey 38. In practice, Firefox was
not using lazy enumeration, so they removed it. That is bad news for our
importer object, since it was nice to be able to enumerate the keys
without actually reading and executing all the code in the modules.

This changes the enumerate hook on the importer to import all the modules
immediately.

FIXME: This still has some problems. If a module throws an exception
during import, then what should the value of the defined property be?
Comment 19 Philip Chimento 2017-01-31 01:25:58 UTC
Created attachment 344619 [details] [review]
WIP - importer: Switch back to lazy enumeration

Lazy enumeration is still available through the jsfriend API in
js::Class, which is really JSClass but with some extra fields that are
masked in the public version.

In addition, JSNewEnumerateOp has changed somewhat, compared with
SpiderMonkey 31. Instead of the enumerate callback being called
incrementally for each property, now it is just called once the first
time an object's properties are enumerated, and you have to fill in the
passed-in JS::AutoIdVector with any names of lazy properties.

FIXME: This changes the behaviour, since the AutoIdVector already
contains any enumerable property names that the JS engine already knows
about, before the enumerate callback is called! So we now get searchPath,
byteArray, etc. when we enumerate the importer.
Comment 20 Philip Chimento 2017-01-31 01:41:37 UTC
All of these patches, except for "js: Various SpiderMonkey 38 improvements", have to be committed at the same time, or else GJS won't build.

Most of them are trivial adaptations to API changes. The final three patches need more careful scrutiny.

I believe "WIP - object: Update weak pointers after GC" is correct, though it touches that gnarly toggle-ref code, so I can't be sure :-)

The final two, "WIP - importer: Switch to eager enumeration" and "WIP - importer: Switch back to lazy enumeration" are two approaches to solve the same problem, which is that object enumeration was totally refactored in SpiderMonkey, and you can't do lazy enumeration anymore through the public API.

There are a few approaches we could take:

  - Switch to eager enumeration (commit patch 1 of 2). This would make
    enumerating the importer object really expensive but I doubt people do
    it very often anyway. Needs a bit of work on edge cases.

  - Use the jsfriendapi to keep lazy enumeration that _almost_ works the
    same (squash patch 2 into patch 1). Needs a bit of work on edge cases.

  - Do some hack like define the properties to null in the enumerate hook,
    and then override the get hook to really import the module if the value
    was null (but I already talked with Cosimo about this option and he
    didn't like it.)

  - Change the importer to a C++ Proxy object, which would also use the
    jsfriendapi.

  - Rebase and fix up Jasper's "wip/imports-rewrite" branch; it uses the
    bootstrap system which I already fixed up for bug 777724. I've done
    some work on this, see the "wip/ptomato/jasper-imports" branch. It
    doesn't pass all the tests, not sure how much more work it needs.

I'm hoping that ES6 modules will land in SpiderMonkey 59, so I'm hesitant to do _too_ much refactoring of the importer if we have to rewrite it all again by next year.
Comment 21 Giovanni Campagna 2017-02-02 17:29:21 UTC
(In reply to Philip Chimento from comment #19)
> Created attachment 344619 [details] [review] [review]
> WIP - importer: Switch back to lazy enumeration
> 
> ...
> 
> FIXME: This changes the behaviour, since the AutoIdVector already
> contains any enumerable property names that the JS engine already knows
> about, before the enumerate callback is called! So we now get searchPath,
> byteArray, etc. when we enumerate the importer.

Can we mark these as not enumerable? I feel like at least searchPath should be.
Comment 22 Philip Chimento 2017-02-06 06:18:49 UTC
Created attachment 345014 [details] [review]
js: Various SpiderMonkey 38 improvements

Here are three places where SpiderMonkey 38 offers a better API than the
one we were using.

The fourth spot, we could use JS::CallArgs::requireAtLeast(), but there is
an issue with the visibility of that symbol in the shared library. Add a
link to the Mozilla bug for that.
Comment 23 Philip Chimento 2017-02-06 06:25:51 UTC
(In reply to Giovanni Campagna from comment #21)
> (In reply to Philip Chimento from comment #19)
> > Created attachment 344619 [details] [review] [review] [review]
> > WIP - importer: Switch back to lazy enumeration
> > 
> > ...
> > 
> > FIXME: This changes the behaviour, since the AutoIdVector already
> > contains any enumerable property names that the JS engine already knows
> > about, before the enumerate callback is called! So we now get searchPath,
> > byteArray, etc. when we enumerate the importer.
> 
> Can we mark these as not enumerable? I feel like at least searchPath should
> be.

It's explicitly marked enumerable, and has been that way since the initial commit; but it wasn't enumerable in practice because the enumerate callback wouldn't have returned it, so I don't see a problem in changing that.

However, if we set native modules like byteArray to be non-enumerable, that's an inconsistency between JS modules and native ones. A pre-existing one, sure, but we should think twice before doing it or not doing it.
Comment 24 Philip Chimento 2017-02-11 06:07:32 UTC
Created attachment 345510 [details] [review]
jsapi-util-root: Re-enable test

SpiderMonkey 31's garbage collector was not smart enough to collect this
object right after it was unrooted. But SpiderMonkey 38's is.
Comment 25 Cosimo Cecchi 2017-02-13 18:01:22 UTC
Review of attachment 344601 [details] [review]:

OK
Comment 26 Cosimo Cecchi 2017-02-13 18:02:08 UTC
Review of attachment 344602 [details] [review]:

Thanks for doing this! Only a small comment.

::: NEWS
@@ +524,1 @@
+Version 0.1

This is unrelated.
Comment 27 Cosimo Cecchi 2017-02-13 18:02:29 UTC
Review of attachment 344603 [details] [review]:

OK
Comment 28 Cosimo Cecchi 2017-02-13 18:10:56 UTC
Review of attachment 344604 [details] [review]:

Looks good.
Comment 29 Cosimo Cecchi 2017-02-13 18:12:33 UTC
Review of attachment 344605 [details] [review]:

Looks good.
Comment 30 Cosimo Cecchi 2017-02-13 18:12:56 UTC
Review of attachment 344606 [details] [review]:

OK
Comment 31 Cosimo Cecchi 2017-02-13 18:14:09 UTC
Review of attachment 344607 [details] [review]:

OK
Comment 32 Cosimo Cecchi 2017-02-13 18:14:37 UTC
Review of attachment 344608 [details] [review]:

OK
Comment 33 Cosimo Cecchi 2017-02-13 18:15:16 UTC
Review of attachment 344609 [details] [review]:

OK
Comment 34 Cosimo Cecchi 2017-02-13 18:15:33 UTC
Review of attachment 344610 [details] [review]:

OK
Comment 35 Cosimo Cecchi 2017-02-13 18:17:22 UTC
Review of attachment 344611 [details] [review]:

OK
Comment 36 Cosimo Cecchi 2017-02-13 18:32:23 UTC
Review of attachment 344612 [details] [review]:

::: gi/ns.cpp
@@ +109,3 @@
+    /* we defined the property in this object */
+    g_base_info_unref(info);
+    *resolved = true;

Should this not be *resolved = defined? (Otherwise defined is also unused.)

::: gi/object.cpp
@@ +614,2 @@
     ret = true;
+    *resolved = false;  /* technically we shouldn't touch this if returning false? */

Yeah, maybe it's also possible to do early returns instead?

::: gi/repo.cpp
@@ +176,2 @@
     if (priv == NULL) /* we are the prototype, or have the wrong class */
+        return false;

This was returning true with objp not set before. So should it not return true with *resolved=false?
Comment 37 Cosimo Cecchi 2017-02-13 20:58:30 UTC
Review of attachment 344613 [details] [review]:

::: gjs/byteArray.cpp
@@ +624,3 @@
+                                    "LATIN1",  /* from_encoding */
+                                    NULL,  /* bytes read */
+                    JS_GetLatin1StringCharsAndLength(context, nogc, str, &len);

Optional: it would be nice if you factored the g_convert() into a single call. (You could store the from_encoding into another variable.)

::: gjs/jsapi-util-string.cpp
@@ +194,3 @@
+    JS::AutoCheckCannotGC nogc;
+
+    if (JS_StringHasLatin1Chars(value.toString())) {

Optional: would be nice to factor out the following block into a separate function.
Comment 38 Cosimo Cecchi 2017-02-13 20:59:15 UTC
Review of attachment 344614 [details] [review]:

Looks good.
Comment 39 Cosimo Cecchi 2017-02-13 20:59:39 UTC
Review of attachment 344615 [details] [review]:

OK
Comment 40 Philip Chimento 2017-02-13 23:36:54 UTC
Created attachment 345681 [details] [review]
WIP - js: Update weak pointers after GC

There are two places where we maintain weak pointers to GC things: one is
in object.cpp, where a GObject is associated with its JS wrapper object.
The other is in gtype.cpp, where each GType is associated with its
wrapper object.

In SpiderMonkey 38, we have to call JS_UpdateWeakPointerAfterGC() on weak
pointers, every garbage collection cycle, in case the garbage collector
moves them.

FIXME: This is one way to do it, another way might be to add a separate
callback for each object with JS_AddWeakPointerCallback() instead of one
callback per file that processes all the weak pointers it knows about.

FIXME: The GType weak pointers might be better off not stored as GType
qdata, instead have a map<GType, JS::Heap<JSObject*>*>
Comment 41 Philip Chimento 2017-02-13 23:36:58 UTC
Created attachment 345682 [details] [review]
WIP - importer: Switch to eager enumeration

Enumeration of just the keys, without defining properties, has been
removed from the public API in SpiderMonkey 38. In practice, Firefox was
not using lazy enumeration, so they removed it. That is bad news for our
importer object, since it was nice to be able to enumerate the keys
without actually reading and executing all the code in the modules.

This changes the enumerate hook on the importer to import all the modules
immediately.

FIXME: This still has some problems. If a module throws an exception
during import, then what should the value of the defined property be?
Comment 42 Philip Chimento 2017-02-13 23:37:03 UTC
Created attachment 345683 [details] [review]
WIP - importer: Switch back to lazy enumeration

Lazy enumeration is still available through the jsfriend API in
js::Class, which is really JSClass but with some extra fields that are
masked in the public version.

In addition, JSNewEnumerateOp has changed somewhat, compared with
SpiderMonkey 31. Instead of the enumerate callback being called
incrementally for each property, now it is just called once the first
time an object's properties are enumerated, and you have to fill in the
passed-in JS::AutoIdVector with any names of lazy properties.

FIXME: This changes the behaviour, since the AutoIdVector already
contains any enumerable property names that the JS engine already knows
about, before the enumerate callback is called! So we now get searchPath,
byteArray, etc. when we enumerate the importer.
Comment 43 Cosimo Cecchi 2017-02-14 00:10:51 UTC
Review of attachment 345014 [details] [review]:

Looks good.
Comment 44 Cosimo Cecchi 2017-02-14 00:11:05 UTC
Review of attachment 345510 [details] [review]:

OK
Comment 45 Cosimo Cecchi 2017-02-14 00:14:32 UTC
Review of attachment 345681 [details] [review]:

::: gi/gtype.cpp
@@ +77,3 @@
+    if (!weak_pointer_callback)
+        JS_AddWeakPointerCallback(JS_GetRuntime(cx), update_gtype_weak_pointers,
+        else

Need to set weak_pointer_callback = true here

@@ +170,3 @@
+    ensure_weak_pointer_callback(context);
+    g_type_set_qdata(gtype, gjs_get_gtype_wrapper_quark(), heap_wrapper);
+    weak_pointer_list.insert(gtype);

We discussed this in person -- would be nice to experiment with a rooted structure for the GType wrappers instead of tracking weak pointers.

::: gi/object.cpp
@@ +1333,3 @@
+    if (!weak_pointer_callback)
+        JS_AddWeakPointerCallback(JS_GetRuntime(cx),
+             * may also cause it to be erased.)

Also need to set weak_pointer_callback = true here.
Comment 46 Cosimo Cecchi 2017-02-14 00:22:24 UTC
Review of attachment 345682 [details] [review]:

::: gjs/importer.cpp
@@ +732,3 @@
+        JS::AutoIdVector module_props(context);
+        JS::RootedValue v_prop_name(context);
+        load_module_elements(context, object, module_props, init_path);

init_path will be leaked when you return false below.
Comment 47 Cosimo Cecchi 2017-02-14 00:24:47 UTC
Review of attachment 345683 [details] [review]:

Nice, I like the cleanup.

::: gjs/importer.cpp
@@ +56,3 @@
+extern js::Class gjs_importer_extended_class;
+// FIXME make JSClass const in macro
+static JSClass *gjs_importer_class = (JSClass *)(&gjs_importer_extended_class);

You mentioned you wanted to fix this as part of this patch?
Comment 48 Philip Chimento 2017-02-14 01:14:45 UTC
(In reply to Cosimo Cecchi from comment #37)
> Review of attachment 344613 [details] [review] [review]:
> 
> ::: gjs/byteArray.cpp
> @@ +624,3 @@
> +                                    "LATIN1",  /* from_encoding */
> +                                    NULL,  /* bytes read */
> +                    JS_GetLatin1StringCharsAndLength(context, nogc, str,
> &len);
> 
> Optional: it would be nice if you factored the g_convert() into a single
> call. (You could store the from_encoding into another variable.)

I don't think that's possible, since the two types for the "chars" array (JSLatin1Char * == unsigned char *, and char16_t *) may have different alignment requirements. I could declare the array as char16_t* which will have wider alignment, but it seems more readable to me the way it was.
Comment 49 Philip Chimento 2017-02-14 01:30:51 UTC
Created attachment 345687 [details] [review]
js: Adapt to new signature of resolve operation

JSNewResolveOp and JSResolveOp are merged in SpiderMonkey 38. There is
only one signature, so no need to distinguish the two with the
JSCLASS_NEW_RESOLVE flag.

Converting from the old JSNewResolveOp callback to the new JSResolveOp
callback is a matter of making sure that *resolved is set whenever the
callback returns true. (The equivalent of *resolved = true before this
change was objp.set(obj) on the passed-in MutableHandleObject.)
Comment 50 Philip Chimento 2017-02-14 01:30:55 UTC
Created attachment 345688 [details] [review]
js: Accommodate both Latin-1 and two-byte strings

Starting with SpiderMonkey 38, strings can be stored internally in the
JS engine as either Latin-1 or two bytes per character (sort-of-UTF-16).
When operating on the characters directly, we must check
JS_StringHasLatin1Chars() and use the appropriate accessors depending on
how they are stored.

Additionally, since the string's characters are still owned by the
string and may get moved around during garbage collection, we cannot use
any JSAPI functions that might trigger a GC while maintaining a pointer
to the string's characters. To enforce this, we must construct a
JS::AutoCheckCannotGC object, which will cause a crash if a GC starts
while it is in scope.
Comment 51 Philip Chimento 2017-02-14 01:34:32 UTC
(In reply to Cosimo Cecchi from comment #26)
> Review of attachment 344602 [details] [review] [review]:
> 
> Thanks for doing this! Only a small comment.
> 
> ::: NEWS
> @@ +524,1 @@
> +Version 0.1
> 
> This is unrelated.

I'll fix that on the branch, but I won't bother to attach a new patch if that's OK with you.
Comment 52 Philip Chimento 2017-02-14 01:58:27 UTC
Created attachment 345689 [details] [review]
WIP - js: Update weak pointers after GC

There are two places where we maintain weak pointers to GC things: one is
in object.cpp, where a GObject is associated with its JS wrapper object.
The other is in gtype.cpp, where each GType is associated with its
wrapper object.

In SpiderMonkey 38, we have to call JS_UpdateWeakPointerAfterGC() on weak
pointers, every garbage collection cycle, in case the garbage collector
moves them.

FIXME: This is one way to do it, another way might be to add a separate
callback for each object with JS_AddWeakPointerCallback() instead of one
callback per file that processes all the weak pointers it knows about.

FIXME: The GType weak pointers might be better off not stored as GType
qdata, instead have a map<GType, JS::Heap<JSObject*>*>
Comment 53 Philip Chimento 2017-02-14 01:58:32 UTC
Created attachment 345690 [details] [review]
WIP - importer: Switch to eager enumeration

Enumeration of just the keys, without defining properties, has been
removed from the public API in SpiderMonkey 38. In practice, Firefox was
not using lazy enumeration, so they removed it. That is bad news for our
importer object, since it was nice to be able to enumerate the keys
without actually reading and executing all the code in the modules.

This changes the enumerate hook on the importer to import all the modules
immediately.

FIXME: This still has some problems. If a module throws an exception
during import, then what should the value of the defined property be?
Comment 54 Philip Chimento 2017-02-14 01:58:36 UTC
Created attachment 345691 [details] [review]
WIP - importer: Switch back to lazy enumeration

Lazy enumeration is still available through the jsfriend API in
js::Class, which is really JSClass but with some extra fields that are
masked in the public version.

In addition, JSNewEnumerateOp has changed somewhat, compared with
SpiderMonkey 31. Instead of the enumerate callback being called
incrementally for each property, now it is just called once the first
time an object's properties are enumerated, and you have to fill in the
passed-in JS::AutoIdVector with any names of lazy properties.

FIXME: This changes the behaviour, since the AutoIdVector already
contains any enumerable property names that the JS engine already knows
about, before the enumerate callback is called! So we now get searchPath,
byteArray, etc. when we enumerate the importer.
Comment 55 Philip Chimento 2017-02-14 02:02:15 UTC
(In reply to Cosimo Cecchi from comment #45)
> Review of attachment 345681 [details] [review] [review]:

> We discussed this in person -- would be nice to experiment with a rooted
> structure for the GType wrappers instead of tracking weak pointers.

I've attached new patches that addressed all the comments except for the above one. I will have to delay investigating that until later, or possibly tomorrow.
Comment 56 Philip Chimento 2017-02-14 04:44:07 UTC
(In reply to Philip Chimento from comment #55)
> (In reply to Cosimo Cecchi from comment #45)
> > Review of attachment 345681 [details] [review] [review] [review]:
> 
> > We discussed this in person -- would be nice to experiment with a rooted
> > structure for the GType wrappers instead of tracking weak pointers.
> 
> I've attached new patches that addressed all the comments except for the
> above one. I will have to delay investigating that until later, or possibly
> tomorrow.

I realized later that we can't do that. It would be a leak, because the JS gtype object would own the C++ struct, which would root the JS gtype object.
Comment 57 Cosimo Cecchi 2017-02-15 03:32:22 UTC
Review of attachment 345687 [details] [review]:

Looks good
Comment 58 Cosimo Cecchi 2017-02-15 03:33:39 UTC
Review of attachment 345688 [details] [review]:

Looks good
Comment 59 Cosimo Cecchi 2017-02-15 03:35:03 UTC
Review of attachment 345689 [details] [review]:

OK
Comment 60 Cosimo Cecchi 2017-02-15 03:36:08 UTC
Review of attachment 345690 [details] [review]:

OK
Comment 61 Cosimo Cecchi 2017-02-15 03:37:19 UTC
Review of attachment 345691 [details] [review]:

Looks good
Comment 62 Philip Chimento 2017-02-15 04:05:02 UTC
Hooray! Amended the "WIP" commit messages on the three remaining patches
and pushed everything. I will make the change in jhbuild and
gnome-continuous as well.

Attachment 344601 [details] pushed as 1adf901 - build: Build with mozjs38
Attachment 344602 [details] pushed as 452e1fd - docs: Overview of new JS features in NEWS
Attachment 344603 [details] pushed as c057122 - js: AutoValueVector's [] operator is rooted
Attachment 344604 [details] pushed as 894eafe - js: Adapt to new JS_NewObject() API
Attachment 344605 [details] pushed as 82e5e11 - js: Adapt to new JS_DefinePropertyById() API
Attachment 344606 [details] pushed as 0a08a75 - js: Rename JS_CallHeapFooTracer()
Attachment 344607 [details] pushed as 4a087ff - js: Discontinue JSClass stubs
Attachment 344608 [details] pushed as fb6fcc0 - js: Adapt to new JS_SetErrorReporter() API
Attachment 344609 [details] pushed as 12114dd - constructor-proxy: Adapt to new js::DirectProxyHandler API
Attachment 344610 [details] pushed as c735ea8 - runtime: Adapt to new JSFinalizeCallback
Attachment 344611 [details] pushed as 9ae4ebe - js: Adapt to new mozilla::Maybe API
Attachment 344614 [details] pushed as f7f2837 - js: JSNative accessors in JS_DefineProperty()
Attachment 344615 [details] pushed as 4858889 - js: Fix misc APIs for mozjs38
Attachment 345014 [details] pushed as 9ccae32 - js: Various SpiderMonkey 38 improvements
Attachment 345510 [details] pushed as dd62f4a - jsapi-util-root: Re-enable test
Attachment 345687 [details] pushed as 8a0021f - js: Adapt to new signature of resolve operation
Attachment 345688 [details] pushed as aa743ce - js: Accommodate both Latin-1 and two-byte strings