Bug 1330339 - Ensure wasm debug is enabled when observesFrame is queried. r=luke
authorYury Delendik <ydelendik@mozilla.com>
Thu, 12 Jan 2017 09:21:05 -0600
changeset 374390 6d67b80ede88eedb11b42a13e52393a657a3ba5b
parent 374389 dc460f55e042c5d18498650fb3bfdf6c8d24c607
child 374391 6e2a6c6c3881562e942d67a66acccfd8e1007dde
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1330339
milestone53.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 1330339 - Ensure wasm debug is enabled when observesFrame is queried. r=luke MozReview-Commit-ID: 7zbwMtA3uIZ
js/src/jit-test/tests/debug/bug1330339.js
js/src/vm/Debugger.cpp
js/src/vm/Stack.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug1330339.js
@@ -0,0 +1,36 @@
+// |jit-test| test-also-wasm-baseline; error: TestComplete
+
+if (!wasmIsSupported())
+     throw "TestComplete";
+
+let module = new WebAssembly.Module(wasmTextToBinary(`
+    (module
+        (import "global" "func")
+        (func (export "test")
+         call 0 ;; calls the import, which is func #0
+        )
+    )
+`));
+
+let imports = {
+  global: {
+    func: function () {
+        let g = newGlobal();
+        let dbg = new Debugger(g);
+        dbg.onExceptionUnwind = function (frame) {
+            frame.older;
+        };
+        g.eval("throw new Error();");
+    }
+  }
+};
+let instance = new WebAssembly.Instance(module, imports);
+
+try {
+    instance.exports.test();
+    assertEq(false, true);
+} catch (e) {
+    assertEq(e.constructor.name, 'Error');
+}
+
+throw "TestComplete";
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -6292,18 +6292,22 @@ bool
 Debugger::observesFrame(const FrameIter& iter) const
 {
     // Skip frames not yet fully initialized during their prologue.
     if (iter.isInterp() && iter.isFunctionFrame()) {
         const Value& thisVal = iter.interpFrame()->thisArgument();
         if (thisVal.isMagic() && thisVal.whyMagic() == JS_IS_CONSTRUCTING)
             return false;
     }
-    if (iter.isWasm())
+    if (iter.isWasm()) {
+        // Skip frame of wasm instances we cannot observe.
+        if (!iter.wasmDebugEnabled())
+            return false;
         return observesWasm(iter.wasmInstance());
+    }
     return observesScript(iter.script());
 }
 
 bool
 Debugger::observesScript(JSScript* script) const
 {
     if (!enabled)
         return false;
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1806,16 +1806,18 @@ class FrameIter
     JSAtom* functionDisplayAtom() const;
     bool mutedErrors() const;
 
     bool hasScript() const { return !isWasm(); }
 
     // -----------------------------------------------------------
     //  The following functions can only be called when isWasm()
     // -----------------------------------------------------------
+
+    inline bool wasmDebugEnabled() const;
     inline wasm::Instance* wasmInstance() const;
 
     // -----------------------------------------------------------
     // The following functions can only be called when hasScript()
     // -----------------------------------------------------------
 
     inline JSScript* script() const;
 
@@ -2051,21 +2053,29 @@ FrameIter::script() const
     if (data_.state_ == INTERP)
         return interpFrame()->script();
     MOZ_ASSERT(data_.state_ == JIT);
     if (data_.jitFrames_.isIonJS())
         return ionInlineFrames_.script();
     return data_.jitFrames_.script();
 }
 
+inline bool
+FrameIter::wasmDebugEnabled() const
+{
+    MOZ_ASSERT(!done());
+    MOZ_ASSERT(data_.state_ == WASM);
+    return data_.wasmFrames_.debugEnabled();
+}
+
 inline wasm::Instance*
 FrameIter::wasmInstance() const
 {
     MOZ_ASSERT(!done());
-    MOZ_ASSERT(data_.state_ == WASM);
+    MOZ_ASSERT(data_.state_ == WASM && wasmDebugEnabled());
     return data_.wasmFrames_.instance();
 }
 
 inline bool
 FrameIter::isIon() const
 {
     return isJit() && data_.jitFrames_.isIonJS();
 }