Title: [200099] trunk/Source/WebCore
Revision
200099
Author
[email protected]
Date
2016-04-26 11:22:40 -0700 (Tue, 26 Apr 2016)

Log Message

Drop Dictionary from CanUseWTFOptionalForParameter()
https://bugs.webkit.org/show_bug.cgi?id=157023

Reviewed by Darin Adler.

As per Web IDL, optional dictionary parameters are always considered to have
a default value of an empty dictionary, unless otherwise specified. There is
therefore never any need to use Optional<> for it. Just implement this
behavior in the bindings generator and drop blacklisting of Dictionary from
CanUseWTFOptionalForParameter().

* bindings/scripts/CodeGeneratorJS.pm:
(GenerateParametersCheck):
(CanUseWTFOptionalForParameter): Deleted.
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::jsTestObjPrototypeFunctionOptionsObject):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (200098 => 200099)


--- trunk/Source/WebCore/ChangeLog	2016-04-26 18:20:09 UTC (rev 200098)
+++ trunk/Source/WebCore/ChangeLog	2016-04-26 18:22:40 UTC (rev 200099)
@@ -1,3 +1,22 @@
+2016-04-26  Chris Dumez  <[email protected]>
+
+        Drop Dictionary from CanUseWTFOptionalForParameter()
+        https://bugs.webkit.org/show_bug.cgi?id=157023
+
+        Reviewed by Darin Adler.
+
+        As per Web IDL, optional dictionary parameters are always considered to have
+        a default value of an empty dictionary, unless otherwise specified. There is
+        therefore never any need to use Optional<> for it. Just implement this
+        behavior in the bindings generator and drop blacklisting of Dictionary from
+        CanUseWTFOptionalForParameter().
+
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateParametersCheck):
+        (CanUseWTFOptionalForParameter): Deleted.
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        (WebCore::jsTestObjPrototypeFunctionOptionsObject):
+
 2016-04-26  Antti Koivisto  <[email protected]>
 
         RenderElement::style() should return const RenderStyle

Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (200098 => 200099)


--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-04-26 18:20:09 UTC (rev 200098)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2016-04-26 18:22:40 UTC (rev 200099)
@@ -3383,13 +3383,48 @@
     return 0 if $codeGenerator->IsEnumType($type);
     return 0 if $codeGenerator->IsWrapperType($type);
     return 0 if $type eq "DOMString";
-    return 0 if $type eq "Dictionary";
     return 0 if $type eq "any";
     return 0 if $type eq "unsigned long";
 
     return 1;
 }
 
+sub WillConvertUndefinedToDefaultParameterValue
+{
+    my $parameterType = shift;
+    my $defaultValue = shift;
+
+    if ($defaultValue eq "[]") {
+        # Dictionary(state, undefined) will construct an empty Dictionary.
+        return 1 if $parameterType eq "Dictionary";
+
+        # toRefPtrNativeArray() will convert undefined to an empty Vector.
+        return 1 if $codeGenerator->GetArrayType($parameterType) or $codeGenerator->GetSequenceType($parameterType);
+    }
+
+    # toString() will convert undefined to the string "undefined";
+    return 1 if $parameterType eq "DOMString" and $defaultValue eq "undefined";
+
+    # JSValue::toBoolean() will convert undefined to false.
+    return 1 if $parameterType eq "boolean" and $defaultValue eq "false";
+
+    # JSValue::toInt*() / JSValue::toUint*() will convert undefined to 0.
+    if ($defaultValue eq "0") {
+        return 1 if $parameterType eq "byte" or $parameterType eq "octet";
+        return 1 if $parameterType eq "short" or $parameterType eq "unsigned short";
+        return 1 if $parameterType eq "long" or $parameterType eq "unsigned long";
+        return 1 if $parameterType eq "long long" or $parameterType eq "unsigned long long";
+    }
+
+    if ($defaultValue eq "NaN") {
+        # toNumber() / toFloat() convert undefined to NaN.
+        return 1 if $parameterType eq "double" or $parameterType eq "unrestricted double";
+        return 1 if $parameterType eq "float" or $parameterType eq "unrestricted float";
+    }
+
+    return 0;
+}
+
 sub GenerateParametersCheck
 {
     my $outputArray = shift;
@@ -3434,12 +3469,13 @@
     $implIncludes{"JSDOMBinding.h"} = 1;
     foreach my $parameter (@{$function->parameters}) {
         my $argType = $parameter->type;
+        my $optional = $parameter->isOptional;
 
-        # Optional arguments with [Optional] should generate an early call with fewer arguments.
-        # Optional arguments with [Optional=...] should not generate the early call.
-        # Optional Dictionary arguments always considered to have default of empty dictionary.
-        my $optional = $parameter->isOptional;
-        if ($optional && !defined($parameter->default) && !CanUseWTFOptionalForParameter($parameter) && $argType ne "Dictionary" && !$codeGenerator->IsCallbackInterface($argType)) {
+        # As per Web IDL, optional dictionary parameters are always considered to have a default value of an empty dictionary, unless otherwise specified.
+        $parameter->default("[]") if ($optional && !defined($parameter->default) && $argType eq "Dictionary");
+
+        # FIXME: We should eventually stop generating any early calls, and instead use either default parameter values or WTF::Optional<>.
+        if ($optional && !defined($parameter->default) && !CanUseWTFOptionalForParameter($parameter) && !$codeGenerator->IsCallbackInterface($argType)) {
             # Generate early call if there are enough parameters.
             if (!$hasOptionalArguments) {
                 push(@$outputArray, "\n    size_t argsCount = state->argumentCount();\n");
@@ -3598,7 +3634,7 @@
                 my $inner;
                 my $nativeType = GetNativeTypeFromSignature($parameter);
 
-                if ($optional && defined($parameter->default)) {
+                if ($optional && defined($parameter->default) && !WillConvertUndefinedToDefaultParameterValue($parameter->type, $parameter->default)) {
                     my $defaultValue = $parameter->default;
 
                     # String-related optimizations.

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (200098 => 200099)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-04-26 18:20:09 UTC (rev 200098)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp	2016-04-26 18:22:40 UTC (rev 200099)
@@ -4194,7 +4194,7 @@
         return throwThisTypeError(*state, "TestObj", "methodWithOptionalDoubleIsNaN");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    double number = state->argument(0).isUndefined() ? PNaN : state->uncheckedArgument(0).toNumber(state);
+    double number = state->argument(0).toNumber(state);
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.methodWithOptionalDoubleIsNaN(number);
@@ -4209,7 +4209,7 @@
         return throwThisTypeError(*state, "TestObj", "methodWithOptionalFloatIsNaN");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    float number = state->argument(0).isUndefined() ? PNaN : state->uncheckedArgument(0).toFloat(state);
+    float number = state->argument(0).toFloat(state);
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.methodWithOptionalFloatIsNaN(number);
@@ -4224,7 +4224,7 @@
         return throwThisTypeError(*state, "TestObj", "methodWithOptionalSequence");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    Vector<String> sequence = state->argument(0).isUndefined() ? Vector<String>() : toNativeArray<String>(state, state->uncheckedArgument(0));
+    Vector<String> sequence = toNativeArray<String>(state, state->argument(0));
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.methodWithOptionalSequence(sequence);
@@ -4254,7 +4254,7 @@
         return throwThisTypeError(*state, "TestObj", "methodWithOptionalLongLongIsZero");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    long long number = state->argument(0).isUndefined() ? 0 : toInt64(state, state->uncheckedArgument(0), NormalConversion);
+    long long number = toInt64(state, state->argument(0), NormalConversion);
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.methodWithOptionalLongLongIsZero(number);
@@ -4284,7 +4284,7 @@
         return throwThisTypeError(*state, "TestObj", "methodWithOptionalUnsignedLongLongIsZero");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    unsigned long long number = state->argument(0).isUndefined() ? 0 : toUInt64(state, state->uncheckedArgument(0), NormalConversion);
+    unsigned long long number = toUInt64(state, state->argument(0), NormalConversion);
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.methodWithOptionalUnsignedLongLongIsZero(number);
@@ -4314,7 +4314,7 @@
         return throwThisTypeError(*state, "TestObj", "methodWithOptionalArrayIsEmpty");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    Vector<String> array = state->argument(0).isUndefined() ? Vector<String>() : toNativeArray<String>(state, state->uncheckedArgument(0));
+    Vector<String> array = toNativeArray<String>(state, state->argument(0));
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.methodWithOptionalArrayIsEmpty(array);
@@ -4344,7 +4344,7 @@
         return throwThisTypeError(*state, "TestObj", "methodWithOptionalBooleanIsFalse");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    bool b = state->argument(0).isUndefined() ? false : state->uncheckedArgument(0).toBoolean(state);
+    bool b = state->argument(0).toBoolean(state);
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.methodWithOptionalBooleanIsFalse(b);

Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp (200098 => 200099)


--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp	2016-04-26 18:20:09 UTC (rev 200098)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp	2016-04-26 18:22:40 UTC (rev 200099)
@@ -463,7 +463,7 @@
         return throwThisTypeError(*state, "TestTypedefs", "func");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestTypedefs::info());
     auto& impl = castedThis->wrapped();
-    Vector<int> x = state->argument(0).isUndefined() ? Vector<int>() : toNativeArray<int>(state, state->uncheckedArgument(0));
+    Vector<int> x = toNativeArray<int>(state, state->argument(0));
     if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
     impl.func(x);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to