Skip to content
Permalink
Browse files
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):


Canonical link: https://commits.webkit.org/175154@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200099 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
cdumez committed Apr 26, 2016
1 parent 9742d65 commit 7e610b969bf5218c870dfc5b957af985665cce65
@@ -1,3 +1,22 @@
2016-04-26 Chris Dumez <cdumez@apple.com>

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 <antti@apple.com>

RenderElement::style() should return const RenderStyle
@@ -3383,13 +3383,48 @@ sub CanUseWTFOptionalForParameter
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 @@ sub GenerateParametersCheck
$implIncludes{"JSDOMBinding.h"} = 1;
foreach my $parameter (@{$function->parameters}) {
my $argType = $parameter->type;

# 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 @@ sub GenerateParametersCheck
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.
@@ -4194,7 +4194,7 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalDoubleI
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 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalFloatIs
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 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalSequenc
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 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalLongLon
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 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalUnsigne
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 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalArrayIs
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 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalBoolean
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);
@@ -463,7 +463,7 @@ EncodedJSValue JSC_HOST_CALL jsTestTypedefsPrototypeFunctionFunc(ExecState* stat
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);

0 comments on commit 7e610b9

Please sign in to comment.