Bug 1414174 - Baldr: fix OOM handling in compileStreaming (r=bbouvier)
authorLuke Wagner <luke@mozilla.com>
Wed, 08 Nov 2017 09:15:26 -0800
changeset 444198 f7fe2e79e4efa0fb1dcdbb716f80b5351d032829
parent 444197 63833bbedd6355fe951cf8a8907e5d9a505d45bf
child 444199 c34360f7ff67041b9ca03c0261c887eb816d6ffa
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1414174
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 1414174 - Baldr: fix OOM handling in compileStreaming (r=bbouvier)
js/src/jit-test/tests/wasm/regress/oom-wasm-streaming.js
js/src/wasm/WasmJS.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/wasm/regress/oom-wasm-streaming.js
@@ -0,0 +1,12 @@
+try {
+    WebAssembly.compileStreaming();
+} catch (err) {
+    assertEq(String(err).indexOf("not supported with --no-threads") !== -1, true);
+    quit();
+}
+if (!this.oomAfterAllocations)
+    quit();
+oomAfterAllocations(1, 2);
+var x = wasmTextToBinary('(module (func (export "run") (result i32) i32.const 42))');
+WebAssembly.compileStreaming(x);
+drainJobQueue();
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -1844,26 +1844,34 @@ WebAssembly_toSource(JSContext* cx, unsi
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     args.rval().setString(cx->names().WebAssembly);
     return true;
 }
 #endif
 
 static bool
+RejectWithPendingException(JSContext* cx, Handle<PromiseObject*> promise)
+{
+    if (!cx->isExceptionPending())
+        return false;
+
+    RootedValue rejectionValue(cx);
+    if (!GetAndClearException(cx, &rejectionValue))
+        return false;
+
+    return PromiseObject::reject(cx, promise, rejectionValue);
+}
+
+static bool
 Reject(JSContext* cx, const CompileArgs& args, UniqueChars error, Handle<PromiseObject*> promise)
 {
     if (!error) {
         ReportOutOfMemory(cx);
-
-        RootedValue rejectionValue(cx);
-        if (!cx->getPendingException(&rejectionValue))
-            return false;
-
-        return PromiseObject::reject(cx, promise, rejectionValue);
+        return RejectWithPendingException(cx, promise);
     }
 
     RootedObject stack(cx, promise->allocationSite());
     RootedString filename(cx, JS_NewStringCopyZ(cx, args.scriptedCaller.filename.get()));
     if (!filename)
         return false;
 
     unsigned line = args.scriptedCaller.line;
@@ -1885,29 +1893,16 @@ Reject(JSContext* cx, const CompileArgs&
     if (!errorObj)
         return false;
 
     RootedValue rejectionValue(cx, ObjectValue(*errorObj));
     return PromiseObject::reject(cx, promise, rejectionValue);
 }
 
 static bool
-RejectWithPendingException(JSContext* cx, Handle<PromiseObject*> promise)
-{
-    if (!cx->isExceptionPending())
-        return false;
-
-    RootedValue rejectionValue(cx);
-    if (!GetAndClearException(cx, &rejectionValue))
-        return false;
-
-    return PromiseObject::reject(cx, promise, rejectionValue);
-}
-
-static bool
 Resolve(JSContext* cx, Module& module, const CompileArgs& compileArgs,
         Handle<PromiseObject*> promise, bool instantiate, HandleObject importObj)
 {
     RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmModule).toObject());
     RootedObject moduleObj(cx, WasmModuleObject::create(cx, module, proto));
     if (!moduleObj)
         return RejectWithPendingException(cx, promise);
 
@@ -2514,17 +2509,17 @@ ResolveResponse(JSContext* cx, CallArgs 
 
     RootedFunction onResolved(cx, NewNativeFunction(cx, ResolveResponse_OnFulfilled, 1, nullptr,
                                                     gc::AllocKind::FUNCTION_EXTENDED));
     if (!onResolved)
         return false;
 
     RootedFunction onRejected(cx, NewNativeFunction(cx, ResolveResponse_OnRejected, 1, nullptr,
                                                     gc::AllocKind::FUNCTION_EXTENDED));
-    if (!onResolved)
+    if (!onRejected)
         return false;
 
     onResolved->setExtendedSlot(0, ObjectValue(*closure));
     onRejected->setExtendedSlot(0, ObjectValue(*closure));
 
     RootedObject resolve(cx, PromiseObject::unforgeableResolve(cx, callArgs.get(0)));
     if (!resolve)
         return false;