Backed out changeset 4047bcadec73 (bug 1522244) for mochitest failure at devtools/client/debugger/new/test/mochitest/browser_dbg-worker-scopes.js a=backout
authorDaniel Varga <dvarga@mozilla.com>
Sat, 02 Mar 2019 00:01:01 +0200
changeset 461917 e3762382f7906a9389f3dd890b07a2bfbad17227
parent 461916 3b08a133c893b960f15e014a8f36c954d31fda34
child 462051 2bd9674d85a170f42398b25aeb0a508880cc2be7
child 462113 07ac96eae9f2c515a204ea33947e05aeca62dc5b
push id35633
push userdvarga@mozilla.com
push dateFri, 01 Mar 2019 22:04:03 +0000
treeherdermozilla-central@e3762382f790 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1522244
milestone67.0a1
backs out4047bcadec730528dab1b651ee679ac11f42c41c
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
Backed out changeset 4047bcadec73 (bug 1522244) for mochitest failure at devtools/client/debugger/new/test/mochitest/browser_dbg-worker-scopes.js a=backout
devtools/client/debugger/new/test/mochitest/browser.ini
devtools/client/debugger/new/test/mochitest/browser_dbg-worker-scopes.js
devtools/client/debugger/new/test/mochitest/examples/doc-worker-scopes.html
devtools/client/debugger/new/test/mochitest/examples/scopes-worker.js
devtools/server/actors/object/previewers.js
devtools/server/actors/object/property-iterator.js
devtools/server/actors/object/utils.js
devtools/server/tests/unit/test_objectgrips-20.js
devtools/shared/DevToolsUtils.js
dom/workers/RuntimeService.cpp
--- a/devtools/client/debugger/new/test/mochitest/browser.ini
+++ b/devtools/client/debugger/new/test/mochitest/browser.ini
@@ -650,18 +650,16 @@ support-files =
   examples/pause-points.js
   examples/script-mutate.js
   examples/script-switching-02.js
   examples/script-switching-01.js
   examples/times2.js
   examples/doc-windowless-workers.html
   examples/doc-windowless-workers-early-breakpoint.html
   examples/simple-worker.js
-  examples/doc-worker-scopes.html
-  examples/scopes-worker.js
   examples/doc-event-handler.html
   examples/doc-eval-throw.html
 
 [browser_dbg-asm.js]
 [browser_dbg-async-stepping.js]
 [browser_dbg-sourcemapped-breakpoint-console.js]
 skip-if = (os == "win" && ccov) # Bug 1453549
 [browser_dbg-xhr-breakpoints.js]
@@ -769,11 +767,10 @@ skip-if = os == "win"
 [browser_dbg-tabs-without-urls.js]
 [browser_dbg-toggling-tools.js]
 [browser_dbg-react-app.js]
 skip-if = os == "win"
 [browser_dbg-wasm-sourcemaps.js]
 skip-if = true
 [browser_dbg-windowless-workers.js]
 [browser_dbg-windowless-workers-early-breakpoint.js]
-[browser_dbg-worker-scopes.js]
 [browser_dbg-event-handler.js]
 [browser_dbg-eval-throw.js]
deleted file mode 100644
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-worker-scopes.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-function findNode(dbg, text) {
-  for (let index = 0;; index++) {
-    var elem = findElement(dbg, "scopeNode", index);
-    if (elem && elem.innerText == text) {
-      return elem;
-    }
-  }
-}
-
-function toggleNode(dbg, text) {
-  return toggleObjectInspectorNode(findNode(dbg, text));
-}
-
-function findNodeValue(dbg, text) {
-  for (let index = 0;; index++) {
-    var elem = findElement(dbg, "scopeNode", index);
-    if (elem && elem.innerText == text) {
-      return findElement(dbg, "scopeValue", index).innerText;
-    }
-  }
-}
-
-// Test that unusual objects have their contents shown in worker thread scopes.
-add_task(async function() {
-  const dbg = await initDebugger("doc-worker-scopes.html", "scopes-worker.js");
-  const workerSource = findSource(dbg, "scopes-worker.js");
-
-  await addBreakpoint(dbg, workerSource, 6);
-  invokeInTab("startWorker");
-  await waitForPaused(dbg, "scopes-worker.js");
-  await removeBreakpoint(dbg, workerSource.id, 6);
-
-  // We should be paused at the first line of simple-worker.js
-  assertPausedAtSourceAndLine(dbg, workerSource.id, 6);
-
-  await toggleNode(dbg, "var_array");
-  ok(findNodeValue(dbg, "0") == "\"mango\"", "array elem0");
-  ok(findNodeValue(dbg, "1") == "\"pamplemousse\"", "array elem1");
-  ok(findNodeValue(dbg, "2") == "\"pineapple\"", "array elem2");
-  await toggleNode(dbg, "var_array");
-
-  await toggleNode(dbg, "var_tarray");
-  ok(findNodeValue(dbg, "0") == "42", "tarray elem0");
-  ok(findNodeValue(dbg, "1") == "43", "tarray elem1");
-  ok(findNodeValue(dbg, "2") == "44", "tarray elem2");
-  await toggleNode(dbg, "var_tarray");
-
-  await toggleNode(dbg, "var_set");
-  await toggleNode(dbg, "<entries>");
-  ok(findNodeValue(dbg, "0") == "\"papaya\"", "set elem0");
-  ok(findNodeValue(dbg, "1") == "\"banana\"", "set elem1");
-  await toggleNode(dbg, "var_set");
-
-  await toggleNode(dbg, "var_map");
-  await toggleNode(dbg, "<entries>");
-  await toggleNode(dbg, "0");
-  ok(findNodeValue(dbg, "<key>"), "1");
-  ok(findNodeValue(dbg, "<value>"), "\"one\"");
-  await toggleNode(dbg, "0");
-  await toggleNode(dbg, "1");
-  ok(findNodeValue(dbg, "<key>"), "2");
-  ok(findNodeValue(dbg, "<value>"), "\"two\"");
-});
deleted file mode 100644
--- a/devtools/client/debugger/new/test/mochitest/examples/doc-worker-scopes.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-
-<script>
-startWorker();
-
-function startWorker() {
-  w = new Worker("scopes-worker.js");
-}
-</script>
-
-<body>
-Hello World!
-</body>
-</html>
deleted file mode 100644
--- a/devtools/client/debugger/new/test/mochitest/examples/scopes-worker.js
+++ /dev/null
@@ -1,8 +0,0 @@
-function f() {
-  var var_array = ["mango","pamplemousse","pineapple"];
-  var var_tarray = new Uint8Array([42,43,44]);
-  var var_set = new Set(["papaya","banana"]);
-  var var_map = new Map([[1,"one"],[2,"two"]]);
-  return 0;
-}
-f();
--- a/devtools/server/actors/object/previewers.js
+++ b/devtools/server/actors/object/previewers.js
@@ -124,35 +124,34 @@ const previewers = {
     if (hooks.getGripDepth() > 1) {
       return true;
     }
 
     const raw = obj.unsafeDereference();
     const items = grip.preview.items = [];
 
     for (let i = 0; i < length; ++i) {
-      if (raw && !isWorker) {
+      if (raw) {
         // Array Xrays filter out various possibly-unsafe properties (like
         // functions, and claim that the value is undefined instead. This
         // is generally the right thing for privileged code accessing untrusted
         // objects, but quite confusing for Object previews. So we manually
         // override this protection by waiving Xrays on the array, and re-applying
         // Xrays on any indexed value props that we pull off of it.
         const desc = Object.getOwnPropertyDescriptor(Cu.waiveXrays(raw), i);
         if (desc && !desc.get && !desc.set) {
           let value = Cu.unwaiveXrays(desc.value);
           value = ObjectUtils.makeDebuggeeValueIfNeeded(obj, value);
           items.push(hooks.createValueGrip(value));
         } else {
           items.push(null);
         }
       } else {
-        // Workers do not have access to Cu, and when recording/replaying we
-        // don't have a raw object. In either case we do not need to deal with
-        // xray wrappers.
+        // When recording/replaying we don't have a raw object, but also don't
+        // need to deal with Xrays into the debuggee compartment.
         const value = DevToolsUtils.getProperty(obj, i);
         items.push(hooks.createValueGrip(value));
       }
 
       if (items.length == OBJECT_PREVIEW_MAX_ITEMS) {
         break;
       }
     }
@@ -453,19 +452,18 @@ previewers.Object = [
 
     if (hooks.getGripDepth() > 1) {
       return true;
     }
 
     const raw = obj.unsafeDereference();
 
     // The raw object will be null/unavailable when interacting with a
-    // replaying execution, and Cu is unavailable in workers. In either case we
-    // do not need to worry about xrays.
-    if (raw && !isWorker) {
+    // replaying execution.
+    if (raw) {
       const global = Cu.getGlobalForObject(DebuggerServer);
       const classProto = global[obj.class].prototype;
       // The Xray machinery for TypedArrays denies indexed access on the grounds
       // that it's slow, and advises callers to do a structured clone instead.
       const safeView = Cu.cloneInto(classProto.subarray.call(raw, 0,
         OBJECT_PREVIEW_MAX_ITEMS), global);
       const items = grip.preview.items = [];
       for (let i = 0; i < safeView.length; i++) {
--- a/devtools/server/actors/object/property-iterator.js
+++ b/devtools/server/actors/object/property-iterator.js
@@ -108,21 +108,18 @@ const PropertyIteratorActor  = protocol.
     return this.slice({ start: 0, count: this.iterator.size });
   },
 });
 
 /**
  * Helper function to create a grip from a Map/Set entry
  */
 function gripFromEntry({ obj, hooks }, entry) {
-  if (!isWorker) {
-    entry = Cu.unwaiveXrays(entry);
-  }
   return hooks.createValueGrip(
-    ObjectUtils.makeDebuggeeValueIfNeeded(obj, entry));
+    ObjectUtils.makeDebuggeeValueIfNeeded(obj, Cu.unwaiveXrays(entry)));
 }
 
 function enumArrayProperties(objectActor, options) {
   return {
     size: ObjectUtils.getArrayLength(objectActor.obj),
     propertyName(index) {
       return index;
     },
@@ -249,47 +246,33 @@ function enumMapEntries(objectActor) {
   // Arrays, the semantics often deny access to the entires based on the
   // nature of the values. So we need waive Xrays for the iterator object
   // and the tupes, and then re-apply them on the underlying values until
   // we fix bug 1023984.
   //
   // Even then though, we might want to continue waiving Xrays here for the
   // same reason we do so for Arrays above - this filtering behavior is likely
   // to be more confusing than beneficial in the case of Object previews.
-  let keys, getValue;
-  if (isWorker) {
-    const keysIterator = DevToolsUtils.callPropertyOnObject(objectActor.obj, "keys");
-    keys = [...DevToolsUtils.makeDebuggeeIterator(keysIterator)];
-    const valuesIterator = DevToolsUtils.callPropertyOnObject(objectActor.obj, "values");
-    const values = [...DevToolsUtils.makeDebuggeeIterator(valuesIterator)];
-    const map = new Map();
-    for (let i = 0; i < keys.length; i++) {
-      map.set(keys[i], values[i]);
-    }
-    getValue = key => map.get(key);
-  } else {
-    const raw = objectActor.obj.unsafeDereference();
-    keys = [...Cu.waiveXrays(Map.prototype.keys.call(raw))];
-    getValue = key => Map.prototype.get.call(raw, key);
-  }
+  const raw = objectActor.obj.unsafeDereference();
 
+  const keys = [...Cu.waiveXrays(Map.prototype.keys.call(raw))];
   return {
     [Symbol.iterator]: function* () {
       for (const key of keys) {
-        const value = getValue(key);
+        const value = Map.prototype.get.call(raw, key);
         yield [ key, value ].map(val => gripFromEntry(objectActor, val));
       }
     },
     size: keys.length,
     propertyName(index) {
       return index;
     },
     propertyDescription(index) {
       const key = keys[index];
-      const val = getValue(key);
+      const val = Map.prototype.get.call(raw, key);
       return {
         enumerable: true,
         value: {
           type: "mapEntry",
           preview: {
             key: gripFromEntry(objectActor, key),
             value: gripFromEntry(objectActor, val),
           },
@@ -386,24 +369,18 @@ function enumSetEntries(objectActor) {
   // compartment. However, we _do_ have Xrays to Object now, so we end up
   // Xraying those temporary objects, and filtering access to |it.value|
   // based on whether or not it's Xrayable and/or callable, which breaks
   // the for/of iteration.
   //
   // This code is designed to handle untrusted objects, so we can safely
   // waive Xrays on the iterable, and relying on the Debugger machinery to
   // make sure we handle the resulting objects carefully.
-  let values;
-  if (isWorker) {
-    const iterator = DevToolsUtils.callPropertyOnObject(objectActor.obj, "values");
-    values = [...DevToolsUtils.makeDebuggeeIterator(iterator)];
-  } else {
-    const raw = objectActor.obj.unsafeDereference();
-    values = [...Cu.waiveXrays(Set.prototype.values.call(raw))];
-  }
+  const raw = objectActor.obj.unsafeDereference();
+  const values = [...Cu.waiveXrays(Set.prototype.values.call(raw))];
 
   return {
     [Symbol.iterator]: function* () {
       for (const item of values) {
         yield gripFromEntry(objectActor, item);
       }
     },
     size: values.length,
--- a/devtools/server/actors/object/utils.js
+++ b/devtools/server/actors/object/utils.js
@@ -166,22 +166,16 @@ function getArrayLength(object) {
   // Real arrays have a reliable `length` own property.
   if (object.class === "Array") {
     return DevToolsUtils.getProperty(object, "length");
   }
 
   // For typed arrays, `DevToolsUtils.getProperty` is not reliable because the `length`
   // getter could be shadowed by an own property, and `getOwnPropertyNames` is
   // unnecessarily slow. Obtain the `length` getter safely and call it manually.
-  if (isWorker) {
-    // Workers can't wrap debugger values into debuggees, so do the calculations
-    // in the debuggee itself.
-    const getter = object.proto.proto.getOwnPropertyDescriptor("length").get;
-    return getter.call(object).return;
-  }
   const typedProto = Object.getPrototypeOf(Uint8Array.prototype);
   const getter = Object.getOwnPropertyDescriptor(typedProto, "length").get;
   return getter.call(object.unsafeDereference());
 }
 
 /**
  * Returns true if the parameter is suitable to be an array index.
  *
--- a/devtools/server/tests/unit/test_objectgrips-20.js
+++ b/devtools/server/tests/unit/test_objectgrips-20.js
@@ -140,30 +140,17 @@ add_task(threadClientTest(async ({ threa
     expectedNonIndexedProperties: [
       ["foo", "bar"],
       ["bar", "foo"],
       ["length", 2],
       ["buffer", DO_NOT_CHECK_VALUE],
       ["byteLength", 2],
       ["byteOffset", 0],
     ],
-  }];
-
-  for (const test of testCases) {
-    await test_object_grip(debuggee, client, threadClient, test);
-  }
-}));
-
-// These tests are not yet supported in workers.
-add_task(threadClientTest(async ({ threadClient, debuggee, client }) => {
-  debuggee.eval(function stopMe(arg1) {
-    debugger;
-  }.toString());
-
-  const testCases = [{
+  }, {
     evaledObject: `(() => {
       x = new Int8Array([1, 2]);
       Object.defineProperty(x, 'length', {value: 0});
       return x;
     })()`,
     expectedIndexedProperties: [["0", 1], ["1", 2]],
     expectedNonIndexedProperties: [
       ["length", 0],
@@ -179,17 +166,17 @@ add_task(threadClientTest(async ({ threa
     })()`,
     expectedIndexedProperties: [["0", 1], ["1", 2]],
     expectedNonIndexedProperties: [],
   }];
 
   for (const test of testCases) {
     await test_object_grip(debuggee, client, threadClient, test);
   }
-}, { doNotRunWorker: true }));
+}));
 
 async function test_object_grip(debuggee, dbgClient, threadClient, testData = {}) {
   const {
     evaledObject,
     expectedIndexedProperties,
     expectedNonIndexedProperties,
   } = testData;
 
--- a/devtools/shared/DevToolsUtils.js
+++ b/devtools/shared/DevToolsUtils.js
@@ -793,22 +793,8 @@ function callPropertyOnObject(object, na
   }
   if ("throw" in result) {
     throw result.throw;
   }
   return result.return;
 }
 
 exports.callPropertyOnObject = callPropertyOnObject;
-
-// Convert a Debugger.Object wrapping an iterator into an iterator in the
-// debugger's realm.
-function* makeDebuggeeIterator(object) {
-  while (true) {
-    const nextValue = callPropertyOnObject(object, "next");
-    if (exports.getProperty(nextValue, "done")) {
-      break;
-    }
-    yield exports.getProperty(nextValue, "value");
-  }
-}
-
-exports.makeDebuggeeIterator = makeDebuggeeIterator;
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -817,18 +817,17 @@ static bool PreserveWrapper(JSContext* c
 
   return mozilla::dom::TryPreserveWrapper(obj);
 }
 
 JSObject* Wrap(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj) {
   JSObject* targetGlobal = JS::CurrentGlobalOrNull(cx);
   if (!IsWorkerDebuggerGlobal(targetGlobal) &&
       !IsWorkerDebuggerSandbox(targetGlobal)) {
-    JS_ReportErrorASCII(cx, "There should be no edges from the debuggee to the debugger.");
-    return nullptr;
+    MOZ_CRASH("There should be no edges from the debuggee to the debugger.");
   }
 
   // Note: the JS engine unwraps CCWs before calling this callback.
   JSObject* originGlobal = JS::GetNonCCWObjectGlobal(obj);
 
   const js::Wrapper* wrapper = nullptr;
   if (IsWorkerDebuggerGlobal(originGlobal) ||
       IsWorkerDebuggerSandbox(originGlobal)) {