From 099ef6f00734cdad8a2525bb9dc368a7213fd258 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 23 Nov 2016 22:57:29 -0500 Subject: [PATCH] Bug 1315135. Remove the RegExp (and some Date) special casing from our dictionary conversions and Web IDL overload resolution. r=peterv --- dom/bindings/BindingUtils.h | 44 +------------ dom/bindings/Codegen.py | 62 ++++++++----------- .../parser/tests/test_distinguishability.py | 3 +- .../test/test_exception_messages.html | 4 +- 4 files changed, 31 insertions(+), 82 deletions(-) diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 3e408d654efb..8b731a7110e1 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -236,50 +236,10 @@ UnwrapObject(JSObject* obj, U& value) PrototypeTraits::Depth); } -inline bool -IsNotDateOrRegExp(JSContext* cx, JS::Handle obj, - bool* notDateOrRegExp) -{ - MOZ_ASSERT(obj); - - js::ESClass cls; - if (!js::GetBuiltinClass(cx, obj, &cls)) { - return false; - } - - *notDateOrRegExp = cls != js::ESClass::Date && cls != js::ESClass::RegExp; - return true; -} - MOZ_ALWAYS_INLINE bool -IsObjectValueConvertibleToDictionary(JSContext* cx, - JS::Handle objVal, - bool* convertible) +IsConvertibleToDictionary(JS::Handle val) { - JS::Rooted obj(cx, &objVal.toObject()); - return IsNotDateOrRegExp(cx, obj, convertible); -} - -MOZ_ALWAYS_INLINE bool -IsConvertibleToDictionary(JSContext* cx, JS::Handle val, - bool* convertible) -{ - if (val.isNullOrUndefined()) { - *convertible = true; - return true; - } - if (!val.isObject()) { - *convertible = false; - return true; - } - return IsObjectValueConvertibleToDictionary(cx, val, convertible); -} - -MOZ_ALWAYS_INLINE bool -IsConvertibleToCallbackInterface(JSContext* cx, JS::Handle obj, - bool* convertible) -{ - return IsNotDateOrRegExp(cx, obj, convertible); + return val.isNullOrUndefined() || val.isObject(); } // The items in the protoAndIfaceCache are indexed by the prototypes::id::ID, diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 886c476517ee..917a504d2e93 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5783,30 +5783,24 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, exceptionCode=exceptionCode) if failureCode is not None: - if isDefinitelyObject: - dictionaryTest = "IsObjectValueConvertibleToDictionary" + # This means we're part of an overload or union conversion, and + # should simply skip stuff if our value is not convertible to + # dictionary, instead of trying and throwing. If we're either + # isDefinitelyObject or isNullOrUndefined then we're convertible to + # dictionary and don't need to check here. + if isDefinitelyObject or isNullOrUndefined: + template = conversionCode else: - dictionaryTest = "IsConvertibleToDictionary" - - template = fill(""" - { // scope for isConvertible - bool isConvertible; - if (!${testConvertible}(cx, ${val}, &isConvertible)) { - $*{exceptionCode} - } - if (!isConvertible) { - $*{failureCode} - } - - $*{conversionCode} - } - - """, - testConvertible=dictionaryTest, - val=val, - exceptionCode=exceptionCode, - failureCode=failureCode, - conversionCode=conversionCode) + template = fill( + """ + if (!IsConvertibleToDictionary(${val})) { + $*{failureCode} + } + $*{conversionCode} + """, + val=val, + failureCode=failureCode, + conversionCode=conversionCode) else: template = conversionCode @@ -8030,12 +8024,12 @@ class CGMethodCall(CGThing): # 1) A platform object that's not a platform array object, being # passed to an interface or "object" arg. # 2) A Date object being passed to a Date or "object" arg. - # 3) A RegExp object being passed to a RegExp or "object" arg. - # 4) A callable object being passed to a callback or "object" arg. - # 5) An iterable object being passed to a sequence arg. - # 6) Any non-Date and non-RegExp object being passed to a - # array or callback interface or dictionary or - # "object" arg. + # XXXbz This is actually gone from the spec now, but we still + # have some APIs using Date. + # 3) A callable object being passed to a callback or "object" arg. + # 4) An iterable object being passed to a sequence arg. + # 5) Any object being passed to a array or callback interface or + # dictionary or "object" arg. # First grab all the overloads that have a non-callback interface # (which includes typed arrays and arraybuffers) at the @@ -12591,14 +12585,8 @@ class CGDictionary(CGThing): else: body += dedent( """ - { // scope for isConvertible - bool isConvertible; - if (!IsConvertibleToDictionary(cx, val, &isConvertible)) { - return false; - } - if (!isConvertible) { - return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription); - } + if (!IsConvertibleToDictionary(val)) { + return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription); } """) diff --git a/dom/bindings/parser/tests/test_distinguishability.py b/dom/bindings/parser/tests/test_distinguishability.py index d7780c1ffa11..9a6cf13c4ebb 100644 --- a/dom/bindings/parser/tests/test_distinguishability.py +++ b/dom/bindings/parser/tests/test_distinguishability.py @@ -163,7 +163,8 @@ def WebIDLTest(parser, harness): "Promise", "Promise?", "USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer", "Uint8Array", "Uint16Array" ] - # When we can parse Date and RegExp, we need to add them here. + # When we can parse Date, we need to add it here. + # XXXbz we can, and should really do that... # Try to categorize things a bit to keep list lengths down def allBut(list1, list2): diff --git a/dom/bindings/test/test_exception_messages.html b/dom/bindings/test/test_exception_messages.html index a0f0cabe63a2..9d5378f23fc0 100644 --- a/dom/bindings/test/test_exception_messages.html +++ b/dom/bindings/test/test_exception_messages.html @@ -44,9 +44,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=882653 [ 'document.createTreeWalker(document, 0xFFFFFFFF, { acceptNode: 5 }).nextNode()', "Property 'acceptNode' is not callable.", "non-callable callback interface operation property" ], - [ '(new TextDecoder).decode(new Uint8Array(), new RegExp())', + [ '(new TextDecoder).decode(new Uint8Array(), 5)', "Argument 2 of TextDecoder.decode can't be converted to a dictionary.", - "regexp passed for a dictionary" ], + "primitive passed for a dictionary" ], [ 'URL.createObjectURL(null, null)', "Argument 1 is not valid for any of the 2-argument overloads of URL.createObjectURL.", "overload resolution failure" ],