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);