merge mozilla-inbound to mozilla-central. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 14 Oct 2017 11:49:31 +0200
changeset 386236 d43c1c0fa038fbd5aa71f09a07a3ed4fb00b8c97
parent 386218 0dd64d5842e80da586e0c3bb3f9ed04e2b1b338e (current diff)
parent 386235 873e2f3a9cf5301c1b267ee7da1c5c5fb10b4463 (diff)
child 386237 4ab539ae8b5b2927e219b219d5735f2557e82425
push id32679
push userarchaeopteryx@coole-files.de
push dateSat, 14 Oct 2017 09:49:51 +0000
treeherdermozilla-central@d43c1c0fa038 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone58.0a1
first release with
nightly linux32
d43c1c0fa038 / 58.0a1 / 20171014100219 / files
nightly linux64
d43c1c0fa038 / 58.0a1 / 20171014100219 / files
nightly mac
d43c1c0fa038 / 58.0a1 / 20171014100219 / files
nightly win32
d43c1c0fa038 / 58.0a1 / 20171014100219 / files
nightly win64
d43c1c0fa038 / 58.0a1 / 20171014100219 / 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 mozilla-inbound to mozilla-central. r=merge a=merge MozReview-Commit-ID: 8Qk2qoQvP0g
editor/libeditor/HTMLEditorDataTransfer.cpp
taskcluster/ci/toolchain/linux.yml
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -1169,31 +1169,31 @@ var interfaceNamesInGlobalScope =
     "UserProximityEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ValidityState",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "VideoPlaybackQuality",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "VideoStreamTrack",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VRDisplay", releaseNonWindows: false},
+    {name: "VRDisplay", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VRDisplayCapabilities", releaseNonWindows: false},
+    {name: "VRDisplayCapabilities", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VRDisplayEvent", releaseNonWindows: false},
+    {name: "VRDisplayEvent", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VREyeParameters", releaseNonWindows: false},
+    {name: "VREyeParameters", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VRFieldOfView", releaseNonWindows: false},
+    {name: "VRFieldOfView", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VRFrameData", releaseNonWindows: false},
+    {name: "VRFrameData", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VRPose", releaseNonWindows: false},
+    {name: "VRPose", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "VRStageParameters", releaseNonWindows: false},
+    {name: "VRStageParameters", releaseNonWindowsAndMac: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "VTTCue",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "VTTRegion", disabled: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "WaveShaperNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "WebAuthnAssertion", disabled: true},
@@ -1312,22 +1312,22 @@ function createInterfaceMap(isXBLScope) 
         interfaceMap[entry] = true;
       } else {
         ok(!("pref" in entry), "Bogus pref annotation for " + entry.name);
         if ((entry.nightly === !isNightly) ||
             (entry.nightlyAndroid === !(isAndroid && isNightly) && isAndroid) ||
             (entry.xbl === !isXBLScope) ||
             (entry.desktop === !isDesktop) ||
             (entry.windows === !isWindows) ||
-            (entry.releaseNonWindows === !isRelease && !isWindows) ||
             (entry.mac === !isMac) ||
             (entry.linux === !isLinux) ||
             (entry.android === !isAndroid && !entry.nightlyAndroid) ||
             (entry.stylo === !isStylo) ||
             (entry.release === !isRelease) ||
+            (entry.releaseNonWindowsAndMac === !(isRelease && !isWindows && !isMac)) ||
             (entry.isSecureContext === !isSecureContext) ||
             entry.disabled) {
           interfaceMap[entry.name] = false;
         } else {
           interfaceMap[entry.name] = true;
         }
       }
     }
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -6809,18 +6809,18 @@ HTMLEditRules::ReturnInListItem(Selectio
           NS_ENSURE_SUCCESS(rv, rv);
           rv = aSelection.Collapse(newListItem, 0);
           NS_ENSURE_SUCCESS(rv, rv);
 
           return NS_OK;
         }
 
         nsCOMPtr<Element> brNode;
-        rv = htmlEditor->CopyLastEditableChildStyles(GetAsDOMNode(prevItem),
-                                                     GetAsDOMNode(&aListItem),
+        rv = htmlEditor->CopyLastEditableChildStyles(prevItem,
+                                                     &aListItem,
                                                      getter_AddRefs(brNode));
         NS_ENSURE_SUCCESS(rv, rv);
         if (brNode) {
           nsCOMPtr<nsINode> brParent = brNode->GetParentNode();
           int32_t offset = brParent ? brParent->IndexOf(brNode) : -1;
           rv = aSelection.Collapse(brParent, offset);
           NS_ENSURE_SUCCESS(rv, rv);
           return NS_OK;
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -3848,30 +3848,16 @@ HTMLEditor::GetPriorHTMLSibling(nsINode*
   nsIContent* node = aNode->GetPreviousSibling();
   while (node && !IsEditable(node)) {
     node = node->GetPreviousSibling();
   }
 
   return node;
 }
 
-nsresult
-HTMLEditor::GetPriorHTMLSibling(nsIDOMNode* inNode,
-                                nsCOMPtr<nsIDOMNode>* outNode)
-{
-  NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
-  *outNode = nullptr;
-
-  nsCOMPtr<nsINode> node = do_QueryInterface(inNode);
-  NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
-
-  *outNode = do_QueryInterface(GetPriorHTMLSibling(node));
-  return NS_OK;
-}
-
 /**
  * GetNextHTMLSibling() returns the next editable sibling, if there is
  * one within the parent.
  */
 nsIContent*
 HTMLEditor::GetNextHTMLSibling(nsINode* aNode)
 {
   MOZ_ASSERT(aNode);
@@ -3879,30 +3865,16 @@ HTMLEditor::GetNextHTMLSibling(nsINode* 
   nsIContent* node = aNode->GetNextSibling();
   while (node && !IsEditable(node)) {
     node = node->GetNextSibling();
   }
 
   return node;
 }
 
-nsresult
-HTMLEditor::GetNextHTMLSibling(nsIDOMNode* inNode,
-                               nsCOMPtr<nsIDOMNode>* outNode)
-{
-  NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
-  *outNode = nullptr;
-
-  nsCOMPtr<nsINode> node = do_QueryInterface(inNode);
-  NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
-
-  *outNode = do_QueryInterface(GetNextHTMLSibling(node));
-  return NS_OK;
-}
-
 /**
  * GetPriorHTMLNode() returns the previous editable leaf node, if there is
  * one within the <body>.
  */
 nsIContent*
 HTMLEditor::GetPriorHTMLNode(nsINode* aNode,
                              bool aNoBlockCrossing)
 {
@@ -3910,30 +3882,16 @@ HTMLEditor::GetPriorHTMLNode(nsINode* aN
 
   if (!GetActiveEditingHost()) {
     return nullptr;
   }
 
   return GetPriorNode(aNode, true, aNoBlockCrossing);
 }
 
-nsresult
-HTMLEditor::GetPriorHTMLNode(nsIDOMNode* aNode,
-                             nsCOMPtr<nsIDOMNode>* aResultNode,
-                             bool aNoBlockCrossing)
-{
-  NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
-
-  *aResultNode = do_QueryInterface(GetPriorHTMLNode(node, aNoBlockCrossing));
-  return NS_OK;
-}
-
 /**
  * GetPriorHTMLNode() is same as above but takes {parent,offset} instead of
  * node.
  */
 nsIContent*
 HTMLEditor::GetPriorHTMLNode(nsINode* aParent,
                              int32_t aOffset,
                              nsINode* aChildAtOffset,
@@ -3962,30 +3920,16 @@ HTMLEditor::GetNextHTMLNode(nsINode* aNo
 
   if (result && !IsDescendantOfEditorRoot(result)) {
     return nullptr;
   }
 
   return result;
 }
 
-nsresult
-HTMLEditor::GetNextHTMLNode(nsIDOMNode* aNode,
-                            nsCOMPtr<nsIDOMNode>* aResultNode,
-                            bool aNoBlockCrossing)
-{
-  NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
-
-  *aResultNode = do_QueryInterface(GetNextHTMLNode(node, aNoBlockCrossing));
-  return NS_OK;
-}
-
 /**
  * GetNextHTMLNode() is same as above but takes {parent,offset} instead of node.
  */
 nsIContent*
 HTMLEditor::GetNextHTMLNode(nsINode* aParent,
                             int32_t aOffset,
                             nsINode* aChildAtOffset,
                             bool aNoBlockCrossing)
@@ -4549,54 +4493,49 @@ HTMLEditor::AreNodesSameType(nsIContent*
   }
 
   // If CSS is enabled, we are stricter about span nodes.
   return mCSSEditUtils->ElementsSameStyle(aNode1->AsDOMNode(),
                                           aNode2->AsDOMNode());
 }
 
 nsresult
-HTMLEditor::CopyLastEditableChildStyles(nsIDOMNode* aPreviousBlock,
-                                        nsIDOMNode* aNewBlock,
+HTMLEditor::CopyLastEditableChildStyles(nsINode* aPreviousBlock,
+                                        nsINode* aNewBlock,
                                         Element** aOutBrNode)
 {
   nsCOMPtr<nsINode> newBlock = do_QueryInterface(aNewBlock);
   NS_ENSURE_STATE(newBlock || !aNewBlock);
   *aOutBrNode = nullptr;
-  nsCOMPtr<nsIDOMNode> child, tmp;
+  nsCOMPtr<nsINode> child, tmp;
   // first, clear out aNewBlock.  Contract is that we want only the styles from previousBlock.
-  nsresult rv = aNewBlock->GetFirstChild(getter_AddRefs(child));
-  while (NS_SUCCEEDED(rv) && child) {
-    rv = DeleteNode(child);
+  child = aNewBlock->GetFirstChild();
+  while (child) {
+    nsresult rv = DeleteNode(child);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = aNewBlock->GetFirstChild(getter_AddRefs(child));
+    child = aNewBlock->GetFirstChild();
   }
   // now find and clone the styles
   child = aPreviousBlock;
   tmp = aPreviousBlock;
   while (tmp) {
     child = tmp;
-    nsCOMPtr<nsINode> child_ = do_QueryInterface(child);
-    NS_ENSURE_STATE(child_ || !child);
-    tmp = GetAsDOMNode(GetLastEditableChild(*child_));
+    tmp = GetLastEditableChild(*child);
   }
   while (child && TextEditUtils::IsBreak(child)) {
-    nsCOMPtr<nsIDOMNode> priorNode;
-    rv = GetPriorHTMLNode(child, address_of(priorNode));
-    NS_ENSURE_SUCCESS(rv, rv);
-    child = priorNode;
+    child = GetPriorHTMLNode(child);
   }
   nsCOMPtr<Element> newStyles, deepestStyle;
-  nsCOMPtr<nsINode> childNode = do_QueryInterface(child);
+  nsCOMPtr<nsINode> childNode = child;
   nsCOMPtr<Element> childElement;
   if (childNode) {
     childElement = childNode->IsElement() ? childNode->AsElement()
                                           : childNode->GetParentElement();
   }
-  while (childElement && (childElement->AsDOMNode() != aPreviousBlock)) {
+  while (childElement && (childElement != aPreviousBlock)) {
     if (HTMLEditUtils::IsInlineStyle(childElement) ||
         childElement->IsHTMLElement(nsGkAtoms::span)) {
       if (newStyles) {
         newStyles = InsertContainerAbove(newStyles,
                                          childElement->NodeInfo()->NameAtom());
         NS_ENSURE_STATE(newStyles);
       } else {
         deepestStyle = newStyles =
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -147,18 +147,18 @@ public:
 
   // nsIHTMLAbsPosEditor methods (implemented in HTMLAbsPositionEditor.cpp)
   NS_DECL_NSIHTMLABSPOSEDITOR
 
   // nsIHTMLInlineTableEditor methods (implemented in HTMLInlineTableEditor.cpp)
   NS_DECL_NSIHTMLINLINETABLEEDITOR
 
   // XXX Following methods are not overriding but defined here...
-  nsresult CopyLastEditableChildStyles(nsIDOMNode* aPreviousBlock,
-                                       nsIDOMNode* aNewBlock,
+  nsresult CopyLastEditableChildStyles(nsINode* aPreviousBlock,
+                                       nsINode* aNewBlock,
                                        Element** aOutBrNode);
 
   nsresult LoadHTML(const nsAString& aInputString);
 
   nsresult GetCSSBackgroundColorState(bool* aMixed, nsAString& aOutColor,
                                       bool aBlockLevel);
   NS_IMETHOD GetHTMLBackgroundColorState(bool* aMixed, nsAString& outColor);
 
@@ -765,33 +765,25 @@ protected:
   bool NodeIsProperty(nsINode& aNode);
   bool IsAtFrontOfNode(nsINode& aNode, int32_t aOffset);
   bool IsAtEndOfNode(nsINode& aNode, int32_t aOffset);
   bool IsOnlyAttribute(const nsIContent* aElement, const nsAString& aAttribute);
 
   nsresult RemoveBlockContainer(nsIContent& aNode);
 
   nsIContent* GetPriorHTMLSibling(nsINode* aNode);
-  nsresult GetPriorHTMLSibling(nsIDOMNode*inNode,
-                               nsCOMPtr<nsIDOMNode>* outNode);
 
   nsIContent* GetNextHTMLSibling(nsINode* aNode);
-  nsresult GetNextHTMLSibling(nsIDOMNode* inNode,
-                              nsCOMPtr<nsIDOMNode>* outNode);
 
   nsIContent* GetPriorHTMLNode(nsINode* aNode, bool aNoBlockCrossing = false);
-  nsresult GetPriorHTMLNode(nsIDOMNode* inNode, nsCOMPtr<nsIDOMNode>* outNode,
-                            bool bNoBlockCrossing = false);
   nsIContent* GetPriorHTMLNode(nsINode* aParent, int32_t aOffset,
                                nsINode* aChildAtOffset,
                                bool aNoBlockCrossing = false);
 
   nsIContent* GetNextHTMLNode(nsINode* aNode, bool aNoBlockCrossing = false);
-  nsresult GetNextHTMLNode(nsIDOMNode* inNode, nsCOMPtr<nsIDOMNode>* outNode,
-                           bool bNoBlockCrossing = false);
   nsIContent* GetNextHTMLNode(nsINode* aParent, int32_t aOffset,
                               nsINode* aChildAtOffset,
                               bool aNoBlockCrossing = false);
 
   bool IsFirstEditableChild(nsINode* aNode);
   bool IsLastEditableChild(nsINode* aNode);
   nsIContent* GetFirstEditableChild(nsINode& aNode);
   nsIContent* GetLastEditableChild(nsINode& aNode);
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -79,16 +79,19 @@ using namespace mozilla::widget;
 
 #define ADD_ATTR_1(_array, _k) do {             \
     (_array).AppendElement(_k);                 \
 } while (0)
 
 static bool
 CreateConfig(EGLConfig* aConfig, bool aEnableDepthBuffer);
 
+static bool
+CreateConfig(EGLConfig* aConfig, int32_t depth, bool aEnableDepthBuffer);
+
 // append three zeros at the end of attribs list to work around
 // EGL implementation bugs that iterate until they find 0, instead of
 // EGL_NONE. See bug 948406.
 #define EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS \
      LOCAL_EGL_NONE, 0, 0, 0
 
 static EGLint kTerminationAttribs[] = {
     EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
@@ -172,19 +175,29 @@ GLContextEGLFactory::Create(EGLNativeWin
     if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
         gfxCriticalNote << "Failed to load EGL library 3!";
         return nullptr;
     }
 
     bool doubleBuffered = true;
 
     EGLConfig config;
-    if (!CreateConfig(&config, aWebRender)) {
-        gfxCriticalNote << "Failed to create EGLConfig!";
-        return nullptr;
+    if (aWebRender && sEGLLibrary.IsANGLE()) {
+        // Force enable alpha channel to make sure ANGLE use correct framebuffer formart
+        const int bpp = 32;
+        const bool withDepth = true;
+        if (!CreateConfig(&config, bpp, withDepth)) {
+            gfxCriticalNote << "Failed to create EGLConfig for WebRender ANGLE!";
+            return nullptr;
+        }
+    } else {
+        if (!CreateConfig(&config, aWebRender)) {
+            gfxCriticalNote << "Failed to create EGLConfig!";
+            return nullptr;
+        }
     }
 
     EGLSurface surface = mozilla::gl::CreateSurfaceFromNativeWindow(aWindow, config);
 
     if (!surface) {
         gfxCriticalNote << "Failed to create EGLSurface!";
         return nullptr;
     }
--- a/js/src/tests/Makefile.in
+++ b/js/src/tests/Makefile.in
@@ -28,16 +28,17 @@ TEST_FILES = \
   js1_4/ \
   js1_5/ \
   js1_6/ \
   js1_7/ \
   js1_8/ \
   js1_8_1/ \
   js1_8_5/ \
   shell/ \
+  test/ \
   test262/ \
   $(NULL)
 
 PKG_STAGE = $(DIST)/test-stage
 
 # stage tests for packaging
 stage-package:
 	$(NSINSTALL) -D $(PKG_STAGE)/jsreftest/tests
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -1,11 +1,14 @@
 # Manifest entries for imported test suites whose individual test cases
 # we don't want to change.
 
+# Skip the folder with tests for the scripts
+skip include test/jstests.list
+
 skip script ecma_6/String/normalize-generateddata-input.js # input data for other test
 
 # Skip intl402 tests when Intl isn't available.
 skip-if(!this.hasOwnProperty('Intl')) include test262/intl402/jstests.list
 
 # Skip built-ins/Simd tests when SIMD isn't available.
 skip-if(!this.hasOwnProperty('SIMD')) include test262/built-ins/Simd/jstests.list
 
@@ -116,16 +119,17 @@ skip script test262/built-ins/TypedArray
 skip script test262/built-ins/TypedArrays/internals/Get/detached-buffer-realm.js
 skip script test262/built-ins/TypedArrays/internals/Get/detached-buffer.js
 skip script test262/built-ins/TypedArrays/internals/GetOwnProperty/detached-buffer-realm.js
 skip script test262/built-ins/TypedArrays/internals/GetOwnProperty/detached-buffer.js
 skip script test262/built-ins/TypedArrays/internals/HasProperty/detached-buffer-realm.js
 skip script test262/built-ins/TypedArrays/internals/HasProperty/detached-buffer.js
 skip script test262/built-ins/TypedArrays/internals/Set/detached-buffer-realm.js
 skip script test262/built-ins/TypedArrays/internals/Set/detached-buffer.js
+skip script test262/harness/detachArrayBuffer.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1129202
 skip script test262/built-ins/TypedArrays/internals/DefineOwnProperty/key-is-greater-than-last-index.js
 skip script test262/built-ins/TypedArrays/internals/DefineOwnProperty/key-is-lower-than-zero.js
 skip script test262/built-ins/TypedArrays/internals/DefineOwnProperty/key-is-minus-zero.js
 skip script test262/built-ins/TypedArrays/internals/DefineOwnProperty/key-is-not-canonical-index.js
 skip script test262/built-ins/TypedArrays/internals/DefineOwnProperty/key-is-not-integer.js
 skip script test262/built-ins/TypedArrays/internals/Get/key-is-not-canonical-index.js
@@ -483,22 +487,38 @@ skip script test262/language/expressions
 skip script test262/language/expressions/async-generator/named-yield-star-async-next.js
 skip script test262/language/expressions/object/method-definition/async-gen-yield-star-async-next.js
 skip script test262/language/expressions/class/async-gen-method-yield-star-async-next.js
 skip script test262/language/expressions/class/async-gen-method-static-yield-star-async-next.js
 skip script test262/language/statements/async-generator/yield-star-async-next.js
 skip script test262/language/statements/class/async-gen-method-yield-star-async-next.js
 skip script test262/language/statements/class/async-gen-method-static-yield-star-async-next.js
 
+# Optional Catch Binding
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1380881
 skip script test262/language/statements/try/optional-catch-binding-lexical.js
 skip script test262/language/statements/try/optional-catch-binding-throws.js
 skip script test262/language/statements/try/optional-catch-binding-finally.js
 skip script test262/language/statements/try/optional-catch-binding.js
 
+# Promise.prototype.finally
+# https://bugzilla.mozilla.org/show_bug.cgi?id=1019116
+skip script test262/built-ins/Promise/prototype/finally/invokes-then-with-function.js
+skip script test262/built-ins/Promise/prototype/finally/invokes-then-with-non-function.js
+skip script test262/built-ins/Promise/prototype/finally/is-a-function.js
+skip script test262/built-ins/Promise/prototype/finally/length.js
+skip script test262/built-ins/Promise/prototype/finally/name.js
+skip script test262/built-ins/Promise/prototype/finally/prop-desc.js
+skip script test262/built-ins/Promise/prototype/finally/rejected-observable-then-calls.js
+skip script test262/built-ins/Promise/prototype/finally/rejection-reason-no-fulfill.js
+skip script test262/built-ins/Promise/prototype/finally/rejection-reason-override-with-throw.js
+skip script test262/built-ins/Promise/prototype/finally/resolution-value-no-override.js
+skip script test262/built-ins/Promise/prototype/finally/resolved-observable-then-calls.js
+skip script test262/built-ins/Promise/prototype/finally/this-value-then-poisoned.js
+skip script test262/built-ins/Promise/prototype/finally/this-value-then-throws.js
 
 ###########################################################
 # Tests disabled due to issues in test262 importer script #
 ###########################################################
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1346080
 skip script test262/intl402/PluralRules/prototype/select/tainting.js
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/requirements.txt
@@ -0,0 +1,1 @@
+PyYAML==3.12
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/export/multi-header.js
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+info: |
+  foo bar  baz
+description: |
+  Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration variable
+  name.  Therefore ASI doesn't apply, and so the |0| where a |=| was expected is a
+  syntax error.
+author: Jeff Walden <jwalden+code@mit.edu>
+negative:
+  phase: early
+  type: SyntaxError
+flags:
+- module
+esid: sec-let-and-const-declarations
+features:
+- foobar
+---*/
+
+function f() {
+    let
+    await 0;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/export/reftest-and-frontmatter-error.js
@@ -0,0 +1,22 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+
+/*---
+esid: sec-let-and-const-declarations
+features: []
+negative:
+  phase: runtime
+  type: SyntaxError
+description: |
+  Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration variable
+  name.  Therefore ASI doesn't apply, and so the |0| where a |=| was expected is a
+  syntax error.
+---*/
+
+eval(`
+    function f() {
+        let
+        await 0;
+    }
+`);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/export/reftest-error-syntaxerror.js
@@ -0,0 +1,21 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+
+/*---
+negative:
+  phase: early
+  type: SyntaxError
+author: Jeff Walden <jwalden+code@mit.edu>
+features: []
+description: |
+  Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration variable
+  name.  Therefore ASI doesn't apply, and so the |0| where a |=| was expected is a
+  syntax error.
+esid: sec-let-and-const-declarations
+---*/
+
+function f() {
+    let
+    await 0;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/export/regular.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Jeff Walden <jwalden+code@mit.edu>
+description: |
+  '|await| is excluded from LexicalDeclaration by grammar parameter, in AsyncFunction.  Therefore
+  |let| followed by |await| inside AsyncFunction is an ASI opportunity, and this code
+  must parse without error.'
+esid: sec-let-and-const-declarations
+---*/
+
+async function f() {
+    let
+    await 0;
+}
+
+assert.sameValue(true, f instanceof Function);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/export/reportCompare.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+  assert.sameValue
+esid: pending
+---*/
+
+
+var a = 42;
+
+// comment
+assert.sameValue(trueish, true, "ok");
+
+assert.sameValue ( true, /*lol*/true, "ok");
+
+assert.sameValue(true, f instanceof Function);
+assert.sameValue(true, true, "don't crash");
+assert.sameValue(42, foo);
+
+    // this was a assert.sameValue Line
+
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/language/export/escaped-foobarbaz.js
@@ -0,0 +1,25 @@
+// |reftest| error:SyntaxError module
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-grammar-notation
+description: >
+  The `default` keyword must not contain Unicode escape sequences.
+info: >
+  Terminal symbols of the lexical, RegExp, and numeric string grammars are shown
+  in fixed width font, both in the productions of the grammars and throughout this
+  specification whenever the text directly refers to such a terminal symbol. These
+  are to appear in a script exactly as written. All terminal symbol code points
+  specified in this way are to be understood as the appropriate Unicode code points
+  from the Basic Latin range, as opposed to any similar-looking code points from
+  other Unicode ranges.
+negative:
+  phase: early
+  type: SyntaxError
+flags: [module]
+---*/
+
+throw "Test262: This statement should not be evaluated.";
+
+export d\u0065fault 0;
new file mode 100644
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/shell.js
@@ -0,0 +1,561 @@
+// file: assert.js
+// Copyright (C) 2017 Ecma International.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+    Collection of assertion functions used throughout test262
+---*/
+
+function assert(mustBeTrue, message) {
+  if (mustBeTrue === true) {
+    return;
+  }
+
+  if (message === undefined) {
+    message = 'Expected true but got ' + String(mustBeTrue);
+  }
+  $ERROR(message);
+}
+
+assert._isSameValue = function (a, b) {
+  if (a === b) {
+    // Handle +/-0 vs. -/+0
+    return a !== 0 || 1 / a === 1 / b;
+  }
+
+  // Handle NaN vs. NaN
+  return a !== a && b !== b;
+};
+
+assert.sameValue = function (actual, expected, message) {
+  if (assert._isSameValue(actual, expected)) {
+    return;
+  }
+
+  if (message === undefined) {
+    message = '';
+  } else {
+    message += ' ';
+  }
+
+  message += 'Expected SameValue(«' + String(actual) + '», «' + String(expected) + '») to be true';
+
+  $ERROR(message);
+};
+
+assert.notSameValue = function (actual, unexpected, message) {
+  if (!assert._isSameValue(actual, unexpected)) {
+    return;
+  }
+
+  if (message === undefined) {
+    message = '';
+  } else {
+    message += ' ';
+  }
+
+  message += 'Expected SameValue(«' + String(actual) + '», «' + String(unexpected) + '») to be false';
+
+  $ERROR(message);
+};
+
+assert.throws = function (expectedErrorConstructor, func, message) {
+  if (typeof func !== "function") {
+    $ERROR('assert.throws requires two arguments: the error constructor ' +
+      'and a function to run');
+    return;
+  }
+  if (message === undefined) {
+    message = '';
+  } else {
+    message += ' ';
+  }
+
+  try {
+    func();
+  } catch (thrown) {
+    if (typeof thrown !== 'object' || thrown === null) {
+      message += 'Thrown value was not an object!';
+      $ERROR(message);
+    } else if (thrown.constructor !== expectedErrorConstructor) {
+      message += 'Expected a ' + expectedErrorConstructor.name + ' but got a ' + thrown.constructor.name;
+      $ERROR(message);
+    }
+    return;
+  }
+
+  message += 'Expected a ' + expectedErrorConstructor.name + ' to be thrown but no exception was thrown at all';
+  $ERROR(message);
+};
+
+assert.throws.early = function(err, code) {
+  let wrappedCode = `function wrapperFn() { ${code} }`;
+  let ieval = eval;
+
+  assert.throws(err, () => { Function(wrappedCode); }, `Function: ${code}`);
+};
+
+// file: compareArray.js
+// Copyright (C) 2017 Ecma International.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+    Compare the contents of two arrays
+---*/
+
+function compareArray(a, b) {
+  if (b.length !== a.length) {
+    return false;
+  }
+
+  for (var i = 0; i < a.length; i++) {
+    if (b[i] !== a[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+assert.compareArray = function(actual, expected, message) {
+  assert(compareArray(actual, expected),
+         `Expected [${actual.join(", ")}] and [${expected.join(", ")}] to have the same contents. ${message}`);
+};
+
+// file: propertyHelper.js
+// Copyright (C) 2017 Ecma International.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+    Collection of functions used to safely verify the correctness of
+    property descriptors.
+---*/
+
+function verifyProperty(obj, name, desc, options) {
+  assert(
+    arguments.length > 2,
+    'verifyProperty should receive at least 3 arguments: obj, name, and descriptor'
+  );
+
+  var originalDesc = Object.getOwnPropertyDescriptor(obj, name);
+  var nameStr = String(name);
+
+  // Allows checking for undefined descriptor if it's explicitly given.
+  if (desc === undefined) {
+    assert.sameValue(
+      originalDesc,
+      undefined,
+      `obj['${nameStr}'] descriptor should be undefined`
+    );
+
+    // desc and originalDesc are both undefined, problem solved;
+    return true;
+  }
+
+  assert(
+    Object.prototype.hasOwnProperty.call(obj, name),
+    `obj should have an own property ${nameStr}`
+  );
+
+  assert.notSameValue(
+    desc,
+    null,
+    `The desc argument should be an object or undefined, null`
+  );
+
+  assert.sameValue(
+    typeof desc,
+    "object",
+    `The desc argument should be an object or undefined, ${String(desc)}`
+  );
+
+  var failures = [];
+
+  if (Object.prototype.hasOwnProperty.call(desc, 'value')) {
+    if (desc.value !== originalDesc.value) {
+      failures.push(`descriptor value should be ${desc.value}`);
+    }
+  }
+
+  if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) {
+    if (desc.enumerable !== originalDesc.enumerable ||
+        desc.enumerable !== isEnumerable(obj, name)) {
+      failures.push(`descriptor should ${desc.enumerable ? '' : 'not '}be enumerable`);
+    }
+  }
+
+  if (Object.prototype.hasOwnProperty.call(desc, 'writable')) {
+    if (desc.writable !== originalDesc.writable ||
+        desc.writable !== isWritable(obj, name)) {
+      failures.push(`descriptor should ${desc.writable ? '' : 'not '}be writable`);
+    }
+  }
+
+  if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) {
+    if (desc.configurable !== originalDesc.configurable ||
+        desc.configurable !== isConfigurable(obj, name)) {
+      failures.push(`descriptor should ${desc.configurable ? '' : 'not '}be configurable`);
+    }
+  }
+
+  assert.sameValue(failures.length, 0, failures.join('; '));
+
+  if (options && options.restore) {
+    Object.defineProperty(obj, name, originalDesc);
+  }
+
+  return true;
+}
+
+function isConfigurable(obj, name) {
+  try {
+    delete obj[name];
+  } catch (e) {
+    if (!(e instanceof TypeError)) {
+      $ERROR("Expected TypeError, got " + e);
+    }
+  }
+  return !Object.prototype.hasOwnProperty.call(obj, name);
+}
+
+function isEnumerable(obj, name) {
+  var stringCheck = false;
+
+  if (typeof name === "string") {
+    for (var x in obj) {
+      if (x === name) {
+        stringCheck = true;
+        break;
+      }
+    }
+  } else {
+    // skip it if name is not string, works for Symbol names.
+    stringCheck = true;
+  }
+
+  return stringCheck &&
+    Object.prototype.hasOwnProperty.call(obj, name) &&
+    Object.prototype.propertyIsEnumerable.call(obj, name);
+}
+
+function isEqualTo(obj, name, expectedValue) {
+  var actualValue = obj[name];
+
+  return assert._isSameValue(actualValue, expectedValue);
+}
+
+function isWritable(obj, name, verifyProp, value) {
+  var newValue = value || "unlikelyValue";
+  var hadValue = Object.prototype.hasOwnProperty.call(obj, name);
+  var oldValue = obj[name];
+  var writeSucceeded;
+
+  try {
+    obj[name] = newValue;
+  } catch (e) {
+    if (!(e instanceof TypeError)) {
+      $ERROR("Expected TypeError, got " + e);
+    }
+  }
+
+  writeSucceeded = isEqualTo(obj, verifyProp || name, newValue);
+
+  // Revert the change only if it was successful (in other cases, reverting
+  // is unnecessary and may trigger exceptions for certain property
+  // configurations)
+  if (writeSucceeded) {
+    if (hadValue) {
+    obj[name] = oldValue;
+    } else {
+    delete obj[name];
+    }
+  }
+
+  return writeSucceeded;
+}
+
+function verifyEqualTo(obj, name, value) {
+  if (!isEqualTo(obj, name, value)) {
+    $ERROR("Expected obj[" + String(name) + "] to equal " + value +
+           ", actually " + obj[name]);
+  }
+}
+
+function verifyWritable(obj, name, verifyProp, value) {
+  if (!verifyProp) {
+    assert(Object.getOwnPropertyDescriptor(obj, name).writable,
+         "Expected obj[" + String(name) + "] to have writable:true.");
+  }
+  if (!isWritable(obj, name, verifyProp, value)) {
+    $ERROR("Expected obj[" + String(name) + "] to be writable, but was not.");
+  }
+}
+
+function verifyNotWritable(obj, name, verifyProp, value) {
+  if (!verifyProp) {
+    assert(!Object.getOwnPropertyDescriptor(obj, name).writable,
+         "Expected obj[" + String(name) + "] to have writable:false.");
+  }
+  if (isWritable(obj, name, verifyProp)) {
+    $ERROR("Expected obj[" + String(name) + "] NOT to be writable, but was.");
+  }
+}
+
+function verifyEnumerable(obj, name) {
+  assert(Object.getOwnPropertyDescriptor(obj, name).enumerable,
+       "Expected obj[" + String(name) + "] to have enumerable:true.");
+  if (!isEnumerable(obj, name)) {
+    $ERROR("Expected obj[" + String(name) + "] to be enumerable, but was not.");
+  }
+}
+
+function verifyNotEnumerable(obj, name) {
+  assert(!Object.getOwnPropertyDescriptor(obj, name).enumerable,
+       "Expected obj[" + String(name) + "] to have enumerable:false.");
+  if (isEnumerable(obj, name)) {
+    $ERROR("Expected obj[" + String(name) + "] NOT to be enumerable, but was.");
+  }
+}
+
+function verifyConfigurable(obj, name) {
+  assert(Object.getOwnPropertyDescriptor(obj, name).configurable,
+       "Expected obj[" + String(name) + "] to have configurable:true.");
+  if (!isConfigurable(obj, name)) {
+    $ERROR("Expected obj[" + String(name) + "] to be configurable, but was not.");
+  }
+}
+
+function verifyNotConfigurable(obj, name) {
+  assert(!Object.getOwnPropertyDescriptor(obj, name).configurable,
+       "Expected obj[" + String(name) + "] to have configurable:false.");
+  if (isConfigurable(obj, name)) {
+    $ERROR("Expected obj[" + String(name) + "] NOT to be configurable, but was.");
+  }
+}
+
+// file: sta.js
+// Copyright (c) 2012 Ecma International.  All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+    Provides both:
+
+    - An error class to avoid false positives when testing for thrown exceptions
+    - A function to explicitly throw an exception using the Test262Error class
+---*/
+
+
+function Test262Error(message) {
+  this.message = message || "";
+}
+
+Test262Error.prototype.toString = function () {
+  return "Test262Error: " + this.message;
+};
+
+var $ERROR;
+$ERROR = function $ERROR(message) {
+  throw new Test262Error(message);
+};
+
+// file: test262-host.js
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// https://github.com/tc39/test262/blob/master/INTERPRETING.md#host-defined-functions
+;(function createHostObject(global) {
+    var FunctionToString = global.Function.prototype.toString;
+    var ReflectApply = global.Reflect.apply;
+    var NewGlobal = global.newGlobal;
+    var Atomics = global.Atomics;
+    var SharedArrayBuffer = global.SharedArrayBuffer;
+    var Int32Array = global.Int32Array;
+    var setSharedArrayBuffer = global.setSharedArrayBuffer;
+    var getSharedArrayBuffer = global.getSharedArrayBuffer;
+    var evalInWorker = global.evalInWorker;
+    var hasThreads = ("helperThreadCount" in global ? global.helperThreadCount() > 0 : true);
+    var hasMailbox = typeof setSharedArrayBuffer == "function" && typeof getSharedArrayBuffer == "function";
+    var hasEvalInWorker = typeof evalInWorker == "function";
+
+    // The $262.agent framework is not appropriate for browsers yet, and some
+    // test cases can't work in browsers (they block the main thread).
+
+    var shellCode = hasMailbox && hasEvalInWorker;
+    var sabTestable = Atomics && SharedArrayBuffer && hasThreads && shellCode;
+
+    global.$262 = {
+        __proto__: null,
+        createRealm() {
+            var newGlobalObject = NewGlobal();
+            var createHostObjectFn = ReflectApply(FunctionToString, createHostObject, []);
+            newGlobalObject.Function(`${createHostObjectFn} createHostObject(this);`)();
+            return newGlobalObject.$262;
+        },
+        detachArrayBuffer: global.detachArrayBuffer,
+        evalScript: global.evaluateScript || global.evaluate,
+        global,
+        agent: (function () {
+
+            // SpiderMonkey complication: With run-time argument --no-threads
+            // our test runner will not properly filter test cases that can't be
+            // run because agents can't be started, and so we do a little
+            // filtering here: We will quietly succeed and exit if an agent test
+            // should not have been run because threads cannot be started.
+            //
+            // Firefox complication: The test cases that use $262.agent can't
+            // currently work in the browser, so for now we rely on them not
+            // being run at all.
+
+            if (!sabTestable) {
+                return {
+                    _notAvailable() {
+                        // See comment above.
+                        if (!hasThreads && shellCode) {
+                            global.reportCompare(0,0);
+                            global.quit(0);
+                        }
+                        throw new Error("Agents not available");
+                    },
+                    start(script) { this._notAvailable() },
+                    broadcast(sab, id) { this._notAvailable() },
+                    getReport() { this._notAvailable() },
+                    sleep(s) { this._notAvailable() }
+                }
+            }
+
+            // The SpiderMonkey implementation uses a designated shared buffer _ia
+            // for coordination, and spinlocks for everything except sleeping.
+
+            var _MSG_LOC = 0;           // Low bit set: broadcast available; High bits: seq #
+            var _ID_LOC = 1;            // ID sent with broadcast
+            var _ACK_LOC = 2;           // Worker increments this to ack that broadcast was received
+            var _RDY_LOC = 3;           // Worker increments this to ack that worker is up and running
+            var _LOCKTXT_LOC = 4;       // Writer lock for the text buffer: 0=open, 1=closed
+            var _NUMTXT_LOC = 5;        // Count of messages in text buffer
+            var _NEXT_LOC = 6;          // First free location in the buffer
+            var _SLEEP_LOC = 7;         // Used for sleeping
+
+            var _FIRST = 10;            // First location of first message
+
+            var _ia = new Int32Array(new SharedArrayBuffer(65536));
+            _ia[_NEXT_LOC] = _FIRST;
+
+            var _worker_prefix =
+// BEGIN WORKER PREFIX
+`if (typeof $262 == 'undefined')
+    $262 = {};
+$262.agent = (function () {
+    var _ia = new Int32Array(getSharedArrayBuffer());
+    var agent = {
+        receiveBroadcast(receiver) {
+            var k;
+            while (((k = Atomics.load(_ia, ${_MSG_LOC})) & 1) == 0)
+                ;
+            var received_sab = getSharedArrayBuffer();
+            var received_id = Atomics.load(_ia, ${_ID_LOC});
+            Atomics.add(_ia, ${_ACK_LOC}, 1);
+            while (Atomics.load(_ia, ${_MSG_LOC}) == k)
+                ;
+            receiver(received_sab, received_id);
+        },
+
+        report(msg) {
+            while (Atomics.compareExchange(_ia, ${_LOCKTXT_LOC}, 0, 1) == 1)
+                ;
+            msg = "" + msg;
+            var i = _ia[${_NEXT_LOC}];
+            _ia[i++] = msg.length;
+            for ( let j=0 ; j < msg.length ; j++ )
+                _ia[i++] = msg.charCodeAt(j);
+            _ia[${_NEXT_LOC}] = i;
+            Atomics.add(_ia, ${_NUMTXT_LOC}, 1);
+            Atomics.store(_ia, ${_LOCKTXT_LOC}, 0);
+        },
+
+        sleep(s) {
+            Atomics.wait(_ia, ${_SLEEP_LOC}, 0, s);
+        },
+
+        leaving() {}
+    };
+    Atomics.add(_ia, ${_RDY_LOC}, 1);
+    return agent;
+})();`;
+// END WORKER PREFIX
+
+            return {
+                _numWorkers: 0,
+                _numReports: 0,
+                _reportPtr: _FIRST,
+
+                _bailIfNotAvailable() {
+                    if (!sabTestable) {
+                        // See comment above.
+                        if (!hasThreads && shellCode) {
+                            global.reportCompare(0,0);
+                            global.quit(0);
+                        }
+                        throw new Error("Agents not available");
+                    }
+                },
+
+                start(script) {
+                    this._bailIfNotAvailable();
+                    setSharedArrayBuffer(_ia.buffer);
+                    var oldrdy = Atomics.load(_ia, _RDY_LOC);
+                    evalInWorker(_worker_prefix + script);
+                    while (Atomics.load(_ia, _RDY_LOC) == oldrdy)
+                        ;
+                    this._numWorkers++;
+                },
+
+                broadcast(sab, id) {
+                    this._bailIfNotAvailable();
+                    setSharedArrayBuffer(sab);
+                    Atomics.store(_ia, _ID_LOC, id);
+                    Atomics.store(_ia, _ACK_LOC, 0);
+                    Atomics.add(_ia, _MSG_LOC, 1);
+                    while (Atomics.load(_ia, _ACK_LOC) < this._numWorkers)
+                        ;
+                    Atomics.add(_ia, _MSG_LOC, 1);
+                },
+
+                getReport() {
+                    this._bailIfNotAvailable();
+                    if (this._numReports == Atomics.load(_ia, _NUMTXT_LOC))
+                        return null;
+                    var s = "";
+                    var i = this._reportPtr;
+                    var len = _ia[i++];
+                    for ( let j=0 ; j < len ; j++ )
+                        s += String.fromCharCode(_ia[i++]);
+                    this._reportPtr = i;
+                    this._numReports++;
+                    return s;
+                },
+
+                sleep(s) {
+                    this._bailIfNotAvailable();
+                    Atomics.wait(_ia, _SLEEP_LOC, 0, s);
+                },
+            };
+        })()
+    };
+})(this);
+
+var $mozAsyncTestDone = false;
+function $DONE(failure) {
+    // This function is generally called from within a Promise handler, so any
+    // exception thrown by this method will be swallowed and most likely
+    // ignored by the Promise machinery.
+    if ($mozAsyncTestDone) {
+        reportFailure("$DONE() already called");
+        return;
+    }
+    $mozAsyncTestDone = true;
+
+    if (failure)
+        reportFailure(failure);
+    else
+        reportCompare(0, 0);
+}
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/bar.js
@@ -0,0 +1,2 @@
+
+reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/baz.js
@@ -0,0 +1,2 @@
+
+reportCompare(0, 0);
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/import/files/local/smTempBranch/temp42/foo.js
@@ -0,0 +1,2 @@
+
+reportCompare(0, 0);
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/expected/import/output.txt
@@ -0,0 +1,14 @@
+From the branch smTempBranch in {{folder}} 
+
+Files being copied to the local folder: 
+test/language/export/escaped-foobarbaz.js
+test/temp42/bar.js
+test/temp42/baz.js
+test/temp42/foo.js
+
+Deleted files (use this list to update the skip list): 
+test/language/export/escaped-from.js
+
+Renamed files (already added with the new names): 
+ rename test/language/export/{escaped-default.js => escaped-foobarbaz.js} (100%)
+
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/.ignore.js
@@ -0,0 +1,1 @@
+.
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/browser.js
@@ -0,0 +1,1 @@
+// not an empty file
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/ignore.js~
@@ -0,0 +1,1 @@
+.
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/multi-header.js
@@ -0,0 +1,20 @@
+// |reftest| skip-if(!this.hasOwnProperty('foobar')||outro()) error:SyntaxError module -- foo bar  baz
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Jeff Walden <jwalden+code@mit.edu>
+esid: sec-let-and-const-declarations
+description: >
+  Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration
+  variable name.  Therefore ASI doesn't apply, and so the |0| where a |=| was
+  expected is a syntax error.
+negative:
+  phase: early
+  type: SyntaxError
+---*/
+
+function f() {
+    let
+    await 0;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/reftest-and-frontmatter-error.js
@@ -0,0 +1,19 @@
+// |reftest| error:SyntaxError
+
+/*---
+esid: sec-let-and-const-declarations
+description: >
+  Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration
+  variable name.  Therefore ASI doesn't apply, and so the |0| where a |=| was
+  expected is a syntax error.
+negative:
+  phase: runtime
+  type: SyntaxError
+---*/
+
+eval(`
+    function f() {
+        let
+        await 0;
+    }
+`);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/reftest-error-syntaxerror.js
@@ -0,0 +1,15 @@
+// |reftest| error:SyntaxError
+
+/*---
+author: Jeff Walden <jwalden+code@mit.edu>
+esid: sec-let-and-const-declarations
+description: >
+  Outside AsyncFunction, |await| is a perfectly cromulent LexicalDeclaration
+  variable name.  Therefore ASI doesn't apply, and so the |0| where a |=| was
+  expected is a syntax error.
+---*/
+
+function f() {
+    let
+    await 0;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/regular.js
@@ -0,0 +1,18 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+author: Jeff Walden <jwalden+code@mit.edu>
+esid: sec-let-and-const-declarations
+description: >
+  |await| is excluded from LexicalDeclaration by grammar parameter, in
+  AsyncFunction.  Therefore |let| followed by |await| inside AsyncFunction is
+  an ASI opportunity, and this code must parse without error.
+---*/
+
+async function f() {
+    let
+    await 0;
+}
+
+reportCompare(true, f instanceof Function);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/reportCompare.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2017 Mozilla Corporation. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: reportCompare
+---*/
+
+
+var a = 42;
+
+reportCompare(0, 0)
+reportCompare(0, 0);
+reportCompare(0, 0, "ok")
+reportCompare(true, true, "ok"); // comment
+reportCompare(trueish, true, "ok");
+
+reportCompare ( 0 , 0  ) ;
+reportCompare ( 0    , 0, "ok")
+reportCompare ( true, /*lol*/true, "ok");
+
+reportCompare(null, null, "test");
+reportCompare(true, f instanceof Function);
+reportCompare(true, true)
+reportCompare(true, true);
+reportCompare(true, true, "don't crash");
+reportCompare(true,true);
+this.reportCompare && reportCompare(0, 0, "ok");
+this.reportCompare && reportCompare(true, true);
+this.reportCompare && reportCompare(true,true);
+
+reportCompare(42, foo);
+
+    reportCompare(0, 0); // this was a reportCompare Line
+
+reportCompare(
+    true,
+    true
+);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/test/fixtures/export/shell.js
@@ -0,0 +1,1 @@
+// not an empty file
new file mode 100644
new file mode 100644
new file mode 100644
new file mode 100755
--- /dev/null
+++ b/js/src/tests/test/run.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+# Adapted from https://github.com/tc39/test262/blob/master/tools/generation/test/run.py
+
+import shutil, subprocess, contextlib, tempfile, sys, os, unittest
+
+testDir = os.path.dirname(os.path.relpath(__file__))
+OUT_DIR = os.path.join(testDir, 'out')
+EXPECTED_DIR = os.path.join(testDir, 'expected')
+ex = os.path.join(testDir, '..', 'test262-export.py')
+importExec = os.path.join(testDir, '..', 'test262-update.py')
+test262Url = 'git://github.com/tc39/test262.git'
+
+@contextlib.contextmanager
+def TemporaryDirectory():
+    tmpDir = tempfile.mkdtemp()
+    try:
+        yield tmpDir
+    finally:
+        shutil.rmtree(tmpDir)
+
+class TestExport(unittest.TestCase):
+    maxDiff = None
+
+    def exportScript(self):
+        relpath = os.path.relpath(os.path.join(testDir, 'fixtures', 'export'))
+        sp = subprocess.Popen(
+            [ex, relpath, '--out', OUT_DIR],
+            stdout=subprocess.PIPE)
+        stdout, stderr = sp.communicate()
+        return dict(stdout=stdout, stderr=stderr, returncode=sp.returncode)
+
+    def importLocal(self):
+        with TemporaryDirectory() as cloneDir:
+            branch = 'smTempBranch'
+            # Clone Test262 to a local branch
+            subprocess.check_call(
+                ['git', 'clone', '--depth=1', test262Url, cloneDir]
+            )
+            # Checkout to a new branch
+            subprocess.check_call(
+                ['git', '-C', cloneDir, 'checkout', '-b', branch]
+            )
+            # Make changes on the new branch
+            # Remove test/language/export/escaped-from.js
+            subprocess.check_call(
+                ['git', '-C', cloneDir, 'rm',
+                    'test/language/export/escaped-from.js']
+            )
+            # Rename test/language/export/escaped-default.js
+            subprocess.check_call(
+                ['git', '-C', cloneDir, 'mv',
+                    'test/language/export/escaped-default.js',
+                    'test/language/export/escaped-foobarbaz.js',
+                ]
+            )
+            # Copy fixtures files
+            fixturesDir = os.path.join(testDir, 'fixtures', 'import', 'files')
+            shutil.copytree(fixturesDir, os.path.join(cloneDir, 'test', 'temp42'))
+            # Stage and Commit changes
+            subprocess.check_call(['git', '-C', cloneDir, 'add', '.'])
+            subprocess.check_call(['git', '-C', cloneDir, 'commit', '-m', '"local foo"'])
+
+            # Run import script
+            print("%s --local %s --out %s" % (importExec, cloneDir, OUT_DIR))
+            sp = subprocess.Popen(
+                [importExec, '--local', cloneDir, '--out', OUT_DIR],
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE
+            )
+            stdoutdata, _ = sp.communicate()
+
+            return stdoutdata, sp.returncode, cloneDir
+
+    def isTestFile(self, filename):
+        return not (
+            filename.startswith('.') or
+            filename.startswith('#') or
+            filename.endswith('~')
+        )
+
+    def getFiles(self, path):
+        names = []
+        for root, _, fileNames in os.walk(path):
+            for fileName in filter(self.isTestFile, fileNames):
+                names.append(os.path.join(root, fileName))
+        names.sort()
+        return names
+
+    def compareTrees(self, targetName):
+        expectedPath = os.path.join(EXPECTED_DIR, targetName)
+        actualPath = OUT_DIR
+
+        expectedFiles = self.getFiles(expectedPath)
+        actualFiles = self.getFiles(actualPath)
+
+        self.assertListEqual(
+            map(lambda x: os.path.relpath(x, expectedPath), expectedFiles),
+            map(lambda x: os.path.relpath(x, actualPath), actualFiles))
+
+        for expectedFile, actualFile in zip(expectedFiles, actualFiles):
+            with open(expectedFile) as expectedHandle:
+                with open(actualFile) as actualHandle:
+                    self.assertMultiLineEqual(
+                        expectedHandle.read(),
+                        actualHandle.read())
+
+    def compareContents(self, output, filePath, folder):
+        with open(filePath, "rb") as file:
+            expected = file.read()
+
+        expected = expected.replace('{{folder}}', folder)
+        self.assertMultiLineEqual(output, expected)
+
+    def tearDown(self):
+        shutil.rmtree(OUT_DIR, ignore_errors=True)
+
+    def test_export(self):
+        result = self.exportScript()
+        self.assertEqual(result['returncode'], 0)
+        self.compareTrees('export')
+
+    def test_import_local(self):
+        output, returncode, folder = self.importLocal()
+        self.assertEqual(returncode, 0)
+        self.compareTrees(os.path.join('import', 'files'))
+        self.compareContents(
+            output,
+            os.path.join(testDir, 'expected', 'import', 'output.txt'),
+            folder
+        )
+
+if __name__ == '__main__':
+    unittest.main()
new file mode 100755
--- /dev/null
+++ b/js/src/tests/test262-export.py
@@ -0,0 +1,359 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from __future__ import print_function
+
+import contextlib
+import os
+import re
+import tempfile
+import shutil
+import sys
+import yaml
+
+from functools import partial
+from itertools import chain, imap
+
+# Skip all common files used to support tests for jstests
+# These files are listed in the README.txt
+SUPPORT_FILES = set(["browser.js", "shell.js", "template.js", "user.js",
+    "js-test-driver-begin.js", "js-test-driver-end.js"])
+
+FRONTMATTER_WRAPPER_PATTERN = re.compile(
+    r'/\*\---\n([\s]*)((?:\s|\S)*)[\n\s*]---\*/', flags=re.DOTALL)
+
+def convertTestFile(source):
+    """
+    Convert a jstest test to a compatible Test262 test file.
+    """
+
+    source = convertReportCompare(source)
+    source = updateMeta(source)
+    source = insertCopyrightLines(source)
+
+    return source
+
+def convertReportCompare(source):
+    """
+    Captures all the reportCompare and convert them accordingly.
+
+    Cases with reportCompare calls where the arguments are the same and one of
+    0, true, or null, will be discarded as they are not necessary for Test262.
+
+    Otherwise, reportCompare will be replaced with assert.sameValue, as the
+    equivalent in Test262
+    """
+
+    def replaceFn(matchobj):
+        actual = matchobj.group(1)
+        expected = matchobj.group(2)
+
+        if actual == expected and actual in ["0", "true", "null"]:
+            return ""
+
+        return matchobj.group()
+
+    newSource = re.sub(
+        r'.*reportCompare\s*\(\s*(\w*)\s*,\s*(\w*)\s*(,\s*\S*)?\s*\)\s*;*\s*',
+        replaceFn,
+        source
+    )
+
+    return re.sub(r'\breportCompare\b', "assert.sameValue", newSource)
+
+def fetchReftestEntries(reftest):
+    """
+    Collects and stores the entries from the reftest header.
+    """
+
+    # TODO: fails, slow, skip, random, random-if
+
+    features = []
+    error = None
+    comments = None
+    module = False
+
+    # should capture conditions to skip
+    matchesSkip = re.search(r'skip-if\((.*)\)', reftest)
+    if matchesSkip:
+        matches = matchesSkip.group(1).split("||")
+        for match in matches:
+            # captures a features list
+            dependsOnProp = re.search(
+                r'!this.hasOwnProperty\([\'\"](.*?)[\'\"]\)', match)
+            if dependsOnProp:
+                features.append(dependsOnProp.group(1))
+            else:
+                print("# Can't parse the following skip-if rule: %s" % match)
+
+    # should capture the expected error
+    matchesError = re.search(r'error:\s*(\w*)', reftest)
+    if matchesError:
+        # The metadata from the reftests won't say if it's a runtime or an
+        # early error. This specification is required for the frontmatter tags.
+        error = matchesError.group(1)
+
+    # just tells if it's a module
+    matchesModule = re.search(r'\bmodule\b', reftest)
+    if matchesModule:
+        module = True
+
+    # captures any comments
+    matchesComments = re.search(r' -- (.*)', reftest)
+    if matchesComments:
+        comments = matchesComments.group(1)
+
+    return {
+        "features": features,
+        "error": error,
+        "module": module,
+        "info": comments
+    }
+
+def parseHeader(source):
+    """
+    Parse the source to return it with the extracted the header
+    """
+    from lib.manifest import TEST_HEADER_PATTERN_INLINE
+
+    # Bail early if we do not start with a single comment.
+    if not source.startswith("//"):
+        return (source, {})
+
+    # Extract the token.
+    part, _, _ = source.partition("\n")
+    matches = TEST_HEADER_PATTERN_INLINE.match(part)
+
+    if matches and matches.group(0):
+        reftest = matches.group(0)
+
+        # Remove the found header from the source;
+        # Fetch and return the reftest entries
+        return (source.replace(reftest + "\n", ""), fetchReftestEntries(reftest))
+
+    return (source, {})
+
+def extractMeta(source):
+    """
+    Capture the frontmatter metadata as yaml if it exists.
+    Returns a new dict if it doesn't.
+    """
+
+    match = FRONTMATTER_WRAPPER_PATTERN.search(source)
+    if not match:
+        return {}
+
+    indent, frontmatter_lines = match.groups()
+
+    unindented = re.sub('^%s' % indent, '', frontmatter_lines)
+
+    return yaml.safe_load(unindented)
+
+def updateMeta(source):
+    """
+    Captures the reftest meta and a pre-existing meta if any and merge them
+    into a single dict.
+    """
+
+    # Extract the reftest data from the source
+    source, reftest = parseHeader(source)
+
+    # Extract the frontmatter data from the source
+    frontmatter = extractMeta(source)
+
+    # Merge the reftest and frontmatter
+    merged = mergeMeta(reftest, frontmatter)
+
+    # Cleanup the metadata
+    properData = cleanupMeta(merged)
+
+    return insertMeta(source, properData)
+
+def cleanupMeta(meta):
+    """
+    Clean up all the frontmatter meta tags. This is not a lint tool, just a
+    simple cleanup to remove trailing spaces and duplicate entries from lists.
+    """
+
+    # Populate required tags
+    for tag in ("description", "esid"):
+        meta.setdefault(tag, "pending")
+
+    # Trim values on each string tag
+    for tag in ("description", "esid", "es5id", "es6id", "info", "author"):
+        if tag in meta:
+            meta[tag] = meta[tag].strip()
+
+    # Remove duplicate entries on each list tag
+    for tag in ("features", "flags", "includes"):
+        if tag in meta:
+            # We need the list back for the yaml dump
+            meta[tag] = list(set(meta[tag]))
+
+    if "negative" in meta:
+        # If the negative tag exists, phase needs to be present and set
+        if meta["negative"].get("phase") not in ("early", "runtime"):
+            print("Warning: the negative.phase is not properly set.\n" + \
+                "Ref https://github.com/tc39/test262/blob/master/INTERPRETING.md#negative")
+        # If the negative tag exists, type is required
+        if "type" not in meta["negative"]:
+            print("Warning: the negative.type is not set.\n" + \
+                "Ref https://github.com/tc39/test262/blob/master/INTERPRETING.md#negative")
+
+    return meta
+
+def mergeMeta(reftest, frontmatter):
+    """
+    Merge the metadata from reftest and an existing frontmatter and populate
+    required frontmatter fields properly.
+    """
+
+    # Merge the meta from reftest to the frontmatter
+
+    if "features" in reftest:
+        frontmatter.setdefault("features", []) \
+            .extend(reftest.get("features", []))
+
+    # Only add the module flag if the value from reftest is truish
+    if reftest.get("module"):
+        frontmatter.setdefault("flags", []).append("module")
+
+    # Add any comments to the info tag
+    info = reftest.get("info")
+    if info:
+        # Open some space in an existing info text
+        if "info" in frontmatter:
+            frontmatter["info"] += "\n\n  \%" % info
+        else:
+            frontmatter["info"] = info
+
+    # Set the negative flags
+    if "error" in reftest:
+        error = reftest["error"]
+        if "negative" not in frontmatter:
+            frontmatter["negative"] = {
+                # This code is assuming error tags are early errors, but they
+                # might be runtime errors as well.
+                # From this point, this code can also print a warning asking to
+                # specify the error phase in the generated code or fill the
+                # phase with an empty string.
+                "phase": "early",
+                "type": error
+            }
+        # Print a warning if the errors don't match
+        elif frontmatter["negative"].get("type") != error:
+            print("Warning: The reftest error doesn't match the existing " + \
+                "frontmatter error. %s != %s" % (error,
+                frontmatter["negative"]["type"]))
+
+    return frontmatter
+
+def insertCopyrightLines(source):
+    """
+    Insert the copyright lines into the file.
+    """
+    from datetime import date
+
+    lines = []
+
+    if not re.match(r'\/\/\s+Copyright.*\. All rights reserved.', source):
+        year = date.today().year
+        lines.append("// Copyright (C) %s Mozilla Corporation. All rights reserved." % year)
+        lines.append("// This code is governed by the BSD license found in the LICENSE file.")
+        lines.append("\n")
+
+    return "\n".join(lines) + source
+
+def insertMeta(source, frontmatter):
+    """
+    Insert the formatted frontmatter into the file, use the current existing
+    space if any
+    """
+    lines = []
+
+    lines.append("/*---")
+
+    for (key, value) in frontmatter.items():
+        if key in ("description", "info"):
+            lines.append("%s: |" % key)
+            lines.append("  " + yaml.dump(value, encoding="utf8",
+                ).strip().replace('\n...', ''))
+        else:
+            lines.append(yaml.dump({key: value}, encoding="utf8",
+                default_flow_style=False).strip())
+
+    lines.append("---*/")
+
+    match = FRONTMATTER_WRAPPER_PATTERN.search(source)
+
+    if match:
+        return source.replace(match.group(0), "\n".join(lines))
+    else:
+        return "\n".join(lines) + source
+
+def exportTest262(args):
+    src = os.path.abspath(args.src[0])
+    outDir = os.path.abspath(args.out)
+
+    # Create the output directory from scratch.
+    if os.path.isdir(outDir):
+        shutil.rmtree(outDir)
+
+    # Process all test directories recursively.
+    for (dirPath, _, fileNames) in os.walk(src):
+        relPath = os.path.relpath(dirPath, src)
+
+        relOutDir = os.path.join(outDir, relPath)
+
+        # This also creates the own outDir folder
+        if not os.path.exists(relOutDir):
+            os.makedirs(relOutDir)
+
+        for fileName in fileNames:
+            # Skip browser.js and shell.js files
+            if fileName == "browser.js" or fileName == "shell.js":
+                continue
+
+            filePath = os.path.join(dirPath, fileName)
+            testName = os.path.relpath(filePath, src) # captures folder/fileName
+
+            # Copy non-test files as is.
+            (_, fileExt) = os.path.splitext(fileName)
+            if fileExt != ".js":
+                shutil.copyfile(filePath, os.path.join(outDir, testName))
+                print("C %s" % testName)
+                continue
+
+            # Read the original test source and preprocess it for Test262
+            with open(filePath, "rb") as testFile:
+                testSource = testFile.read()
+
+            if not testSource:
+                print("SKIPPED %s" % testName)
+                continue
+
+            newSource = convertTestFile(testSource)
+
+            with open(os.path.join(outDir, testName), "wb") as output:
+                output.write(newSource)
+
+            print("SAVED %s" % testName)
+
+if __name__ == "__main__":
+    import argparse
+
+    # This script must be run from js/src/tests to work correctly.
+    if "/".join(os.path.normpath(os.getcwd()).split(os.sep)[-3:]) != "js/src/tests":
+        raise RuntimeError("%s must be run from js/src/tests" % sys.argv[0])
+
+    parser = argparse.ArgumentParser(description="Export tests to match Test262 file compliance.")
+    parser.add_argument("--out", default="test262/export",
+                        help="Output directory. Any existing directory will be removed! (default: %(default)s)")
+    parser.add_argument("src", nargs="+", help="Source folder with test files to export")
+    parser.set_defaults(func=exportTest262)
+    args = parser.parse_args()
+    args.func(args)
--- a/js/src/tests/test262-update.py
+++ b/js/src/tests/test262-update.py
@@ -326,17 +326,17 @@ def process_test262(test262Dir, test262O
 
     # Process all test directories recursively.
     for (dirPath, dirNames, fileNames) in os.walk(testDir):
         relPath = os.path.relpath(dirPath, testDir)
         if relPath == ".":
             continue
 
         # Skip creating a "prs" directory if it already exists
-        if relPath != "prs" or not os.path.exists(os.path.join(test262OutDir, relPath)):
+        if relPath not in ("prs", "local") and not os.path.exists(os.path.join(test262OutDir, relPath)):
             os.makedirs(os.path.join(test262OutDir, relPath))
 
         includeSet = set()
         includesMap[relPath] = includeSet
 
         if relPath in explicitIncludes:
             includeSet.update(explicitIncludes[relPath])
 
@@ -356,137 +356,233 @@ def process_test262(test262Dir, test262O
                 testSource = testFile.read()
 
             for (newFileName, newSource) in convertTestFile(test262parser, testSource, testName, includeSet, strictTests):
                 writeTestFile(test262OutDir, newFileName, newSource)
 
         # Add shell.js and browers.js files for the current directory.
         writeShellAndBrowserFiles(test262OutDir, harnessDir, includesMap, localIncludesMap, relPath)
 
-def fetch_pr_files(outDir, inDir, prNumber):
+def fetch_local_changes(inDir, outDir, srcDir, strictTests):
+    """
+    Fetch the changes from a local clone of Test262.
+
+    1. Get the list of file changes made by the current branch used on Test262 (srcDir).
+    2. Copy only the (A)dded, (C)opied, (M)odified, and (R)enamed files to inDir.
+    3. inDir is treated like a Test262 checkout, where files will be converted.
+    4. Fetches the current branch name to set the outDir.
+    5. Processed files will be added to `<outDir>/local/<branchName>`.
+    """
+    import subprocess
+
+    # TOOD: fail if it's in the master branch? or require a branch name?
+
+    # Checks for unstaged or non committed files. A clean branch provides a clean status.
+    status = subprocess.check_output(
+        ("git -C %s status --porcelain" % srcDir).split(" ")
+    )
+
+    if status.strip():
+        raise RuntimeError(
+            "Please commit files and cleanup the local test262 folder before importing files.\nCurrent status: \n%s"
+            % status)
+
+    # Captures the branch name to be used on the output
+    branchName = subprocess.check_output(
+        ("git -C %s rev-parse --abbrev-ref HEAD" % srcDir).split(" ")).split("\n")[0]
+
+    # Fetches the file names to import
+    files = subprocess.check_output(
+        ("git -C %s diff master --diff-filter=ACMR --name-only" % srcDir).split(" ")
+    )
+
+    # Fetches the deleted files to print an output log. This can be used to
+    # set up the skip list, if necessary.
+    deletedFiles = subprocess.check_output(
+        ("git -C %s diff master --diff-filter=D --name-only" % srcDir).split(" ")
+    )
+
+    # Fetches the modified files as well for logging to support maintenance
+    # in the skip list.
+    modifiedFiles = subprocess.check_output(
+        ("git -C %s diff master --diff-filter=M --name-only" % srcDir).split(" ")
+    )
+
+    # Fetches the renamed files for the same reason, this avoids duplicate
+    # tests if running the new local folder and the general imported Test262
+    # files.
+    renamedFiles = subprocess.check_output(
+        ("git -C %s diff master --diff-filter=R --summary" % srcDir).split(" ")
+    )
+
+    # Print some friendly output
+    print("From the branch %s in %s \n" % (branchName, srcDir))
+    print("Files being copied to the local folder: \n%s" % files)
+    if deletedFiles:
+        print("Deleted files (use this list to update the skip list): \n%s" % deletedFiles)
+    if modifiedFiles:
+        print("Modified files (use this list to update the skip list): \n%s" % modifiedFiles)
+    if renamedFiles:
+        print("Renamed files (already added with the new names): \n%s" % renamedFiles)
+
+    for f in files.splitlines():
+        # Capture the subdirectories names to recreate the file tree
+        # TODO: join the file tree with -- instead of multiple subfolders?
+        fileTree = os.path.join(inDir, os.path.dirname(f))
+        if not os.path.exists(fileTree):
+            os.makedirs(fileTree)
+
+        shutil.copyfile(
+            os.path.join(srcDir, f),
+            os.path.join(fileTree, os.path.basename(f))
+        )
+
+    # Extras from Test262. Copy the current support folders - including the
+    # harness - for a proper conversion process
+    shutil.copytree(os.path.join(srcDir, "tools"), os.path.join(inDir, "tools"))
+    shutil.copytree(os.path.join(srcDir, "harness"), os.path.join(inDir, "harness"))
+
+    # Reset any older directory in the output using the same branch name
+    outDir = os.path.join(outDir, "local", branchName)
+    if os.path.isdir(outDir):
+        shutil.rmtree(outDir)
+    os.makedirs(outDir)
+
+    process_test262(inDir, outDir, strictTests)
+
+def fetch_pr_files(inDir, outDir, prNumber, strictTests):
     import requests
 
-    prTestsOutDir = os.path.join(outDir, prNumber)
+    prTestsOutDir = os.path.join(outDir, "prs", prNumber)
     if os.path.isdir(prTestsOutDir):
         print("Removing folder %s" % prTestsOutDir)
         shutil.rmtree(prTestsOutDir)
+    os.makedirs(prTestsOutDir)
 
     # Reuses current Test262 clone's harness and tools folders only, the clone's test/
     # folder can be discarded from here
     shutil.rmtree(os.path.join(inDir, "test"))
 
     prRequest = requests.get("https://api.github.com/repos/tc39/test262/pulls/%s" % prNumber)
     prRequest.raise_for_status()
 
     pr = prRequest.json()
 
     if (pr["state"] != "open"):
         # Closed PR, remove respective files from folder
-        print("PR %s is closed" % prNumber)
-    else:
-        files = requests.get("https://api.github.com/repos/tc39/test262/pulls/%s/files" % prNumber)
-        files.raise_for_status()
+        return print("PR %s is closed" % prNumber)
+
+    files = requests.get("https://api.github.com/repos/tc39/test262/pulls/%s/files" % prNumber)
+    files.raise_for_status()
+
+    for item in files.json():
+        if not item["filename"].startswith("test/"):
+            continue
+
+        filename = item["filename"]
+        fileStatus = item["status"]
+
+        print("%s %s" % (fileStatus, filename))
+
+        # Do not add deleted files
+        if fileStatus == "removed":
+            continue
 
-        for item in files.json():
-            if not item["filename"].startswith("test/"):
-                continue
+        contents = requests.get(item["raw_url"])
+        contents.raise_for_status()
+
+        fileText = contents.text
+
+        filePathDirs = os.path.join(inDir, *filename.split("/")[:-1])
 
-            filename = item["filename"]
-            fileStatus = item["status"]
+        if not os.path.isdir(filePathDirs):
+            os.makedirs(filePathDirs)
 
-            print("%s %s" % (fileStatus, filename))
+        with io.open(os.path.join(inDir, *filename.split("/")), "wb") as output_file:
+            output_file.write(fileText.encode('utf8'))
+
+    process_test262(inDir, prTestsOutDir, strictTests)
+
+def general_update(inDir, outDir, strictTests):
+    import subprocess
 
-            # Do not add deleted files
-            if fileStatus == "removed":
-                continue
+    restoreLocalTestsDir = False
+    restorePrsTestsDir = False
+    localTestsOutDir = os.path.join(outDir, "local")
+    prsTestsOutDir = os.path.join(outDir, "prs")
 
-            contents = requests.get(item["raw_url"])
-            contents.raise_for_status()
+    # Stash test262/local and test262/prs. Currently the Test262 repo does not have any
+    # top-level subdirectories named "local" or "prs".
+    # This prevents these folders from being removed during the update process.
+    if os.path.isdir(localTestsOutDir):
+        shutil.move(localTestsOutDir, inDir)
+        restoreLocalTestsDir = True
 
-            fileText = contents.text
+    if os.path.isdir(prsTestsOutDir):
+        shutil.move(prsTestsOutDir, inDir)
+        restorePrsTestsDir = True
 
-            # Prefix the PRs tests dir with test/ so files are processed as Test262 files
-            prsTestsDir = "test/prs/%s" % prNumber
-            filePathDirs = os.path.join(inDir, prsTestsDir, *filename.split("/")[1:-1])
+    # Create the output directory from scratch.
+    if os.path.isdir(outDir):
+        shutil.rmtree(outDir)
+    os.makedirs(outDir)
+
+    # Copy license file.
+    shutil.copyfile(os.path.join(inDir, "LICENSE"), os.path.join(outDir, "LICENSE"))
 
-            if not os.path.isdir(filePathDirs):
-                os.makedirs(filePathDirs)
+    # Create the git info file.
+    with io.open(os.path.join(outDir, "GIT-INFO"), "wb") as info:
+        subprocess.check_call(["git", "-C", inDir, "log", "-1"], stdout=info)
+
+    # Copy the test files.
+    process_test262(inDir, outDir, strictTests)
 
-            filenameInDir = os.path.join(inDir, prsTestsDir, *filename.split("/")[1:])
+    # Move test262/local back.
+    if restoreLocalTestsDir:
+        shutil.move(os.path.join(inDir, "local"), outDir)
 
-            with io.open(filenameInDir, "wb") as output_file:
-                output_file.write(fileText.encode('utf8'))
+    # Restore test262/prs if necessary after a general Test262 update.
+    if restorePrsTestsDir:
+        shutil.move(os.path.join(inDir, "prs"), outDir)
 
 def update_test262(args):
     import subprocess
 
     url = args.url
     branch = args.branch
     revision = args.revision
     outDir = args.out
     prNumber = args.pull
+    srcDir = args.local
 
     if not os.path.isabs(outDir):
         outDir = os.path.join(os.getcwd(), outDir)
 
     strictTests = args.strict
-    localTestsOutDir = os.path.join(outDir, "local")
-    prsTestsOutDir = os.path.join(outDir, "prs")
 
     # Download the requested branch in a temporary directory.
     with TemporaryDirectory() as inDir:
-        restoreLocalTestsDir = False
-        restorePrsTestsDir = False
+        # If it's a local import, skip the git clone parts.
+        if srcDir:
+            return fetch_local_changes(inDir, outDir, srcDir, strictTests)
 
         if revision == "HEAD":
             subprocess.check_call(["git", "clone", "--depth=1", "--branch=%s" % branch, url, inDir])
         else:
             subprocess.check_call(["git", "clone", "--single-branch", "--branch=%s" % branch, url, inDir])
             subprocess.check_call(["git", "-C", inDir, "reset", "--hard", revision])
 
-        # If a PR number is provided, fetches only the new and modified files from that PR.
-        # It also creates a new folder for that PR or replaces if it already exists, without
-        # updating the regular Test262 tests.
+        # If a PR number is provided, fetches only the new and modified files
+        # from that PR. It also creates a new folder for that PR or replaces if
+        # it already exists, without updating the regular Test262 tests.
         if prNumber:
-            fetch_pr_files(prsTestsOutDir, inDir, prNumber)
-        # Without a specific PR, follows through a regular copy.
-        else:
-            # Stash test262/local and test262/prs. Currently the Test262 repo does not have any
-            # top-level subdirectories named "local" or "prs".
-            # This prevents these folders from being removed during the update process.
-            if os.path.isdir(localTestsOutDir):
-                shutil.move(localTestsOutDir, inDir)
-                restoreLocalTestsDir = True
-
-            if os.path.isdir(prsTestsOutDir):
-                shutil.move(prsTestsOutDir, inDir)
-                restorePrsTestsDir = True
+            return fetch_pr_files(inDir, outDir, prNumber, strictTests)
 
-            # Create the output directory from scratch.
-            if os.path.isdir(outDir):
-                shutil.rmtree(outDir)
-            os.makedirs(outDir)
-
-            # Copy license file.
-            shutil.copyfile(os.path.join(inDir, "LICENSE"), os.path.join(outDir, "LICENSE"))
-
-            # Create the git info file.
-            with io.open(os.path.join(outDir, "GIT-INFO"), "wb") as info:
-                subprocess.check_call(["git", "-C", inDir, "log", "-1"], stdout=info)
-
-        # Copy the test files.
-        process_test262(inDir, outDir, strictTests)
-
-        # Move test262/local back.
-        if restoreLocalTestsDir:
-            shutil.move(os.path.join(inDir, "local"), outDir)
-
-        # Restore test262/prs if necessary after a general Test262 update.
-        if restorePrsTestsDir:
-            shutil.move(os.path.join(inDir, "prs"), outDir)
+        # Without a PR or a local import, follows through a regular copy.
+        general_update(inDir, outDir, strictTests)
 
 if __name__ == "__main__":
     import argparse
 
     # This script must be run from js/src/tests to work correctly.
     if "/".join(os.path.normpath(os.getcwd()).split(os.sep)[-3:]) != "js/src/tests":
         raise RuntimeError("%s must be run from js/src/tests" % sys.argv[0])
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -10710,16 +10710,25 @@ nsIFrame::AddSizeOfExcludingThisForTree(
   // We don't do this for Gecko because this stuff is stored in the nsPresArena
   // and so measured elsewhere.
   if (mStyleContext->IsServo()) {
     ServoStyleContext* sc = mStyleContext->AsServo();
     if (!aSizes.mState.HaveSeenPtr(sc)) {
       sc->AddSizeOfIncludingThis(aSizes,
                                  &aSizes.mLayoutComputedValuesNonDom);
     }
+
+    // And our additional style contexts.
+    int32_t index = 0;
+    while (auto* extra = GetAdditionalStyleContext(index++)) {
+      if (!aSizes.mState.HaveSeenPtr(extra)) {
+        extra->AsServo()->AddSizeOfIncludingThis(aSizes,
+                                                 &aSizes.mLayoutComputedValuesNonDom);
+      }
+    }
   }
 
   FrameChildListIterator iter(this);
   while (!iter.IsDone()) {
     for (const nsIFrame* f : iter.CurrentList()) {
       f->AddSizeOfExcludingThisForTree(aSizes);
     }
     iter.Next();
--- a/moz.build
+++ b/moz.build
@@ -74,17 +74,17 @@ if CONFIG['ENABLE_CLANG_PLUGIN']:
 DIRS += [
     'config',
     'python',
     'taskcluster',
     'testing/mozbase',
     'third_party/python',
 ]
 
-if CONFIG['MOZ_WIDGET_TOOLKIT']:
+if CONFIG['MOZ_WIDGET_TOOLKIT'] or not CONFIG['MOZ_BUILD_APP']:
     # These python manifests are included here so they get picked up without an objdir
     PYTHON_UNITTEST_MANIFESTS += [
         'layout/tools/reftest/selftest/python.ini',
         'testing/marionette/harness/marionette_harness/tests/harness_unit/python.ini',
         'testing/mochitest/tests/python/python.ini',
     ]
 
     CONFIGURE_SUBST_FILES += [
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -264,84 +264,108 @@ linux64-android-sdk-linux-repack:
         using: toolchain-script
         script: repack-android-sdk-linux.sh
         tc-vcs: false
         resources:
             - 'python/mozboot/**/*android*'
         toolchain-artifact: project/gecko/android-sdk/android-sdk-linux.tar.xz
         toolchain-alias: android-sdk-linux
 
+linux64-rust-1.20:
+    description: "rust repack"
+    treeherder:
+        kind: build
+        platform: toolchains/opt
+        symbol: TL(rust)
+        tier: 1
+    worker-type: aws-provisioner-v1/gecko-{level}-b-linux
+    worker:
+        docker-image: {in-tree: desktop-build}
+        max-run-time: 7200
+        env:
+          UPLOAD_DIR: artifacts
+    run:
+        using: toolchain-script
+        script: repack_rust.py
+        arguments: [
+            '--channel', '1.20.0',
+            '--host', 'x86_64-unknown-linux-gnu',
+            '--target', 'x86_64-unknown-linux-gnu',
+            '--target', 'i686-unknown-linux-gnu',
+        ]
+        toolchain-alias: linux64-rust
+        toolchain-artifact: public/build/rustc.tar.xz
+
 linux64-rust-1.19:
     description: "rust repack"
     treeherder:
         kind: build
         platform: toolchains/opt
-        symbol: TL(rust)
+        symbol: TL(rust-1.19)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: desktop-build}
         max-run-time: 7200
         env:
           UPLOAD_DIR: artifacts
     run:
         using: toolchain-script
         script: repack_rust.py
         arguments: [
             '--channel', '1.19.0',
             '--host', 'x86_64-unknown-linux-gnu',
             '--target', 'x86_64-unknown-linux-gnu',
             '--target', 'i686-unknown-linux-gnu',
         ]
-        toolchain-alias: linux64-rust
         toolchain-artifact: public/build/rustc.tar.xz
 
-linux64-rust-macos-1.19:
+linux64-rust-macos-1.20:
     description: "rust repack with macos-cross support"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(rust-macos)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: desktop-build}
         max-run-time: 7200
         env:
           UPLOAD_DIR: artifacts
     run:
         using: toolchain-script
         script: repack_rust.py
         arguments: [
-           '--channel', '1.19.0',
+           '--channel', '1.20.0',
            '--host', 'x86_64-unknown-linux-gnu',
            '--target', 'x86_64-unknown-linux-gnu',
            '--target', 'x86_64-apple-darwin',
         ]
         toolchain-alias: linux64-rust-macos
         toolchain-artifact: public/build/rustc.tar.xz
 
-linux64-rust-android-1.19:
+linux64-rust-android-1.20:
     description: "rust repack with android-cross support"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(rust-android)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: desktop-build}
         max-run-time: 7200
         env:
           UPLOAD_DIR: artifacts
     run:
         using: toolchain-script
         script: repack_rust.py
         arguments: [
-           '--channel', '1.19.0',
+           '--channel', '1.20.0',
            '--host', 'x86_64-unknown-linux-gnu',
            '--target', 'x86_64-unknown-linux-gnu',
            '--target', 'armv7-linux-androideabi',
            '--target', 'aarch64-linux-android',
            '--target', 'i686-linux-android',
         ]
         toolchain-alias: linux64-rust-android
         toolchain-artifact: public/build/rustc.tar.xz
--- a/taskcluster/ci/toolchain/windows.yml
+++ b/taskcluster/ci/toolchain/windows.yml
@@ -89,82 +89,105 @@ win64-clang-tidy:
         script: build-clang-tidy64-windows.sh
         resources:
             - 'build/clang-plugin/**'
             - 'build/build-clang/build-clang.py'
             - 'build/build-clang/clang-tidy-win32.json'
             - 'taskcluster/scripts/misc/build-clang-windows-helper64.sh'
         toolchain-artifact: public/build/clang-tidy.tar.bz2
 
-win64-rust-1.19:
+win64-rust-1.20:
     description: "rust repack"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TW64(rust)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: desktop-build}
         max-run-time: 7200
         env:
           UPLOAD_DIR: artifacts
     run:
         using: toolchain-script
         script: repack_rust.py
         arguments: [
-          '--channel', '1.19.0',
+          '--channel', '1.20.0',
           '--host', 'x86_64-pc-windows-msvc',
           '--target', 'x86_64-pc-windows-msvc',
         ]
         toolchain-alias: win64-rust
         toolchain-artifact: public/build/rustc.tar.bz2
 
-win32-rust-1.19:
+win64-rust-1.19:
+    description: "rust repack"
+    treeherder:
+        kind: build
+        platform: toolchains/opt
+        symbol: TW64(rust-1.19)
+        tier: 1
+    worker-type: aws-provisioner-v1/gecko-{level}-b-linux
+    worker:
+        docker-image: {in-tree: desktop-build}
+        max-run-time: 7200
+        env:
+          UPLOAD_DIR: artifacts
+    run:
+        using: toolchain-script
+        script: repack_rust.py
+        arguments: [
+          '--channel', '1.19.0',
+          '--host', 'x86_64-pc-windows-msvc',
+          '--target', 'x86_64-pc-windows-msvc',
+        ]
+        toolchain-artifact: public/build/rustc.tar.bz2
+
+win32-rust-1.20:
     description: "rust repack"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TW32(rust)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: desktop-build}
         max-run-time: 7200
         env:
           UPLOAD_DIR: artifacts
     run:
         using: toolchain-script
         script: repack_rust.py
         arguments: [
-          '--channel', '1.19.0',
+          '--channel', '1.20.0',
           '--host', 'i686-pc-windows-msvc',
           '--target', 'i686-pc-windows-msvc',
         ]
         toolchain-alias: win32-rust
         toolchain-artifact: public/build/rustc.tar.bz2
 
-mingw32-rust-1.19:
+mingw32-rust-1.20:
     description: "rust repack"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TMW(rust)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux
     worker:
         docker-image: {in-tree: desktop-build}
         max-run-time: 7200
         env:
           UPLOAD_DIR: artifacts
     run:
         using: toolchain-script
         script: repack_rust.py
         arguments: [
-          '--channel', '1.19.0',
+          '--channel', '1.20.0',
           '--host', 'i686-unknown-linux-gnu',
           '--target', 'i686-pc-windows-gnu',
           '--target', 'x86_64-unknown-linux-gnu',
           '--target', 'i686-unknown-linux-gnu',
         ]
         toolchain-alias: mingw32-rust
         toolchain-artifact: public/build/rustc.tar.xz
 
--- a/toolkit/crashreporter/breakpad-client/mac/crash_generation/crash_generation_client.cc
+++ b/toolkit/crashreporter/breakpad-client/mac/crash_generation/crash_generation_client.cc
@@ -41,17 +41,17 @@ bool CrashGenerationClient::RequestDumpF
     mach_port_t crashing_thread) {
   // The server will send a message to this port indicating that it
   // has finished its work.
   ReceivePort acknowledge_port;
 
   MachSendMessage message(kDumpRequestMessage);
   message.AddDescriptor(mach_task_self());            // this task
   message.AddDescriptor(crashing_thread);             // crashing thread
-  message.AddDescriptor(mach_thread_self());          // handler thread
+  message.AddDescriptor(MACH_PORT_NULL);              // handler thread
   message.AddDescriptor(acknowledge_port.GetPort());  // message receive port
 
   ExceptionInfo info;
   info.exception_type = exception_type;
   info.exception_code = exception_code;
   info.exception_subcode = exception_subcode;
   message.SetData(&info, sizeof(info));