Merge inbound to mozilla-central. a=merge
authorshindli <shindli@mozilla.com>
Sat, 23 Mar 2019 11:47:34 +0200
changeset 465823 59e55930dc0f243357a8730be1a0ca372e6baddb
parent 465809 02b7484f316b1936479d4e28789c9c6dbf3fad9c (current diff)
parent 465822 86e2a4fbe138e98528eae960d0589cf520f861df (diff)
child 465826 21d88a7b7f7c74b9832d2f94c2091354920a828d
push id35747
push usershindli@mozilla.com
push dateSat, 23 Mar 2019 09:48:05 +0000
treeherdermozilla-central@59e55930dc0f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone68.0a1
first release with
nightly linux32
59e55930dc0f / 68.0a1 / 20190323094805 / files
nightly linux64
59e55930dc0f / 68.0a1 / 20190323094805 / files
nightly mac
59e55930dc0f / 68.0a1 / 20190323094805 / files
nightly win32
59e55930dc0f / 68.0a1 / 20190323094805 / files
nightly win64
59e55930dc0f / 68.0a1 / 20190323094805 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
js/src/vm/JSObject.cpp
--- a/build/mozconfig.artifact
+++ b/build/mozconfig.artifact
@@ -1,7 +1,11 @@
 # Common options for testing artifact builds in automation.
 
 # Enable the artifact build.
 ac_add_options --enable-artifact-builds
-ac_add_options --enable-artifact-build-symbols
+if test -n "$MOZ_ARTIFACT_TASK_WIN32_OPT" -a -z "$MOZ_DISABLE_FULL_SYMBOLS"; then
+  ac_add_options --enable-artifact-build-symbols=full
+else
+  ac_add_options --enable-artifact-build-symbols
+fi
 
 . "$topsrcdir/build/mozconfig.no-compile"
--- a/devtools/server/actors/replay/debugger.js
+++ b/devtools/server/actors/replay/debugger.js
@@ -539,16 +539,21 @@ ReplayDebugger.prototype = {
   },
 
   findSources() {
     this._ensurePaused();
     const data = this._sendRequest({ type: "findSources" });
     return data.map(source => this._addSource(source));
   },
 
+  adoptSource(source) {
+    assert(source._dbg == this);
+    return source;
+  },
+
   /////////////////////////////////////////////////////////
   // Object methods
   /////////////////////////////////////////////////////////
 
   _getObject(id) {
     if (id && !this._objects[id]) {
       const data = this._sendRequest({ type: "getObject", id });
       switch (data.kind) {
--- a/devtools/server/actors/utils/TabSources.js
+++ b/devtools/server/actors/utils/TabSources.js
@@ -143,16 +143,29 @@ TabSources.prototype = {
       throw new Error("getSource: could not find source actor for " +
                       (source.url || "source"));
     }
 
     return sourceActor;
   },
 
   getOrCreateSourceActor(source) {
+    // Tolerate the source coming from a different Debugger than the one
+    // associated with the thread.
+    try {
+      source = this._thread.dbg.adoptSource(source);
+    } catch (e) {
+      // We can't create actors for sources in the same compartment as the
+      // thread's Debugger.
+      if (/is in the same compartment as this debugger/.test(e)) {
+        return null;
+      }
+      throw e;
+    }
+
     if (this.hasSourceActor(source)) {
       return this.getSourceActor(source);
     }
     return this.createSourceActor(source);
   },
 
   getSourceActorByInternalSourceId: function(id) {
     if (!this._sourcesByInternalSourceId) {
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -401,18 +401,17 @@ void HTMLFormElement::UnbindFromTree(boo
   if (oldDocument) {
     oldDocument->RemovedForm();
   }
   ForgetCurrentSubmission();
 }
 
 void HTMLFormElement::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
   aVisitor.mWantsWillHandleEvent = true;
-  if (aVisitor.mEvent->IsTrusted() &&
-      aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
+  if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
     uint32_t msg = aVisitor.mEvent->mMessage;
     if (msg == eFormSubmit) {
       if (mGeneratingSubmit) {
         aVisitor.mCanHandle = false;
         return;
       }
       mGeneratingSubmit = true;
 
@@ -439,18 +438,17 @@ void HTMLFormElement::WillHandleEvent(Ev
        aVisitor.mEvent->mMessage == eFormReset) &&
       aVisitor.mEvent->mFlags.mInBubblingPhase &&
       aVisitor.mEvent->mOriginalTarget != static_cast<nsIContent*>(this)) {
     aVisitor.mEvent->StopPropagation();
   }
 }
 
 nsresult HTMLFormElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
-  if (aVisitor.mEvent->IsTrusted() &&
-      aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
+  if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
     EventMessage msg = aVisitor.mEvent->mMessage;
     if (msg == eFormSubmit) {
       // let the form know not to defer subsequent submissions
       mDeferSubmission = false;
     }
 
     if (aVisitor.mEventStatus == nsEventStatus_eIgnore) {
       switch (msg) {
--- a/js/src/builtin/WeakMapObject.h
+++ b/js/src/builtin/WeakMapObject.h
@@ -16,16 +16,21 @@ class GlobalObject;
 
 // Abstract base class for WeakMapObject and WeakSetObject.
 class WeakCollectionObject : public NativeObject {
  public:
   ObjectValueMap* getMap() {
     return static_cast<ObjectValueMap*>(getPrivate());
   }
 
+  size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) {
+    ObjectValueMap* map = getMap();
+    return map ? map->sizeOfIncludingThis(aMallocSizeOf) : 0;
+  }
+
   static MOZ_MUST_USE bool nondeterministicGetKeys(
       JSContext* cx, Handle<WeakCollectionObject*> obj,
       MutableHandleObject ret);
 
  protected:
   static const ClassOps classOps_;
 };
 
--- a/js/src/doc/Debugger/Debugger.md
+++ b/js/src/doc/Debugger/Debugger.md
@@ -477,16 +477,20 @@ other kinds of objects.
      equivalent debuggee value owned by this `Debugger`.
 
      If `value` is a primitive value, return it unchanged. If `value` is a
      `Debugger.Object` owned by an arbitrary `Debugger`, return an equivalent
      `Debugger.Object` owned by this `Debugger`. Otherwise, if `value` is some
      other kind of object, and hence not a proper debuggee value, throw a
      TypeError instead.
 
+<code>adoptSource(<i>source</i>)</code>
+:    Given `source` of type `Debugger.Source` which is owned by an arbitrary
+     `Debugger`, return an equivalent `Debugger.Source` owned by this `Debugger`.
+
 ## Static methods of the Debugger Object
 
 The functions described below are not called with a `this` value.
 
 <code id="isCompilableUnit">isCompilableUnit(<i>source</i>)</code>
 :   Given a string of source code, designated by <i>source</i>, return false if
     the string might become a valid JavaScript statement with the addition of
     more lines. Otherwise return true. The intent is to support interactive
--- a/js/src/gc/WeakMap.cpp
+++ b/js/src/gc/WeakMap.cpp
@@ -124,16 +124,20 @@ void WeakMapBase::restoreMarkedWeakMaps(
   for (WeakMapSet::Range r = markedWeakMaps.all(); !r.empty(); r.popFront()) {
     WeakMapBase* map = r.front();
     MOZ_ASSERT(map->zone()->isGCMarking());
     MOZ_ASSERT(!map->marked);
     map->marked = true;
   }
 }
 
+size_t ObjectValueMap::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) {
+  return mallocSizeOf(this) + shallowSizeOfExcludingThis(mallocSizeOf);
+}
+
 bool ObjectValueMap::findZoneEdges() {
   /*
    * For unmarked weakmap keys with delegates in a different zone, add a zone
    * edge to ensure that the delegate zone finishes marking before the key
    * zone.
    */
   JS::AutoSuppressGCAnalysis nogc;
   for (Range r = all(); !r.empty(); r.popFront()) {
--- a/js/src/gc/WeakMap.h
+++ b/js/src/gc/WeakMap.h
@@ -257,16 +257,18 @@ class WeakMap
 #endif
 };
 
 class ObjectValueMap : public WeakMap<HeapPtr<JSObject*>, HeapPtr<Value>> {
  public:
   ObjectValueMap(JSContext* cx, JSObject* obj) : WeakMap(cx, obj) {}
 
   bool findZoneEdges() override;
+
+  size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf);
 };
 
 // Generic weak map for mapping objects to other objects.
 class ObjectWeakMap {
   ObjectValueMap map;
 
  public:
   explicit ObjectWeakMap(JSContext* cx);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -5644,16 +5644,79 @@ bool Debugger::adoptDebuggeeValue(JSCont
       return false;
     }
   }
 
   args.rval().set(v);
   return true;
 }
 
+class DebuggerAdoptSourceMatcher {
+  JSContext* cx_;
+  Debugger* dbg_;
+
+ public:
+  explicit DebuggerAdoptSourceMatcher(JSContext* cx, Debugger* dbg)
+      : cx_(cx), dbg_(dbg) {}
+
+  using ReturnType = JSObject*;
+
+  ReturnType match(HandleScriptSourceObject source) {
+    if (source->compartment() == cx_->compartment()) {
+      JS_ReportErrorASCII(cx_, "Source is in the same compartment as this debugger");
+      return nullptr;
+    }
+    return dbg_->wrapSource(cx_, source);
+  }
+  ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
+    if (wasmInstance->compartment() == cx_->compartment()) {
+      JS_ReportErrorASCII(cx_, "WasmInstance is in the same compartment as this debugger");
+      return nullptr;
+    }
+    return dbg_->wrapWasmSource(cx_, wasmInstance);
+  }
+};
+
+static inline NativeObject* GetSourceReferentRawObject(JSObject* obj);
+static inline DebuggerSourceReferent GetSourceReferent(JSObject* obj);
+
+bool Debugger::adoptSource(JSContext* cx, unsigned argc, Value* vp) {
+  THIS_DEBUGGER(cx, argc, vp, "adoptSource", args, dbg);
+  if (!args.requireAtLeast(cx, "Debugger.adoptSource", 1)) {
+    return false;
+  }
+
+  RootedObject obj(cx, NonNullObject(cx, args[0]));
+  if (!obj) {
+    return false;
+  }
+
+  obj = UncheckedUnwrap(obj);
+  if (obj->getClass() != &DebuggerSource_class) {
+    JS_ReportErrorASCII(cx, "Argument is not a Debugger.Source");
+    return false;
+  }
+
+  if (!GetSourceReferentRawObject(obj)) {
+    JS_ReportErrorASCII(cx, "Argument is Debugger.Source.prototype");
+    return false;
+  }
+
+  Rooted<DebuggerSourceReferent> referent(cx, GetSourceReferent(obj));
+
+  DebuggerAdoptSourceMatcher matcher(cx, dbg);
+  JSObject* res = referent.match(matcher);
+  if (!res) {
+    return false;
+  }
+
+  args.rval().setObject(*res);
+  return true;
+}
+
 const JSPropertySpec Debugger::properties[] = {
     JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0),
     JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
             Debugger::setOnDebuggerStatement, 0),
     JS_PSGS("onExceptionUnwind", Debugger::getOnExceptionUnwind,
             Debugger::setOnExceptionUnwind, 0),
     JS_PSGS("onNewScript", Debugger::getOnNewScript, Debugger::setOnNewScript,
             0),
@@ -5685,16 +5748,17 @@ const JSFunctionSpec Debugger::methods[]
     JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 0, 0),
     JS_FN("findScripts", Debugger::findScripts, 1, 0),
     JS_FN("findSources", Debugger::findSources, 1, 0),
     JS_FN("findObjects", Debugger::findObjects, 1, 0),
     JS_FN("findAllGlobals", Debugger::findAllGlobals, 0, 0),
     JS_FN("makeGlobalObjectReference", Debugger::makeGlobalObjectReference, 1,
           0),
     JS_FN("adoptDebuggeeValue", Debugger::adoptDebuggeeValue, 1, 0),
+    JS_FN("adoptSource", Debugger::adoptSource, 1, 0),
     JS_FS_END};
 
 const JSFunctionSpec Debugger::static_methods[]{
     JS_FN("isCompilableUnit", Debugger::isCompilableUnit, 1, 0),
     JS_FN("recordReplayProcessKind", Debugger::recordReplayProcessKind, 0, 0),
     JS_FS_END};
 
 /*** Debugger.Script ********************************************************/
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -782,16 +782,17 @@ class Debugger : private mozilla::Linked
   static bool endTraceLogger(JSContext* cx, unsigned argc, Value* vp);
   static bool isCompilableUnit(JSContext* cx, unsigned argc, Value* vp);
   static bool recordReplayProcessKind(JSContext* cx, unsigned argc, Value* vp);
 #ifdef NIGHTLY_BUILD
   static bool setupTraceLogger(JSContext* cx, unsigned argc, Value* vp);
   static bool drainTraceLogger(JSContext* cx, unsigned argc, Value* vp);
 #endif
   static bool adoptDebuggeeValue(JSContext* cx, unsigned argc, Value* vp);
+  static bool adoptSource(JSContext* cx, unsigned argc, Value* vp);
   static bool construct(JSContext* cx, unsigned argc, Value* vp);
   static const JSPropertySpec properties[];
   static const JSFunctionSpec methods[];
   static const JSFunctionSpec static_methods[];
 
   static void removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx,
                                                        AbstractFramePtr frame,
                                                        bool suspending = false);
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -26,16 +26,17 @@
 #include "jsutil.h"
 
 #include "builtin/Array.h"
 #include "builtin/BigInt.h"
 #include "builtin/Eval.h"
 #include "builtin/Object.h"
 #include "builtin/String.h"
 #include "builtin/Symbol.h"
+#include "builtin/WeakSetObject.h"
 #include "frontend/BytecodeCompiler.h"
 #include "gc/Policy.h"
 #include "jit/BaselineJIT.h"
 #include "js/CharacterEncoding.h"
 #include "js/MemoryMetrics.h"
 #include "js/PropertyDescriptor.h"  // JS::FromPropertyDescriptor
 #include "js/PropertySpec.h"
 #include "js/Proxy.h"
@@ -3953,16 +3954,19 @@ void JSObject::addSizeOfExcludingThis(mo
         as<RegExpStaticsObject>().sizeOfData(mallocSizeOf);
   } else if (is<PropertyIteratorObject>()) {
     info->objectsMallocHeapMisc +=
         as<PropertyIteratorObject>().sizeOfMisc(mallocSizeOf);
   } else if (is<ArrayBufferObject>()) {
     ArrayBufferObject::addSizeOfExcludingThis(this, mallocSizeOf, info);
   } else if (is<SharedArrayBufferObject>()) {
     SharedArrayBufferObject::addSizeOfExcludingThis(this, mallocSizeOf, info);
+  } else if (is<WeakCollectionObject>()) {
+    info->objectsMallocHeapMisc +=
+        as<WeakCollectionObject>().sizeOfExcludingThis(mallocSizeOf);
 #ifdef JS_HAS_CTYPES
   } else {
     // This must be the last case.
     info->objectsMallocHeapMisc +=
         js::SizeOfDataIfCDataObject(mallocSizeOf, const_cast<JSObject*>(this));
 #endif
   }
 }
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -398,24 +398,17 @@ class MOZ_NON_PARAM Vector final : priva
   };
 
   template <size_t Dummy>
   struct CRAndStorage<0, Dummy> : CapacityAndReserved {
     explicit CRAndStorage(size_t aCapacity, size_t aReserved)
         : CapacityAndReserved(aCapacity, aReserved) {}
     CRAndStorage() = default;
 
-    T* storage() {
-      // If this returns |nullptr|, functions like |Vector::begin()| would too,
-      // breaking callers that pass a vector's elements as pointer/length to
-      // code that bounds its operation by length but (even just as a sanity
-      // check) always wants a non-null pointer.  Fake up an aligned, non-null
-      // pointer to support these callers.
-      return reinterpret_cast<T*>(sizeof(T));
-    }
+    T* storage() { return nullptr; }
   };
 
   CRAndStorage<kInlineCapacity, 0> mTail;
 
 #ifdef _MSC_VER
 #  pragma warning(pop)
 #endif  // _MSC_VER
 
--- a/mfbt/tests/TestVector.cpp
+++ b/mfbt/tests/TestVector.cpp
@@ -501,81 +501,19 @@ static_assert(sizeof(Vector<S, 0>) == si
 
 static_assert(sizeof(Vector<Incomplete, 0>) ==
                   sizeof(NoInlineStorageLayout<Incomplete>),
               "Vector of an incomplete class without inline storage shouldn't "
               "occupy dead space for that absence of storage");
 
 #endif  // DEBUG
 
-static void TestVectorBeginNonNull() {
-  // Vector::begin() should never return nullptr, to accommodate callers that
-  // (either for hygiene, or for semantic reasons) need a non-null pointer even
-  // for zero elements.
-
-  Vector<bool, 0> bvec0;
-  MOZ_RELEASE_ASSERT(bvec0.length() == 0);
-  MOZ_RELEASE_ASSERT(bvec0.begin() != nullptr);
-
-  Vector<bool, 1> bvec1;
-  MOZ_RELEASE_ASSERT(bvec1.length() == 0);
-  MOZ_RELEASE_ASSERT(bvec1.begin() != nullptr);
-
-  Vector<bool, 64> bvec64;
-  MOZ_RELEASE_ASSERT(bvec64.length() == 0);
-  MOZ_RELEASE_ASSERT(bvec64.begin() != nullptr);
-
-  Vector<int, 0> ivec0;
-  MOZ_RELEASE_ASSERT(ivec0.length() == 0);
-  MOZ_RELEASE_ASSERT(ivec0.begin() != nullptr);
-
-  Vector<int, 1> ivec1;
-  MOZ_RELEASE_ASSERT(ivec1.length() == 0);
-  MOZ_RELEASE_ASSERT(ivec1.begin() != nullptr);
-
-  Vector<int, 64> ivec64;
-  MOZ_RELEASE_ASSERT(ivec64.length() == 0);
-  MOZ_RELEASE_ASSERT(ivec64.begin() != nullptr);
-
-  Vector<long, 0> lvec0;
-  MOZ_RELEASE_ASSERT(lvec0.length() == 0);
-  MOZ_RELEASE_ASSERT(lvec0.begin() != nullptr);
-
-  Vector<long, 1> lvec1;
-  MOZ_RELEASE_ASSERT(lvec1.length() == 0);
-  MOZ_RELEASE_ASSERT(lvec1.begin() != nullptr);
-
-  Vector<long, 64> lvec64;
-  MOZ_RELEASE_ASSERT(lvec64.length() == 0);
-  MOZ_RELEASE_ASSERT(lvec64.begin() != nullptr);
-
-  // Vector<T, N> doesn't guarantee N inline elements -- the actual count is
-  // capped so that any Vector fits in a not-crazy amount of space -- so the
-  // code below won't overflow stacks or anything crazy.
-  struct VeryBig {
-    int array[16 * 1024 * 1024];
-  };
-
-  Vector<VeryBig, 0> vbvec0;
-  MOZ_RELEASE_ASSERT(vbvec0.length() == 0);
-  MOZ_RELEASE_ASSERT(vbvec0.begin() != nullptr);
-
-  Vector<VeryBig, 1> vbvec1;
-  MOZ_RELEASE_ASSERT(vbvec1.length() == 0);
-  MOZ_RELEASE_ASSERT(vbvec1.begin() != nullptr);
-
-  Vector<VeryBig, 64> vbvec64;
-  MOZ_RELEASE_ASSERT(vbvec64.length() == 0);
-  MOZ_RELEASE_ASSERT(vbvec64.begin() != nullptr);
-}
-
 int main() {
   VectorTesting::testReserved();
   VectorTesting::testConstRange();
   VectorTesting::testEmplaceBack();
   VectorTesting::testReverse();
   VectorTesting::testExtractRawBuffer();
   VectorTesting::testExtractOrCopyRawBuffer();
   VectorTesting::testReplaceRawBuffer();
   VectorTesting::testInsert();
   VectorTesting::testPodResizeToFit();
-  TestVectorBeginNonNull();
 }
--- a/remote/doc/index.rst
+++ b/remote/doc/index.rst
@@ -1,31 +1,36 @@
-===
-CDP
-===
+===============
+Remote Protocol
+===============
 
-In addition to the Firefox Developer Tools _Remote Debugging Protocol_,
-also known as RDP, Firefox also has a partial implementation of
-the Chrome DevTools Protocol (CDP).
+The Firefox **remote protocol** is a low-level debugging interface
+you can use to inspect the state and control execution of documents
+running in web content, instrument the browser in interesting ways,
+simulate user interaction for automation purposes, and for subscribing
+to updates in the browser such as network- or console logs.
 
-The Firefox remote agent is a low-level debugging interface based on
-the CDP protocol.  With it, you can inspect the state and control
-execution of documents running in web content, instrument Gecko in
-interesting ways, simulate user interaction for automation purposes,
-and debug JavaScript execution.
+It complements the existing Firefox Developer Tools `Remote Debugging
+Protocol`_ (RDP) by implementing a subset of the `Chrome DevTools
+Protocol`_ (CDP).
+
+.. _Remote Debugging Protocol: https://docs.firefox-dev.tools/backend/protocol.html
+.. _Chrome DevTools Protocol: https://chromedevtools.github.io/devtools-protocol/
+
 
 Users
 =====
 
 .. toctree::
   :maxdepth: 1
 
   Usage.md
   Prefs.md
 
+
 Developers
 ==========
 
 .. toctree::
   :maxdepth: 1
 
   Building.md
   Debugging.md
@@ -43,16 +48,16 @@ Bugs are tracked under the `Remote Proto
 
 
 Communication
 =============
 
 The mailing list for Firefox remote debugging discussion is
 `dev-remote@lists.mozilla.org`_ (`subscribe`_, `archive`_).
 
-If you prefer real-time chat, there is often someone in the
-#devtools IRC channel on irc.mozilla.org.  Don’t ask if you may
-ask a question just go ahead and ask, and please wait for an answer
-as we might not be in your timezone.
+If you prefer real-time chat, there is often someone in the *#remote*
+IRC channel on irc.mozilla.org.  Don’t ask if you may ask a
+question just go ahead and ask, and please wait for an answer as
+we might not be in your timezone.
 
 .. _dev-remote@lists.mozilla.org: mailto:dev-remote@lists.mozilla.org
 .. _subscribe: https://lists.mozilla.org/listinfo/dev-remote
 .. _archive: https://lists.mozilla.org/pipermail/dev-remote/
--- a/taskcluster/ci/build/windows.yml
+++ b/taskcluster/ci/build/windows.yml
@@ -1186,31 +1186,84 @@ win64-aarch64-shippable/opt:
         symbol: B
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
         max-run-time: 7200
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/aarch64.manifest"
             PERFHERDER_EXTRA_OPTIONS: aarch64
+            MOZ_ARTIFACT_TASK: {task-reference: '<win64-aarch64-opt>'}
+            MOZ_ARTIFACT_TASK_WIN32_OPT: {task-reference: '<win32-opt>'}
+            USE_ARTIFACT: '1'
     run:
         actions: [get-secrets, build]
         options: [append-env-variables-from-configs]
         script: mozharness/scripts/fx_desktop_build.py
         secrets: true
         config:
             - builds/releng_base_firefox.py
             - builds/taskcluster_base_windows.py
             - builds/taskcluster_base_win64.py
             - taskcluster_nightly.py
         extra-config:
             stage_platform: win64-aarch64
             mozconfig_platform: win64-aarch64
+    dependencies:
+        win32-opt: build-win32-nightly/opt
+        win64-aarch64-opt: build-win64-aarch64-nightly-no-eme/opt
+    fetches:
+        # Abuse fetches to copy the generated-files artifact from the non-eme
+        # build directly to the artifacts directory of this build. Likewise
+        # for target.langpack.xpi
+        win64-aarch64-opt:
+            - artifact: target.generated-files.tar.gz
+              extract: false
+              dest: ../public/build
+            - artifact: target.langpack.xpi
+              extract: false
+              dest: ../public/build
     run-on-projects: []  # Don't run by default yet
     toolchains:
+        - win64-node
+
+win64-aarch64-nightly-no-eme/opt:
+    description: "AArch64 Win64 Nightly w/o EME"
+    index:
+        product: firefox
+        job-name: win64-aarch64-no-eme-opt
+        type: nightly
+    attributes:
+        enable-full-crashsymbols: true
+    shipping-phase: build
+    shipping-product: firefox
+    treeherder:
+        platform: windows2012-aarch64/opt
+        symbol: Nn
+        tier: 1
+    worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
+    worker:
+        max-run-time: 7200
+        env:
+            TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/aarch64.manifest"
+            PERFHERDER_EXTRA_OPTIONS: aarch64-no-eme
+    run:
+        actions: [get-secrets, build]
+        options: [append-env-variables-from-configs]
+        script: mozharness/scripts/fx_desktop_build.py
+        secrets: true
+        config:
+            - builds/releng_base_firefox.py
+            - builds/taskcluster_base_windows.py
+            - taskcluster_nightly.py
+        extra-config:
+            stage_platform: win64-aarch64
+            mozconfig_platform: win64-aarch64
+    run-on-projects: []
+    toolchains:
         - win64-clang-cl
         - win64-aarch64-rust
         - win64-cbindgen
         - win64-nasm
         - win64-node
 
 win64-aarch64-nightly/opt:
     description: "AArch64 Win64 Nightly"
@@ -1228,33 +1281,46 @@ win64-aarch64-nightly/opt:
         symbol: N
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-win2012
     worker:
         max-run-time: 7200
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/win64/aarch64.manifest"
             PERFHERDER_EXTRA_OPTIONS: aarch64
+            MOZ_ARTIFACT_TASK: {task-reference: '<win64-aarch64-opt>'}
+            MOZ_ARTIFACT_TASK_WIN32_OPT: {task-reference: '<win32-opt>'}
+            USE_ARTIFACT: '1'
     run:
         actions: [get-secrets, build]
         options: [append-env-variables-from-configs]
         script: mozharness/scripts/fx_desktop_build.py
         secrets: true
         config:
             - builds/releng_base_firefox.py
             - builds/taskcluster_base_windows.py
             - taskcluster_nightly.py
         extra-config:
             stage_platform: win64-aarch64
             mozconfig_platform: win64-aarch64
+    dependencies:
+        win32-opt: build-win32-nightly/opt
+        win64-aarch64-opt: build-win64-aarch64-nightly-no-eme/opt
+    fetches:
+        # Abuse fetches to copy the generated-files artifact from the non-eme
+        # build directly to the artifacts directory of this build. Likewise
+        # for target.langpack.xpi
+        win64-aarch64-opt:
+            - artifact: target.generated-files.tar.gz
+              extract: false
+              dest: ../public/build
+            - artifact: target.langpack.xpi
+              extract: false
+              dest: ../public/build
     toolchains:
-        - win64-clang-cl
-        - win64-aarch64-rust
-        - win64-cbindgen
-        - win64-nasm
         - win64-node
 
 
 win64-aarch64-devedition-nightly/opt:
     description: "AArch64 Win64 MSVC Devedition Nightly"
     index:
         product: devedition
         job-name: win64-aarch64-opt
--- a/testing/web-platform/tests/html/semantics/forms/the-button-element/button-click-submits.html
+++ b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-click-submits.html
@@ -202,25 +202,9 @@ async_test(t => {
     t.step_timeout(() => t.done(), 500);
   }));
 
   const e = new MouseEvent("click", { bubbles: false });
   span.dispatchEvent(e);
 
 }, "clicking the child of a button by dispatching a non-bubbling event should not trigger submit");
 
-async_test(t => {
-  const form = document.createElement("form");
-  const button = document.createElement("button");
-  button.type = "button";
-  button.onclick =
-    function(e) {
-      form.dispatchEvent(new Event("submit"), { bubbles: true});
-    };
-  form.appendChild(button);
-  document.body.appendChild(form);
-
-  button.click();
-
-  t.step_timeout(() => t.done(), 500);
-}, "dispatching submit event should not trigger a submit");
-
 </script>