Bug 1333840 - Protect from frame.this access for wasm debugger frame. r=ochameau draft
authorYury Delendik <ydelendik@mozilla.com>
Wed, 25 Jan 2017 12:21:37 -0600
changeset 468412 21c12aebb9aa87725b87d1ea890e58b90596b8a3
parent 468403 adab5d5d0372d1a26685d6fbc59cdfc977ad76c6
child 543948 af88f01ab8e0d0d6a9ba4cef2f95117167f43c25
push id43464
push userydelendik@mozilla.com
push dateTue, 31 Jan 2017 14:04:32 +0000
reviewersochameau
bugs1333840
milestone54.0a1
Bug 1333840 - Protect from frame.this access for wasm debugger frame. r=ochameau MozReview-Commit-ID: eEhoHiXQTr
devtools/server/actors/frame.js
devtools/server/actors/script.js
devtools/server/tests/unit/test_frameactor_wasm-01.js
devtools/server/tests/unit/xpcshell.ini
--- a/devtools/server/actors/frame.js
+++ b/devtools/server/actors/frame.js
@@ -63,18 +63,20 @@ let FrameActor = ActorClassWithSpec(fram
 
     if (this.frame.environment) {
       let envActor = threadActor.createEnvironmentActor(
         this.frame.environment,
         this.frameLifetimePool
       );
       form.environment = envActor.form();
     }
-    form.this = createValueGrip(this.frame.this, threadActor._pausePool,
-      threadActor.objectGrip);
+    if (this.frame.type != "wasmcall") {
+      form.this = createValueGrip(this.frame.this, threadActor._pausePool,
+        threadActor.objectGrip);
+    }
     form.arguments = this._args();
     if (this.frame.script) {
       let generatedLocation = this.threadActor.sources.getFrameLocation(this.frame);
       form.where = {
         source: generatedLocation.generatedSourceActor.form(),
         line: generatedLocation.generatedLine,
         column: generatedLocation.generatedColumn
       };
--- a/devtools/server/actors/script.js
+++ b/devtools/server/actors/script.js
@@ -2185,20 +2185,25 @@ Object.assign(PauseScopedObjectActor.pro
 function hackDebugger(Debugger) {
   // TODO: Improve native code instead of hacking on top of it
 
   /**
    * Override the toString method in order to get more meaningful script output
    * for debugging the debugger.
    */
   Debugger.Script.prototype.toString = function () {
+    if (this.type == "wasm") {
+      return "[wasm]";
+    }
+
     let output = "";
     if (this.url) {
       output += this.url;
     }
+
     if (typeof this.staticLevel != "undefined") {
       output += ":L" + this.staticLevel;
     }
     if (typeof this.startLine != "undefined") {
       output += ":" + this.startLine;
       if (this.lineCount && this.lineCount > 1) {
         output += "-" + (this.startLine + this.lineCount - 1);
       }
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/unit/test_frameactor_wasm-01.js
@@ -0,0 +1,70 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Verify that wasm frame(s) can be requested from the client.
+ */
+
+var gDebuggee;
+var gClient;
+var gThreadClient;
+var gOldPref;
+
+function run_test()
+{
+  gOldPref = Services.prefs.getBoolPref("javascript.options.wasm");
+  Services.prefs.setBoolPref("javascript.options.wasm", true);
+
+  if (typeof WebAssembly == "undefined") {
+    return; // wasm is not enabled for this platform
+  }
+
+  initTestDebuggerServer();
+  gDebuggee = addTestGlobal("test-stack");
+  gClient = new DebuggerClient(DebuggerServer.connectPipe());
+  gClient.connect().then(function () {
+    attachTestTabAndResume(gClient, "test-stack", function (aResponse, aTabClient, aThreadClient) {
+      gThreadClient = aThreadClient;
+      gThreadClient.reconfigure({ observeAsmJS: true }, function (aResponse) {
+        do_check_eq(!!aResponse.error, false);
+        test_pause_frame();
+      });
+    });
+  });
+  do_test_pending();
+}
+
+function test_pause_frame()
+{
+  gThreadClient.addOneTimeListener("paused", function (aEvent, aPacket1) {
+    gThreadClient.getFrames(0, null, function (aFrameResponse) {
+      do_check_eq(aFrameResponse.frames.length, 4);
+
+      let wasmFrame = aFrameResponse.frames[1];
+      do_check_eq(wasmFrame.type, "wasmcall");
+      do_check_eq(wasmFrame.this, undefined);
+
+      let location = wasmFrame.where;
+      do_check_eq(location.line > 0, true);
+      do_check_eq(location.column > 0, true);
+      do_check_eq(location.source.url.endsWith(" > wasm"), true);
+
+      Services.prefs.setBoolPref("javascript.options.wasm", gOldPref);
+      finishClient(gClient);
+    });
+  });
+
+  gDebuggee.eval("(" + function () {
+    // WebAssembly bytecode was generated by running:
+    // js -e 'print(wasmTextToBinary("(module(import \"a\" \"b\")(func(export \"c\")call 0))"))'
+    var m = new WebAssembly.Module(new Uint8Array([
+      0,97,115,109,13,0,0,0,1,132,128,128,128,0,1,96,0,0,2,135,128,128,128,0,1,1,97,1,
+      98,0,0,3,130,128,128,128,0,1,0,6,129,128,128,128,0,0,7,133,128,128,128,0,1,1,99,
+      0,1,10,138,128,128,128,0,1,132,128,128,128,0,0,16,0,11
+    ]));
+    var i = new WebAssembly.Instance(m, {a: {b: () => {
+      debugger;
+    }}});
+    i.exports.c();
+  } + ")()");
+}
--- a/devtools/server/tests/unit/xpcshell.ini
+++ b/devtools/server/tests/unit/xpcshell.ini
@@ -59,16 +59,17 @@ support-files =
 [test_blackboxing-05.js]
 [test_blackboxing-06.js]
 [test_blackboxing-07.js]
 [test_frameactor-01.js]
 [test_frameactor-02.js]
 [test_frameactor-03.js]
 [test_frameactor-04.js]
 [test_frameactor-05.js]
+[test_frameactor_wasm-01.js]
 [test_framearguments-01.js]
 [test_getRuleText.js]
 [test_getTextAtLineColumn.js]
 [test_pauselifetime-01.js]
 [test_pauselifetime-02.js]
 [test_pauselifetime-03.js]
 [test_pauselifetime-04.js]
 [test_threadlifetime-01.js]