Bug 1330339 - Ensure wasm debug is enabled when observesFrame is queried. r?luke
MozReview-Commit-ID: 7zbwMtA3uIZ
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();
}