Merge latest green fx-team changeset and mozilla-central
authorEd Morley <emorley@mozilla.com>
Mon, 14 Oct 2013 17:35:25 +0100
changeset 164446 8a4374c8fc92f90c39ab7adf004172ab16460a68
parent 164445 b6dfeb4a34c89a3c6409f62d4babd1b515dbce33 (current diff)
parent 164442 fcddc11fb2ef7747a638f7f5efc1fb1c62614996 (diff)
child 164466 871fa1724684722ff7dcbd2a5f6d771f9e6039f3
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge latest green fx-team changeset and mozilla-central
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -277,23 +277,16 @@ public:
 
   // event handler
   IMPL_EVENT_HANDLER(readystatechange)
 
   // states
   uint16_t ReadyState();
 
   // request
-  void Open(const nsACString& aMethod, const nsAString& aUrl, ErrorResult& aRv)
-  {
-    Open(aMethod, aUrl, true,
-         mozilla::dom::Optional<nsAString>(),
-         mozilla::dom::Optional<nsAString>(),
-         aRv);
-  }
   void Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
             const mozilla::dom::Optional<nsAString>& aUser,
             const mozilla::dom::Optional<nsAString>& aPassword,
             ErrorResult& aRv)
   {
     aRv = Open(aMethod, NS_ConvertUTF16toUTF8(aUrl),
                aAsync, aUser, aPassword);
   }
--- a/content/base/test/test_createHTMLDocument.html
+++ b/content/base/test/test_createHTMLDocument.html
@@ -22,33 +22,29 @@ function checkDoc(title, expectedtitle, 
   // Opera doesn't have a doctype: DSK-311092
   ok(doc.doctype, "Need a doctype");
   is(doc.doctype.name, "html");
   is(doc.doctype.publicId, "");
   is(doc.doctype.systemId, "");
   is(doc.doctype.internalSubset, null, "internalSubset should be null!");
   isElement(doc.documentElement, "html");
   isElement(doc.documentElement.firstChild, "head");
-  if (title !== undefined) {
-    is(doc.documentElement.firstChild.childNodes.length, 1);
-    isElement(doc.documentElement.firstChild.firstChild, "title");
-    // Doesn't always work out in WebKit.
-    ok(doc.documentElement.firstChild.firstChild.firstChild, "Need a text node.");
-    is(doc.documentElement.firstChild.firstChild.firstChild.data, expectedtitle);
-  } else {
-    is(doc.documentElement.firstChild.childNodes.length, 0);
-  }
+  is(doc.documentElement.firstChild.childNodes.length, 1);
+  isElement(doc.documentElement.firstChild.firstChild, "title");
+  // Doesn't always work out in WebKit.
+  ok(doc.documentElement.firstChild.firstChild.firstChild, "Need a text node.");
+  is(doc.documentElement.firstChild.firstChild.firstChild.data, expectedtitle);
   isElement(doc.documentElement.lastChild, "body");
   is(doc.documentElement.lastChild.childNodes.length, 0);
   ((!title || title.indexOf("\f") === -1) ? is : todo_is)
     (doc.title, normalizedtitle);
   doc.body.innerHTML = "foo";
   is(doc.body.innerHTML, "foo", "innerHTML should work in HTML data documents!");
 }
 checkDoc("", "", "");
 checkDoc(null, "null", "null");
-checkDoc(undefined, "", "");
+checkDoc(undefined, "undefined", "undefined");
 checkDoc("foo  bar baz", "foo  bar baz", "foo bar baz");
 checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz");
 checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz");
 checkDoc("foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz");
 checkDoc("foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz");
 </script>
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -993,61 +993,35 @@ nsXBLPrototypeBinding::Read(nsIObjectInp
       previousHandler->SetNextHandler(handler);
     }
     else {
       SetPrototypeHandlers(handler);
     }
     previousHandler = handler;
   } while (1);
 
-  if (mBinding) {
-    while (true) {
-      XBLBindingSerializeDetails type;
-      rv = aStream->Read8(&type);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      if (type != XBLBinding_Serialize_Attribute) {
-        break;
-      }
-
-      int32_t attrNamespace;
-      rv = ReadNamespace(aStream, attrNamespace);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      nsAutoString attrName, attrValue;
-      rv = aStream->ReadString(attrName);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      rv = aStream->ReadString(attrValue);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      nsCOMPtr<nsIAtom> atomName = do_GetAtom(attrName);
-      mBinding->SetAttr(attrNamespace, atomName, attrValue, false);
-    }
-  }
-
   // Finally, read in the resources.
-  while (true) {
+  do {
     XBLBindingSerializeDetails type;
     rv = aStream->Read8(&type);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (type == XBLBinding_Serialize_NoMoreItems)
       break;
 
     NS_ASSERTION((type & XBLBinding_Serialize_Mask) == XBLBinding_Serialize_Stylesheet ||
                  (type & XBLBinding_Serialize_Mask) == XBLBinding_Serialize_Image, "invalid resource type");
 
     nsAutoString src;
     rv = aStream->ReadString(src);
     NS_ENSURE_SUCCESS(rv, rv);
 
     AddResource(type == XBLBinding_Serialize_Stylesheet ? nsGkAtoms::stylesheet :
                                                           nsGkAtoms::image, src);
-  }
+  } while (1);
 
   if (isFirstBinding) {
     aDocInfo->SetFirstPrototypeBinding(this);
   }
 
   cleanup.Disconnect();
   return NS_OK;
 }
@@ -1147,40 +1121,16 @@ nsXBLPrototypeBinding::Write(nsIObjectOu
     NS_ENSURE_SUCCESS(rv, rv);
 
     handler = handler->GetNextHandler();
   }
 
   aStream->Write8(XBLBinding_Serialize_NoMoreItems);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (mBinding) {
-    uint32_t attributes = mBinding->GetAttrCount();
-    nsAutoString attrValue;
-    for (uint32_t i = 0; i < attributes; ++i) {
-      const nsAttrName* attr = mBinding->GetAttrNameAt(i);
-      nsDependentAtomString attrName = attr->Atom();
-      mBinding->GetAttr(attr->NamespaceID(), attr->Atom(), attrValue);
-      rv = aStream->Write8(XBLBinding_Serialize_Attribute);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      rv = WriteNamespace(aStream, attr->NamespaceID());
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      rv = aStream->WriteWStringZ(attrName.get());
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      rv = aStream->WriteWStringZ(attrValue.get());
-      NS_ENSURE_SUCCESS(rv, rv);
-    }
-  }
-
-  aStream->Write8(XBLBinding_Serialize_NoMoreItems);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   // Write out the resources
   if (mResources) {
     rv = mResources->Write(aStream);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Write out an end mark at the end.
   return aStream->Write8(XBLBinding_Serialize_NoMoreItems);
--- a/content/xbl/src/nsXBLSerialize.h
+++ b/content/xbl/src/nsXBLSerialize.h
@@ -10,17 +10,17 @@
 #include "nsIObjectOutputStream.h"
 #include "nsINameSpaceManager.h"
 #include "js/TypeDecls.h"
 
 typedef uint8_t XBLBindingSerializeDetails;
 
 // A version number to ensure we don't load cached data in a different
 // file format.
-#define XBLBinding_Serialize_Version 0x00000003
+#define XBLBinding_Serialize_Version 0x00000002
 
 // Set for the first binding in a document
 #define XBLBinding_Serialize_IsFirstBinding 1
 
 // Set to indicate that nsXBLPrototypeBinding::mInheritStyle should be true
 #define XBLBinding_Serialize_InheritStyle 2
 
 // Set to indicate that nsXBLPrototypeBinding::mChromeOnlyContent should be true
@@ -40,17 +40,16 @@ typedef uint8_t XBLBindingSerializeDetai
 #define XBLBinding_Serialize_SetterProperty 3
 #define XBLBinding_Serialize_GetterSetterProperty 4
 #define XBLBinding_Serialize_Method 5
 #define XBLBinding_Serialize_Constructor 6
 #define XBLBinding_Serialize_Destructor 7
 #define XBLBinding_Serialize_Handler 8
 #define XBLBinding_Serialize_Image 9
 #define XBLBinding_Serialize_Stylesheet 10
-#define XBLBinding_Serialize_Attribute 0xA
 #define XBLBinding_Serialize_Mask 0x0F
 #define XBLBinding_Serialize_ReadOnly 0x80
 
 // Appears at the end of the list of insertion points to indicate that there
 // are no more. 
 #define XBLBinding_Serialize_NoMoreInsertionPoints 0xFFFFFFFF
 
 // When serializing content nodes, a single-byte namespace id is written out
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2698,17 +2698,18 @@ def getJSToNativeConversionInfo(type, de
         if (defaultValue is not None and
             not isinstance(defaultValue, IDLNullValue)):
             raise TypeError("Can't handle non-null default value here")
         return handleDefault(template, codeToSetNull)
 
     # A helper function for wrapping up the template body for
     # possibly-nullable objecty stuff
     def wrapObjectTemplate(templateBody, type, codeToSetNull, failureCode=None):
-        if isNullOrUndefined and type.nullable():
+        if isNullOrUndefined:
+            assert type.nullable()
             # Just ignore templateBody and set ourselves to null.
             # Note that we don't have to worry about default values
             # here either, since we already examined this value.
             return "%s;" % codeToSetNull
 
         if not isDefinitelyObject:
             # Handle the non-object cases by wrapping up the whole
             # thing in an if cascade.
@@ -3315,16 +3316,19 @@ for (uint32_t i = 0; i < length; ++i) {
 
     if type.isDOMString():
         assert not isEnforceRange and not isClamp
 
         treatAs = {
             "Default": "eStringify",
             "EmptyString": "eEmpty",
             "Null": "eNull",
+            # For Missing it doesn't matter what we use here, since we'll never
+            # call ConvertJSValueToString on undefined in that case.
+            "Missing": "eStringify"
         }
         if type.nullable():
             # For nullable strings null becomes a null string.
             treatNullAs = "Null"
             # For nullable strings undefined becomes a null string unless
             # specified otherwise.
             if treatUndefinedAs == "Default":
                 treatUndefinedAs = "Null"
@@ -3834,18 +3838,21 @@ class CGArgumentConverter(CGThing):
             "declName" : "arg%d" % index,
             "holderName" : ("arg%d" % index) + "_holder",
             "obj" : "obj"
             }
         self.replacementVariables["val"] = string.Template(
             "args[${index}]"
             ).substitute(replacer)
         self.replacementVariables["mutableVal"] = self.replacementVariables["val"]
-        haveValueCheck = string.Template(
-            "args.hasDefined(${index})").substitute(replacer)
+        if argument.treatUndefinedAs == "Missing":
+            haveValueCheck = "args.hasDefined(${index})"
+        else:
+            haveValueCheck = "${index} < args.length()"
+        haveValueCheck = string.Template(haveValueCheck).substitute(replacer)
         self.replacementVariables["haveValue"] = haveValueCheck
         self.descriptorProvider = descriptorProvider
         if self.argument.optional and not self.argument.defaultValue:
             self.argcAndIndex = replacer
         else:
             self.argcAndIndex = None
         self.invalidEnumValueFatal = invalidEnumValueFatal
         self.lenientFloatCode = lenientFloatCode
@@ -4976,16 +4983,25 @@ class CGMethodCall(CGThing):
                 code = (
                     "if (args.length() < %d) {\n"
                     '  return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "%s");\n'
                     "}" % (requiredArgs, methodName))
                 self.cgRoot.prepend(
                     CGWrapper(CGIndenter(CGGeneric(code)), pre="\n", post="\n"))
             return
 
+        # We don't handle [TreatUndefinedAs=Missing] arguments in overload
+        # resolution yet.
+        for (_, sigArgs) in signatures:
+            for arg in sigArgs:
+                if arg.treatUndefinedAs == "Missing":
+                    raise TypeError("No support for [TreatUndefinedAs=Missing] "
+                                    "handling in overload resolution yet: %s" %
+                                    arg.location)
+
         # Need to find the right overload
         maxArgCount = method.maxArgCount
         allowedArgCounts = method.allowedArgCounts
 
         argCountCases = []
         for argCount in allowedArgCounts:
             possibleSignatures = method.signaturesForArgCount(argCount)
             if len(possibleSignatures) == 1:
@@ -5065,119 +5081,59 @@ class CGMethodCall(CGThing):
                         isNullOrUndefined=False):
                 assert not isDefinitelyObject or not isNullOrUndefined
                 assert isDefinitelyObject or isNullOrUndefined
                 if isDefinitelyObject:
                     failureCode = "break;"
                 else:
                     failureCode = None
                 type = distinguishingType(signature)
-                # The argument at index distinguishingIndex can't possibly be
-                # unset here, because we've already checked that argc is large
-                # enough that we can examine this argument.  But note that we
-                # still want to claim that optional arguments are optional, in
-                # case undefined was passed in.
-                argIsOptional = (distinguishingArgument(signature).optional and
-                                 not distinguishingArgument(signature).defaultValue)
+                # The argument at index distinguishingIndex can't possibly
+                # be unset here, because we've already checked that argc is
+                # large enough that we can examine this argument.
                 testCode = instantiateJSToNativeConversion(
                     getJSToNativeConversionInfo(type, descriptor,
                                                 failureCode=failureCode,
                                                 isDefinitelyObject=isDefinitelyObject,
                                                 isNullOrUndefined=isNullOrUndefined,
-                                                isOptional=argIsOptional,
                                                 sourceDescription=(argDesc % (distinguishingIndex + 1))),
                     {
                         "declName" : "arg%d" % distinguishingIndex,
                         "holderName" : ("arg%d" % distinguishingIndex) + "_holder",
                         "val" : distinguishingArg,
                         "mutableVal" : distinguishingArg,
-                        "obj" : "obj",
-                        "haveValue": "args.hasDefined(%d)" % distinguishingIndex
-                        },
-                    checkForValue=argIsOptional
-                    )
+                        "obj" : "obj"
+                        })
                 caseBody.append(CGIndenter(testCode, indent));
                 # If we got this far, we know we unwrapped to the right
                 # C++ type, so just do the call.  Start conversion with
                 # distinguishingIndex + 1, since we already converted
                 # distinguishingIndex.
                 caseBody.append(CGIndenter(
                         getPerSignatureCall(signature, distinguishingIndex + 1),
                         indent))
 
-            def hasConditionalConversion(type):
-                """
-                Return whether the argument conversion for this type will be
-                conditional on the type of incoming JS value.  For example, for
-                interface types the conversion is conditional on the incoming
-                value being isObject().
-
-                For the types for which this returns false, we do not have to
-                output extra isUndefined() or isNullOrUndefined() cases, because
-                null/undefined values will just fall through into our
-                unconditional conversion.
-                """
-                if type.isString() or type.isEnum():
-                    return False
-                if type.isBoolean():
-                    distinguishingTypes = (distinguishingType(s) for s in
-                                           possibleSignatures)
-                    return any(t.isString() or t.isEnum() or t.isNumeric()
-                               for t in distinguishingTypes)
-                if type.isNumeric():
-                    distinguishingTypes = (distinguishingType(s) for s in
-                                           possibleSignatures)
-                    return any(t.isString() or t.isEnum()
-                               for t in distinguishingTypes)
-                return True
-
-            def needsNullOrUndefinedCase(type):
-                """
-                Return true if the type needs a special isNullOrUndefined() case
-                """
-                return ((type.nullable() and
-                        hasConditionalConversion(type)) or
-                        type.isDictionary())
-
-            # First check for undefined and optional distinguishing arguments
-            # and output a special branch for that case.  Note that we don't
-            # use distinguishingArgument here because we actualy want to
-            # exclude variadic arguments.  Also note that we skip this check if
-            # we plan to output a isNullOrUndefined() special case for this
-            # argument anyway, since that will subsume our isUndefined() check.
-            # This is safe, because there can be at most one nullable
-            # distinguishing argument, so if we're it we'll definitely get
-            # picked up by the nullable handling.  Also, we can skip this check
-            # if the argument has an unconditional conversion later on.
-            undefSigs = [s for s in possibleSignatures if
-                         distinguishingIndex < len(s[1]) and
-                         s[1][distinguishingIndex].optional and
-                         hasConditionalConversion(s[1][distinguishingIndex].type) and
-                         not needsNullOrUndefinedCase(s[1][distinguishingIndex].type)]
-            # Can't have multiple signatures with an optional argument at the
-            # same index.
-            assert len(undefSigs) < 2
-            if len(undefSigs) > 0:
-                caseBody.append(CGGeneric("if (%s.isUndefined()) {" %
-                                          distinguishingArg))
-                tryCall(undefSigs[0], 2, isNullOrUndefined=True)
-                caseBody.append(CGGeneric("}"))
-
-            # Next, check for null or undefined.  That means looking for
+            # First check for null or undefined.  That means looking for
             # nullable arguments at the distinguishing index and outputting a
-            # separate branch for them.  But if the nullable argument has an
-            # unconditional conversion, we don't need to do that.  The reason
+            # separate branch for them.  But if the nullable argument is a
+            # primitive, string, or enum, we don't need to do that.  The reason
             # for that is that at most one argument at the distinguishing index
             # is nullable (since two nullable arguments are not
-            # distinguishable), and null/undefined values will always fall
-            # through to the unconditional conversion we have, if any, since
-            # they will fail whatever the conditions on the input value are for
-            # our other conversions.
+            # distinguishable), and all the argument types other than
+            # primitive/string/enum end up inside isObject() checks.  So if our
+            # nullable is a primitive/string/enum it's safe to not output the
+            # extra branch: we'll fall through to conversion for those types,
+            # which correctly handles null as needed, because isObject() will be
+            # false for null and undefined.
             nullOrUndefSigs = [s for s in possibleSignatures
-                               if needsNullOrUndefinedCase(distinguishingType(s))]
+                               if ((distinguishingType(s).nullable() and not
+                                    distinguishingType(s).isString() and not
+                                    distinguishingType(s).isEnum() and not
+                                   distinguishingType(s).isPrimitive()) or
+                                   distinguishingType(s).isDictionary())]
             # Can't have multiple nullable types here
             assert len(nullOrUndefSigs) < 2
             if len(nullOrUndefSigs) > 0:
                 caseBody.append(CGGeneric("if (%s.isNullOrUndefined()) {" %
                                           distinguishingArg))
                 tryCall(nullOrUndefSigs[0], 2, isNullOrUndefined=True)
                 caseBody.append(CGGeneric("}"))
 
--- a/dom/bindings/Nullable.h
+++ b/dom/bindings/Nullable.h
@@ -76,16 +76,21 @@ public:
     return Equals(aOtherNullable);
   }
 
   bool operator!=(const Nullable<T>& aOtherNullable) const
   {
     return !Equals(aOtherNullable);
   }
 
+  operator bool() const
+  {
+    return !mIsNull;
+  }
+
   // Make it possible to use a const Nullable of an array type with other
   // array types.
   template<typename U>
   operator const Nullable< nsTArray<U> >&() const {
     // Make sure that T is ok to reinterpret to nsTArray<U>
     const nsTArray<U>& arr = mValue;
     (void)arr;
     return *reinterpret_cast<const Nullable< nsTArray<U> >*>(this);
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -396,17 +396,22 @@ class IDLObjectWithIdentifier(IDLObject)
                     raise WebIDLError("[TreatNullAs] must take the identifier "
                                       "'EmptyString', not '%s'" % value,
                                       [self.location])
                 self.treatNullAs = value
             elif identifier == "TreatUndefinedAs":
                 if isDictionaryMember:
                     raise WebIDLError("[TreatUndefinedAs] is not allowed for "
                                       "dictionary members", [self.location])
-                if value == 'Null':
+                if value == 'Missing':
+                    if not isOptional:
+                        raise WebIDLError("[TreatUndefinedAs=Missing] is only "
+                                          "allowed on optional arguments",
+                                          [self.location])
+                elif value == 'Null':
                     if not self.type.isDOMString():
                         raise WebIDLError("[TreatUndefinedAs=Null] is only "
                                           "allowed on arguments or "
                                           "attributes whose type is "
                                           "DOMString or DOMString?",
                                           [self.location])
                     if not self.type.nullable():
                         raise WebIDLError("[TreatUndefinedAs=Null] is only "
@@ -416,18 +421,18 @@ class IDLObjectWithIdentifier(IDLObject)
                     if not self.type.isDOMString():
                         raise WebIDLError("[TreatUndefinedAs=EmptyString] "
                                           "is only allowed on arguments or "
                                           "attributes whose type is "
                                           "DOMString or DOMString?",
                                           [self.location])
                 else:
                     raise WebIDLError("[TreatUndefinedAs] must take the "
-                                      "identifiers EmptyString or Null",
-                                      [self.location])
+                                      "identifiers EmptyString or Null or "
+                                      "Missing", [self.location])
                 self.treatUndefinedAs = value
             else:
                 unhandledAttrs.append(attr)
 
         return unhandledAttrs
 
 class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
     def __init__(self, location, parentScope, identifier):
@@ -3133,32 +3138,35 @@ class IDLMethod(IDLInterfaceMember, IDLS
         return self
 
     def signatures(self):
         return [(overload.returnType, overload.arguments) for overload in
                 self._overloads]
 
     def finish(self, scope):
         for overload in self._overloads:
+            inOptionalArguments = False
             variadicArgument = None
 
             arguments = overload.arguments
             for (idx, argument) in enumerate(arguments):
-                if not argument.isComplete():
-                    argument.complete(scope)
+                if argument.isComplete():
+                    continue
+
+                argument.complete(scope)
                 assert argument.type.isComplete()
 
                 if (argument.type.isDictionary() or
                     (argument.type.isUnion() and
                      argument.type.unroll().hasDictionaryType)):
                     # Dictionaries and unions containing dictionaries at the
                     # end of the list or followed by optional arguments must be
                     # optional.
                     if (not argument.optional and
-                        all(arg.optional for arg in arguments[idx+1:])):
+                        (idx == len(arguments) - 1 or arguments[idx+1].optional)):
                         raise WebIDLError("Dictionary argument or union "
                                           "argument containing a dictionary "
                                           "not followed by a required argument "
                                           "must be optional",
                                           [argument.location])
 
                     # An argument cannot be a Nullable Dictionary
                     if argument.type.nullable():
@@ -3166,16 +3174,23 @@ class IDLMethod(IDLInterfaceMember, IDLS
                                           "dictionary or nullable union "
                                           "containing a dictionary",
                                           [argument.location])
 
                 # Only the last argument can be variadic
                 if variadicArgument:
                     raise WebIDLError("Variadic argument is not last argument",
                                       [variadicArgument.location])
+                # Once we see an optional argument, there can't be any non-optional
+                # arguments.
+                if inOptionalArguments and not argument.optional:
+                    raise WebIDLError("Non-optional argument after optional "
+                                      "arguments",
+                                      [argument.location])
+                inOptionalArguments = argument.optional
                 if argument.variadic:
                     variadicArgument = argument
 
             returnType = overload.returnType
             if returnType.isComplete():
                 continue
 
             type = returnType.complete(scope)
@@ -3210,17 +3225,17 @@ class IDLMethod(IDLInterfaceMember, IDLS
                             (self.identifier.name, argCount, idx,
                              distinguishingIndex),
                             [self.location, overload.location])
 
     def overloadsForArgCount(self, argc):
         return [overload for overload in self._overloads if
                 len(overload.arguments) == argc or
                 (len(overload.arguments) > argc and
-                 all(arg.optional for arg in overload.arguments[argc:])) or
+                 overload.arguments[argc].optional) or
                 (len(overload.arguments) < argc and
                  len(overload.arguments) > 0 and
                  overload.arguments[-1].variadic)]
 
     def signaturesForArgCount(self, argc):
         return [(overload.returnType, overload.arguments) for overload
                 in self.overloadsForArgCount(argc)]
 
@@ -4040,16 +4055,31 @@ class Parser(Tokenizer):
         if stringifier:
             if len(arguments) != 0:
                 raise WebIDLError("stringifier has wrong number of arguments",
                                   [self.getLocation(p, 2)])
             if not returnType.isDOMString():
                 raise WebIDLError("stringifier must have DOMString return type",
                                   [self.getLocation(p, 2)])
 
+        inOptionalArguments = False
+        variadicArgument = False
+        for argument in arguments:
+            # Only the last argument can be variadic
+            if variadicArgument:
+                raise WebIDLError("Only the last argument can be variadic",
+                                  [variadicArgument.location])
+            # Once we see an optional argument, there can't be any non-optional
+            # arguments.
+            if inOptionalArguments and not argument.optional:
+                raise WebIDLError("Cannot have a non-optional argument following an optional argument",
+                                  [argument.location])
+            inOptionalArguments = argument.optional
+            variadicArgument = argument if argument.variadic else None
+
         # identifier might be None.  This is only permitted for special methods.
         if not identifier:
             if not getter and not setter and not creator and \
                not deleter and not legacycaller and not stringifier:
                 raise WebIDLError("Identifier required for non-special methods",
                                   [self.getLocation(p, 2)])
 
             location = BuiltinLocation("<auto-generated-identifier>")
--- a/dom/bindings/parser/tests/test_dictionary.py
+++ b/dom/bindings/parser/tests/test_dictionary.py
@@ -173,33 +173,16 @@ def WebIDLTest(parser, harness):
 
     parser = parser.reset()
     threw = False
     try:
         parser.parse("""
             dictionary A {
             };
             interface X {
-              void doFoo(A arg1, optional long arg2, long arg3);
-            };
-        """)
-        results = parser.finish()
-    except:
-        threw = True
-
-    harness.ok(not threw,
-               "Dictionary arg followed by non-optional arg doesn't have to be optional")
-
-    parser = parser.reset()
-    threw = False
-    try:
-        parser.parse("""
-            dictionary A {
-            };
-            interface X {
               void doFoo((A or DOMString) arg1, optional long arg2);
             };
         """)
         results = parser.finish()
     except:
         threw = True
 
     harness.ok(threw,
--- a/dom/bindings/parser/tests/test_optional_constraints.py
+++ b/dom/bindings/parser/tests/test_optional_constraints.py
@@ -6,19 +6,19 @@ def WebIDLTest(parser, harness):
               void foo(optional byte arg1, byte arg2);
             };
         """)
 
         results = parser.finish()
     except:
         threw = True
 
-    harness.ok(not threw,
-               "Should not have thrown on non-optional argument following "
-               "optional argument.")
+    harness.ok(threw,
+               "Should have thrown on non-optional argument following optional "
+               "argument.")
 
     parser = parser.reset()
     parser.parse("""
         interface OptionalConstraints2 {
           void foo(optional byte arg1 = 1, optional byte arg2 = 2,
                    optional byte arg3, optional byte arg4 = 4,
                    optional byte arg5, optional byte arg6 = 9);
         };
--- a/dom/bindings/parser/tests/test_overload.py
+++ b/dom/bindings/parser/tests/test_overload.py
@@ -6,31 +6,29 @@ def WebIDLTest(parser, harness):
           void basic();
           void basic(long arg1);
           boolean abitharder(TestOverloads foo);
           boolean abitharder(boolean foo);
           void abitharder(ArrayBuffer? foo);
           void withVariadics(long... numbers);
           void withVariadics(TestOverloads iface);
           void withVariadics(long num, TestOverloads iface);
-          void optionalTest();
-          void optionalTest(optional long num1, long num2);
         };
     """)
 
     results = parser.finish()
 
     harness.ok(True, "TestOverloads interface parsed without error.")
     harness.check(len(results), 1, "Should be one production.")
     iface = results[0]
     harness.ok(isinstance(iface, WebIDL.IDLInterface),
                "Should be an IDLInterface")
     harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
     harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
-    harness.check(len(iface.members), 4, "Expect %s members" % 4)
+    harness.check(len(iface.members), 3, "Expect %s members" % 3)
 
     member = iface.members[0]
     harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
     harness.check(member.identifier.name, "basic", "Method has the right name")
     harness.check(member.hasOverloads(), True, "Method has overloads")
 
     signatures = member.signatures()
     harness.check(len(signatures), 2, "Method should have 2 signatures")
@@ -45,16 +43,8 @@ def WebIDLTest(parser, harness):
     harness.check(len(argumentSet), 1, "Expect an argument set with one argument")
 
     argument = argumentSet[0]
     harness.ok(isinstance(argument, WebIDL.IDLArgument),
                "Should be an IDLArgument")
     harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName")
     harness.check(argument.identifier.name, "arg1", "Argument has the right name")
     harness.check(str(argument.type), "Long", "Argument has the right type")
-
-    member = iface.members[3]
-    harness.check(len(member.overloadsForArgCount(0)), 1,
-                  "Only one overload for no args")
-    harness.check(len(member.overloadsForArgCount(1)), 0,
-                  "No overloads for one arg")
-    harness.check(len(member.overloadsForArgCount(2)), 1,
-                  "Only one overload for two args")
--- a/dom/bindings/parser/tests/test_variadic_constraints.py
+++ b/dom/bindings/parser/tests/test_variadic_constraints.py
@@ -1,63 +1,52 @@
 def WebIDLTest(parser, harness):
     threw = False
     try:
-        parser.parse("""
+        results = parser.parse("""
             interface VariadicConstraints1 {
               void foo(byte... arg1, byte arg2);
             };
         """)
-        results = parser.finish()
 
     except:
         threw = True
 
-    harness.ok(threw,
-               "Should have thrown on variadic argument followed by required "
-               "argument.")
+    harness.ok(threw, "Should have thrown.")
 
-    parser = parser.reset()
     threw = False
     try:
-        parser.parse("""
+        results = parser.parse("""
             interface VariadicConstraints2 {
               void foo(byte... arg1, optional byte arg2);
             };
         """)
-        results = parser.finish();
+
     except:
         threw = True
 
-    harness.ok(threw,
-               "Should have thrown on variadic argument followed by optional "
-               "argument.")
+    harness.ok(threw, "Should have thrown.")
 
-    parser = parser.reset()
     threw = False
     try:
-        parser.parse("""
+        results = parser.parse("""
             interface VariadicConstraints3 {
               void foo(optional byte... arg1);
             };
         """)
-        results = parser.finish()
 
     except:
         threw = True
 
-    harness.ok(threw,
-               "Should have thrown on variadic argument explicitly flagged as "
-               "optional.")
+    harness.ok(threw, "Should have thrown.")
 
-    parser = parser.reset()
     threw = False
     try:
-        parser.parse("""
+        results = parser.parse("""
             interface VariadicConstraints4 {
               void foo(byte... arg1 = 0);
             };
         """)
-        results = parser.finish()
+
     except:
         threw = True
 
     harness.ok(threw, "Should have thrown on variadic argument with default value.")
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -156,19 +156,19 @@ public:
 
   // Integer types
   int8_t ReadonlyByte();
   int8_t WritableByte();
   void SetWritableByte(int8_t);
   void PassByte(int8_t);
   int8_t ReceiveByte();
   void PassOptionalByte(const Optional<int8_t>&);
-  void PassOptionalByteBeforeRequired(const Optional<int8_t>&, int8_t);
+  void PassOptionalUndefinedMissingByte(const Optional<int8_t>&);
   void PassOptionalByteWithDefault(int8_t);
-  void PassOptionalByteWithDefaultBeforeRequired(int8_t, int8_t);
+  void PassOptionalUndefinedMissingByteWithDefault(int8_t);
   void PassNullableByte(const Nullable<int8_t>&);
   void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
   void PassVariadicByte(const Sequence<int8_t>&);
 
   int16_t ReadonlyShort();
   int16_t WritableShort();
   void SetWritableShort(int16_t);
   void PassShort(int16_t);
@@ -405,17 +405,19 @@ public:
   void PassVariadicTypedArray(const Sequence<Float32Array>&);
   void PassVariadicNullableTypedArray(const Sequence<Nullable<Float32Array> >&);
   JSObject* ReceiveUint8Array(JSContext*);
 
   // DOMString types
   void PassString(const nsAString&);
   void PassNullableString(const nsAString&);
   void PassOptionalString(const Optional<nsAString>&);
+  void PassOptionalUndefinedMissingString(const Optional<nsAString>&);
   void PassOptionalStringWithDefaultValue(const nsAString&);
+  void PassOptionalUndefinedMissingStringWithDefaultValue(const nsAString&);
   void PassOptionalNullableString(const Optional<nsAString>&);
   void PassOptionalNullableStringWithDefaultValue(const nsAString&);
   void PassVariadicString(const Sequence<nsString>&);
 
   // ByteString types
   void PassByteString(const nsCString&);
   void PassNullableByteString(const nsCString&);
   void PassOptionalByteString(const Optional<nsCString>&);
@@ -624,32 +626,16 @@ public:
   void Overload5(TestEnum);
   void Overload6(int32_t);
   void Overload6(bool);
   void Overload7(int32_t);
   void Overload7(bool);
   void Overload7(const nsCString&);
   void Overload8(int32_t);
   void Overload8(TestInterface&);
-  void Overload9(const Nullable<int32_t>&);
-  void Overload9(const nsAString&);
-  void Overload10(const Nullable<int32_t>&);
-  void Overload10(JSContext*, JS::Handle<JSObject*>);
-  void Overload11(int32_t);
-  void Overload11(const nsAString&);
-  void Overload12(int32_t);
-  void Overload12(const Nullable<bool>&);
-  void Overload13(const Nullable<int32_t>&);
-  void Overload13(bool);
-  void Overload14(const Optional<int32_t>&);
-  void Overload14(TestInterface&);
-  void Overload15(int32_t);
-  void Overload15(const Optional<NonNull<TestInterface> >&);
-  void Overload16(int32_t);
-  void Overload16(const Optional<TestInterface*>&);
 
   // Variadic handling
   void PassVariadicThirdArg(const nsAString&, int32_t,
                             const Sequence<OwningNonNull<TestInterface> >&);
 
   // Conditionally exposed methods/attributes
   bool Prefable1();
   bool Prefable2();
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -113,19 +113,19 @@ interface OnlyForUseInConstructor {
 interface TestInterface {
   // Integer types
   // XXXbz add tests for throwing versions of all the integer stuff
   readonly attribute byte readonlyByte;
   attribute byte writableByte;
   void passByte(byte arg);
   byte receiveByte();
   void passOptionalByte(optional byte arg);
-  void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
+  void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
   void passOptionalByteWithDefault(optional byte arg = 0);
-  void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
+  void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
   void passNullableByte(byte? arg);
   void passOptionalNullableByte(optional byte? arg);
   void passVariadicByte(byte... arg);
 
   readonly attribute short readonlyShort;
   attribute short writableShort;
   void passShort(short arg);
   short receiveShort();
@@ -360,17 +360,19 @@ interface TestInterface {
   void passVariadicTypedArray(Float32Array... arg);
   void passVariadicNullableTypedArray(Float32Array?... arg);
   Uint8Array receiveUint8Array();
 
   // DOMString types
   void passString(DOMString arg);
   void passNullableString(DOMString? arg);
   void passOptionalString(optional DOMString arg);
+  void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
   void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
+  void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
   void passOptionalNullableString(optional DOMString? arg);
   void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
   void passVariadicString(DOMString... arg);
 
   // ByteString types
   void passByteString(ByteString arg);
   void passNullableByteString(ByteString? arg);
   void passOptionalByteString(optional ByteString arg);
@@ -574,32 +576,16 @@ interface TestInterface {
   void overload5(TestEnum arg);
   void overload6(long arg);
   void overload6(boolean arg);
   void overload7(long arg);
   void overload7(boolean arg);
   void overload7(ByteString arg);
   void overload8(long arg);
   void overload8(TestInterface arg);
-  void overload9(long? arg);
-  void overload9(DOMString arg);
-  void overload10(long? arg);
-  void overload10(object arg);
-  void overload11(long arg);
-  void overload11(DOMString? arg);
-  void overload12(long arg);
-  void overload12(boolean? arg);
-  void overload13(long? arg);
-  void overload13(boolean arg);
-  void overload14(optional long arg);
-  void overload14(TestInterface arg);
-  void overload15(long arg);
-  void overload15(optional TestInterface arg);
-  void overload16(long arg);
-  void overload16(optional TestInterface? arg);
 
   // Variadic handling
   void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
 
   // Conditionally exposed methods/attributes
   [Pref="abc.def"]
   readonly attribute boolean prefable1;
   [Pref="abc.def"]
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -18,19 +18,19 @@
 interface TestExampleInterface {
   // Integer types
   // XXXbz add tests for throwing versions of all the integer stuff
   readonly attribute byte readonlyByte;
   attribute byte writableByte;
   void passByte(byte arg);
   byte receiveByte();
   void passOptionalByte(optional byte arg);
-  void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
+  void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
   void passOptionalByteWithDefault(optional byte arg = 0);
-  void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
+  void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
   void passNullableByte(byte? arg);
   void passOptionalNullableByte(optional byte? arg);
   void passVariadicByte(byte... arg);
 
   readonly attribute short readonlyShort;
   attribute short writableShort;
   void passShort(short arg);
   short receiveShort();
@@ -258,17 +258,19 @@ interface TestExampleInterface {
   void passVariadicTypedArray(Float32Array... arg);
   void passVariadicNullableTypedArray(Float32Array?... arg);
   Uint8Array receiveUint8Array();
 
   // DOMString types
   void passString(DOMString arg);
   void passNullableString(DOMString? arg);
   void passOptionalString(optional DOMString arg);
+  void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
   void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
+  void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
   void passOptionalNullableString(optional DOMString? arg);
   void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
   void passVariadicString(DOMString... arg);
 
   // ByteString types
   void passByteString(ByteString arg);
   void passNullableByteString(ByteString? arg);
   void passOptionalByteString(optional ByteString arg);
@@ -471,32 +473,16 @@ interface TestExampleInterface {
   void overload5(TestEnum arg);
   void overload6(long arg);
   void overload6(boolean arg);
   void overload7(long arg);
   void overload7(boolean arg);
   void overload7(ByteString arg);
   void overload8(long arg);
   void overload8(TestInterface arg);
-  void overload9(long? arg);
-  void overload9(DOMString arg);
-  void overload10(long? arg);
-  void overload10(object arg);
-  void overload11(long arg);
-  void overload11(DOMString? arg);
-  void overload12(long arg);
-  void overload12(boolean? arg);
-  void overload13(long? arg);
-  void overload13(boolean arg);
-  void overload14(optional long arg);
-  void overload14(TestInterface arg);
-  void overload15(long arg);
-  void overload15(optional TestInterface arg);
-  void overload16(long arg);
-  void overload16(optional TestInterface? arg);
 
   // Variadic handling
   void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
 
   // Conditionally exposed methods/attributes
   [Pref="abc.def"]
   readonly attribute boolean prefable1;
   [Pref="abc.def"]
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -30,19 +30,19 @@ enum MyTestEnum {
 interface TestJSImplInterface {
   // Integer types
   // XXXbz add tests for throwing versions of all the integer stuff
   readonly attribute byte readonlyByte;
   attribute byte writableByte;
   void passByte(byte arg);
   byte receiveByte();
   void passOptionalByte(optional byte arg);
-  void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
+  void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
   void passOptionalByteWithDefault(optional byte arg = 0);
-  void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
+  void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
   void passNullableByte(byte? arg);
   void passOptionalNullableByte(optional byte? arg);
   void passVariadicByte(byte... arg);
 
   readonly attribute short readonlyShort;
   attribute short writableShort;
   void passShort(short arg);
   short receiveShort();
@@ -280,17 +280,19 @@ interface TestJSImplInterface {
   //void passVariadicTypedArray(Float32Array... arg);
   //void passVariadicNullableTypedArray(Float32Array?... arg);
   //Uint8Array receiveUint8Array();
 
   // DOMString types
   void passString(DOMString arg);
   void passNullableString(DOMString? arg);
   void passOptionalString(optional DOMString arg);
+  void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
   void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
+  void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
   void passOptionalNullableString(optional DOMString? arg);
   void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
   void passVariadicString(DOMString... arg);
 
   // ByteString types
   void passByteString(ByteString arg);
   void passNullableByteString(ByteString? arg);
   void passOptionalByteString(optional ByteString arg);
@@ -499,32 +501,16 @@ interface TestJSImplInterface {
   void overload5(MyTestEnum arg);
   void overload6(long arg);
   void overload6(boolean arg);
   void overload7(long arg);
   void overload7(boolean arg);
   void overload7(ByteString arg);
   void overload8(long arg);
   void overload8(TestJSImplInterface arg);
-  void overload9(long? arg);
-  void overload9(DOMString arg);
-  void overload10(long? arg);
-  void overload10(object arg);
-  void overload11(long arg);
-  void overload11(DOMString? arg);
-  void overload12(long arg);
-  void overload12(boolean? arg);
-  void overload13(long? arg);
-  void overload13(boolean arg);
-  void overload14(optional long arg);
-  void overload14(TestInterface arg);
-  void overload15(long arg);
-  void overload15(optional TestInterface arg);
-  void overload16(long arg);
-  void overload16(optional TestInterface? arg);
 
   // Variadic handling
   void passVariadicThirdArg(DOMString arg1, long arg2, TestJSImplInterface... arg3);
 
   // Miscellania
   [LenientThis] attribute long attrWithLenientThis;
   // FIXME: Bug 863954 Unforgeable things get all confused when
   // non-JS-implemented interfaces inherit from JS-implemented ones or vice
--- a/dom/imptests/html/dom/nodes/test_DOMImplementation-createHTMLDocument.html
+++ b/dom/imptests/html/dom/nodes/test_DOMImplementation-createHTMLDocument.html
@@ -13,31 +13,27 @@
 function checkDoc(title, expectedtitle, normalizedtitle) {
   test(function() {
     var doc = document.implementation.createHTMLDocument(title);
     assert_equals(doc.doctype.name, "html")
     assert_equals(doc.doctype.publicId, "")
     assert_equals(doc.doctype.systemId, "")
     assert_equals(doc.documentElement.localName, "html")
     assert_equals(doc.documentElement.firstChild.localName, "head")
-    if (title !== undefined) {
-      assert_equals(doc.documentElement.firstChild.childNodes.length, 1)
-      assert_equals(doc.documentElement.firstChild.firstChild.localName, "title")
-      assert_equals(doc.documentElement.firstChild.firstChild.firstChild.data,
-                    expectedtitle)
-    } else {
-      assert_equals(doc.documentElement.firstChild.childNodes.length, 0)
-    }
+    assert_equals(doc.documentElement.firstChild.childNodes.length, 1)
+    assert_equals(doc.documentElement.firstChild.firstChild.localName, "title")
+    assert_equals(doc.documentElement.firstChild.firstChild.firstChild.data,
+    expectedtitle)
     assert_equals(doc.documentElement.lastChild.localName, "body")
     assert_equals(doc.documentElement.lastChild.childNodes.length, 0)
   })
 }
 checkDoc("", "", "")
 checkDoc(null, "null", "null")
-checkDoc(undefined, "", "")
+checkDoc(undefined, "undefined", "undefined")
 checkDoc("foo  bar baz", "foo  bar baz", "foo bar baz")
 checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
 checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")
 checkDoc("foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz")
 checkDoc("foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz")
 
 test(function() {
   var doc = document.implementation.createHTMLDocument();
--- a/dom/imptests/html/html/dom/documents/dta/test_document.title-07.html
+++ b/dom/imptests/html/html/dom/documents/dta/test_document.title-07.html
@@ -7,15 +7,15 @@
 function checkDoc(title, expectedtitle, normalizedtitle) {
   test(function() {
     var doc = document.implementation.createHTMLDocument(title);
     assert_equals(doc.title, normalizedtitle)
   })
 }
 checkDoc("", "", "")
 checkDoc(null, "null", "null")
-checkDoc(undefined, "", "")
+checkDoc(undefined, "undefined", "undefined")
 checkDoc("foo  bar baz", "foo  bar baz", "foo bar baz")
 checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
 checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")
 checkDoc("foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz")
 checkDoc("foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz")
 </script>
--- a/dom/quota/QuotaManager.cpp
+++ b/dom/quota/QuotaManager.cpp
@@ -2797,17 +2797,17 @@ QuotaManager::RunSynchronizedOp(nsIOffli
 SynchronizedOp*
 QuotaManager::FindSynchronizedOp(const nsACString& aPattern,
                                  Nullable<PersistenceType> aPersistenceType,
                                  nsISupports* aId)
 {
   for (uint32_t index = 0; index < mSynchronizedOps.Length(); index++) {
     const nsAutoPtr<SynchronizedOp>& currentOp = mSynchronizedOps[index];
     if (PatternMatchesOrigin(aPattern, currentOp->mOriginOrPattern) &&
-        (currentOp->mPersistenceType.IsNull() ||
+        (!currentOp->mPersistenceType ||
          currentOp->mPersistenceType == aPersistenceType) &&
         (!currentOp->mId || currentOp->mId == aId)) {
       return currentOp;
     }
   }
 
   return nullptr;
 }
@@ -3062,28 +3062,28 @@ QuotaManager::CollectOriginsForEviction(
   // Collect active origins first.
   OriginCollection originCollection;
 
   // Add patterns and origins that have running or pending synchronized ops.
   // (add patterns first to reduce redundancy in the origin collection).
   uint32_t index;
   for (index = 0; index < mSynchronizedOps.Length(); index++) {
     nsAutoPtr<SynchronizedOp>& op = mSynchronizedOps[index];
-    if (op->mPersistenceType.IsNull() ||
+    if (!op->mPersistenceType ||
         op->mPersistenceType.Value() == PERSISTENCE_TYPE_TEMPORARY) {
       if (op->mOriginOrPattern.IsPattern() &&
           !originCollection.ContainsPattern(op->mOriginOrPattern)) {
         originCollection.AddPattern(op->mOriginOrPattern);
       }
     }
   }
 
   for (index = 0; index < mSynchronizedOps.Length(); index++) {
     nsAutoPtr<SynchronizedOp>& op = mSynchronizedOps[index];
-    if (op->mPersistenceType.IsNull() ||
+    if (!op->mPersistenceType ||
         op->mPersistenceType.Value() == PERSISTENCE_TYPE_TEMPORARY) {
       if (op->mOriginOrPattern.IsOrigin() &&
           !originCollection.ContainsOrigin(op->mOriginOrPattern)) {
         originCollection.AddOrigin(op->mOriginOrPattern);
       }
     }
   }
 
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -69,30 +69,30 @@ interface CanvasRenderingContext2D {
   void clearRect(double x, double y, double w, double h);
   [LenientFloat]
   void fillRect(double x, double y, double w, double h);
   [LenientFloat]
   void strokeRect(double x, double y, double w, double h);
 
   // path API (see also CanvasPathMethods)
   void beginPath();
-  void fill(optional CanvasWindingRule winding = "nonzero");
+  void fill([TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
 // NOT IMPLEMENTED  void fill(Path path);
   void stroke();
 // NOT IMPLEMENTED  void stroke(Path path);
 // NOT IMPLEMENTED  void drawSystemFocusRing(Element element);
 // NOT IMPLEMENTED  void drawSystemFocusRing(Path path, Element element);
 // NOT IMPLEMENTED  boolean drawCustomFocusRing(Element element);
 // NOT IMPLEMENTED  boolean drawCustomFocusRing(Path path, Element element);
 // NOT IMPLEMENTED  void scrollPathIntoView();
 // NOT IMPLEMENTED  void scrollPathIntoView(Path path);
-  void clip(optional CanvasWindingRule winding = "nonzero");
+  void clip([TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
 // NOT IMPLEMENTED  void clip(Path path);
 // NOT IMPLEMENTED  void resetClip();
-  boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
+  boolean isPointInPath(unrestricted double x, unrestricted double y, [TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
 // NOT IMPLEMENTED  boolean isPointInPath(Path path, unrestricted double x, unrestricted double y);
   boolean isPointInStroke(double x, double y);
 
   // text (see also the CanvasDrawingStyles interface)
   [Throws, LenientFloat]
   void fillText(DOMString text, double x, double y, optional double maxWidth);
   [Throws, LenientFloat]
   void strokeText(DOMString text, double x, double y, optional double maxWidth);
--- a/dom/webidl/Promise.webidl
+++ b/dom/webidl/Promise.webidl
@@ -23,14 +23,14 @@ interface Promise {
   // Promise object in this scope without having resolved the interface object
   // first.
   [Creator, Throws, Func="mozilla::dom::Promise::EnabledForScope"]
   static Promise resolve(any value); // same as any(value)
   [Creator, Throws, Func="mozilla::dom::Promise::EnabledForScope"]
   static Promise reject(any value);
 
   [Creator]
-  Promise then(optional AnyCallback fulfillCallback,
-               optional AnyCallback rejectCallback);
+  Promise then([TreatUndefinedAs=Missing] optional AnyCallback fulfillCallback,
+               [TreatUndefinedAs=Missing] optional AnyCallback rejectCallback);
 
   [Creator]
-  Promise catch(optional AnyCallback rejectCallback);
+  Promise catch([TreatUndefinedAs=Missing] optional AnyCallback rejectCallback);
 };
--- a/dom/webidl/XMLHttpRequest.webidl
+++ b/dom/webidl/XMLHttpRequest.webidl
@@ -66,19 +66,17 @@ interface XMLHttpRequest : XMLHttpReques
   const unsigned short HEADERS_RECEIVED = 2;
   const unsigned short LOADING = 3;
   const unsigned short DONE = 4;
 
   readonly attribute unsigned short readyState;
 
   // request
   [Throws]
-  void open(ByteString method, DOMString url);
-  [Throws]
-  void open(ByteString method, DOMString url, boolean async,
+  void open(ByteString method, DOMString url, optional boolean async = true,
             optional DOMString? user, optional DOMString? password);
   [Throws]
   void setRequestHeader(ByteString header, ByteString value);
 
   [SetterThrows]
   attribute unsigned long timeout;
 
   [SetterThrows]
--- a/dom/workers/XMLHttpRequest.h
+++ b/dom/workers/XMLHttpRequest.h
@@ -116,21 +116,16 @@ public:
 #undef IMPL_GETTER_AND_SETTER
 
   uint16_t
   ReadyState() const
   {
     return mStateData.mReadyState;
   }
 
-  void Open(const nsACString& aMethod, const nsAString& aUrl, ErrorResult& aRv)
-  {
-    Open(aMethod, aUrl, true, Optional<nsAString>(),
-         Optional<nsAString>(), aRv);
-  }
   void
   Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
        const Optional<nsAString>& aUser, const Optional<nsAString>& aPassword,
        ErrorResult& aRv);
 
   void
   SetRequestHeader(const nsACString& aHeader, const nsACString& aValue,
                    ErrorResult& aRv);
--- a/js/xpconnect/tests/unit/test_allowedDomainsXHR.js
+++ b/js/xpconnect/tests/unit/test_allowedDomainsXHR.js
@@ -47,17 +47,17 @@ function run_test()
   httpserver.start(4444);
 
   httpserver2.registerPathHandler(negativetestpath, serverHandler);
   httpserver2.start(4445);
 
   // Test sync XHR sending
   cu.evalInSandbox('var createXHR = ' + createXHR.toString(), sb);
   var res = cu.evalInSandbox('var sync = createXHR("4444/simple"); sync.send(null); sync', sb);
-  do_check_true(checkResults(res));
+  checkResults(res);
 
   // negative test sync XHR sending (to ensure that the xhr do not have chrome caps, see bug 779821)
   try {
     cu.evalInSandbox('var createXHR = ' + createXHR.toString(), sb);
     var res = cu.evalInSandbox('var sync = createXHR("4445/negative"); sync.send(null); sync', sb);
     do_check_false(true, "XHR created from sandbox should not have chrome caps");
   } catch (e) {
     do_check_true(true);