Bug 1347984 - Check for dead object proxies in TriggerPromiseReactions. r=till
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 06 Oct 2017 20:11:07 +0200
changeset 384949 754a3e12321c8656a83759adf297e61b0e188368
parent 384948 f7942ddde813952a6e21153ebf2dc7c2122918c7
child 384950 f6f706a84c451dea0ff17b3eb3861e7e69e66fd7
push id32636
push userarchaeopteryx@coole-files.de
push dateSat, 07 Oct 2017 08:46:47 +0000
treeherdermozilla-central@6b0491f83229 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1347984
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1347984 - Check for dead object proxies in TriggerPromiseReactions. r=till
js/src/builtin/Promise.cpp
js/src/jit-test/tests/basic/bug908915.js
js/src/jit-test/tests/promise/bug1347984.js
js/src/shell/js.cpp
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -1047,18 +1047,22 @@ RejectMaybeWrappedPromise(JSContext *cx,
 // ES2016, 25.4.1.8.
 static MOZ_MUST_USE bool
 TriggerPromiseReactions(JSContext* cx, HandleValue reactionsVal, JS::PromiseState state,
                         HandleValue valueOrReason)
 {
     RootedObject reactions(cx, &reactionsVal.toObject());
     RootedObject reaction(cx);
 
-    if (reactions->is<PromiseReactionRecord>() || IsWrapper(reactions))
+    if (reactions->is<PromiseReactionRecord>() ||
+        IsWrapper(reactions) ||
+        JS_IsDeadWrapper(reactions))
+    {
         return EnqueuePromiseReactionJob(cx, reactions, valueOrReason, state);
+    }
 
     RootedNativeObject reactionsList(cx, &reactions->as<NativeObject>());
     size_t reactionsCount = reactionsList->getDenseInitializedLength();
     MOZ_ASSERT(reactionsCount > 1, "Reactions list should be created lazily");
 
     RootedValue reactionVal(cx);
     for (size_t i = 0; i < reactionsCount; i++) {
         reactionVal = reactionsList->getDenseElement(i);
--- a/js/src/jit-test/tests/basic/bug908915.js
+++ b/js/src/jit-test/tests/basic/bug908915.js
@@ -6,16 +6,17 @@ load(libdir + "immutable-prototype.js");
 os.file.redirect(null);
 
 var blacklist = {
     'quit': true,
     'crash': true,
     'readline': true,
     'terminate': true,
     'nestedShell': true,
+    'nukeAllCCWs': true,
 };
 
 function f(y) {}
 for each(let e in newGlobal()) {
     if (e.name in blacklist)
 	continue;
     print(e.name);
     try {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/promise/bug1347984.js
@@ -0,0 +1,6 @@
+// |jit-test| error:dead object
+var g = newGlobal();
+var p = new Promise(() => {});
+g.Promise.prototype.then.call(p, () => void 0);
+g.eval("nukeAllCCWs()");
+resolvePromise(p, 9);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5067,16 +5067,33 @@ NukeCCW(JSContext* cx, unsigned argc, Va
     }
 
     NukeCrossCompartmentWrapper(cx, &args[0].toObject());
     args.rval().setUndefined();
     return true;
 }
 
 static bool
+NukeAllCCWs(JSContext* cx, unsigned argc, Value* vp)
+{
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    if (args.length() != 0) {
+        JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS,
+                                  "nukeAllCCWs");
+        return false;
+    }
+
+    NukeCrossCompartmentWrappers(cx, AllCompartments(), cx->compartment(),
+                                 NukeWindowReferences, NukeAllReferences);
+    args.rval().setUndefined();
+    return true;
+}
+
+static bool
 GetMaxArgs(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     args.rval().setInt32(ARGS_LENGTH_MAX);
     return true;
 }
 
 static bool
@@ -6573,16 +6590,20 @@ static const JSFunctionSpecWithHelp shel
 "         principals of ~0 subsumes all other principals. The absence of a\n"
 "         principal is treated as if its bits were 0xffff, for subsumption\n"
 "         purposes. If this property is omitted, supply no principal."),
 
     JS_FN_HELP("nukeCCW", NukeCCW, 1, 0,
 "nukeCCW(wrapper)",
 "  Nuke a CrossCompartmentWrapper, which turns it into a DeadProxyObject."),
 
+    JS_FN_HELP("nukeAllCCWs", NukeAllCCWs, 0, 0,
+"nukeAllCCWs()",
+"  Like nukeCCW, but for all CrossCompartmentWrappers targeting the current compartment."),
+
     JS_FN_HELP("createMappedArrayBuffer", CreateMappedArrayBuffer, 1, 0,
 "createMappedArrayBuffer(filename, [offset, [size]])",
 "  Create an array buffer that mmaps the given file."),
 
     JS_FN_HELP("addPromiseReactions", AddPromiseReactions, 3, 0,
 "addPromiseReactions(promise, onResolve, onReject)",
 "  Calls the JS::AddPromiseReactions JSAPI function with the given arguments."),