Modified: trunk/Source/WebCore/ChangeLog (228188 => 228189)
--- trunk/Source/WebCore/ChangeLog 2018-02-06 21:24:09 UTC (rev 228188)
+++ trunk/Source/WebCore/ChangeLog 2018-02-06 21:45:21 UTC (rev 228189)
@@ -1,3 +1,27 @@
+2018-02-06 Andy Estes <aes...@apple.com>
+
+ [WebIDL] Support optional Promise arguments
+ https://bugs.webkit.org/show_bug.cgi?id=182399
+ <rdar://problem/36754552>
+
+ Reviewed by Sam Weinig and Chris Dumez.
+
+ Previously, declaring a Promise argument as optional would result in a native type of
+ std::optional<RefPtr<DOMPromise>>. This is wasteful, since RefPtr can represent an optional
+ argument by storing nullptr. Further, PassArgumentExpression() assumed Promises were never
+ optional and tried to pass the argument as a Ref by calling RefPtr::releaseNonNull().
+
+ This patch removes the std::optional wrapper around optional Promises and simply passes the
+ promise as a RefPtr to native code.
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (PassArgumentExpression):
+ (GenerateParametersCheck):
+ * bindings/scripts/test/JS/JSTestObj.cpp:
+ (WebCore::jsTestObjPrototypeFunctionMethodWithOptionalPromiseBody):
+ (WebCore::jsTestObjPrototypeFunctionMethodWithOptionalPromise):
+ * bindings/scripts/test/TestObj.idl:
+
2018-02-06 Youenn Fablet <you...@apple.com>
HasServiceWorkerRegistration bit should be sent when creating a new page
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (228188 => 228189)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2018-02-06 21:24:09 UTC (rev 228188)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2018-02-06 21:45:21 UTC (rev 228189)
@@ -1538,13 +1538,13 @@
my $type = $context->type;
return "WTFMove(${name})" if $type->isNullable;
-
+
if ($codeGenerator->IsBufferSourceType($type)) {
return "*${name}" if $type->name eq "ArrayBuffer";
return "${name}.releaseNonNull()";
}
- return "${name}.releaseNonNull()" if $codeGenerator->IsCallbackInterface($type) || $codeGenerator->IsCallbackFunction($type) || $codeGenerator->IsPromiseType($type);
+ return "${name}.releaseNonNull()" if $codeGenerator->IsCallbackInterface($type) || $codeGenerator->IsCallbackFunction($type) || ($codeGenerator->IsPromiseType($type) && (ref($context) ne "IDLArgument" || !$context->isOptional));
return "*${name}" if $codeGenerator->IsWrapperType($type);
return "WTFMove(${name})";
}
@@ -5656,11 +5656,17 @@
}
} else {
my $argumentIDLType = GetIDLType($interface, $argument->type);
- my $defaultValue = "std::optional<Converter<$argumentIDLType>::ReturnType>()";
+ my $defaultValue;
+ if ($codeGenerator->IsPromiseType($argument->type)) {
+ $defaultValue = "nullptr";
+ } else {
+ $defaultValue = "std::optional<Converter<$argumentIDLType>::ReturnType>()";
+ $nativeValueCastFunction = "std::optional<Converter<$argumentIDLType>::ReturnType>";
+ }
+
$optionalCheck = "state->argument($argumentIndex).isUndefined() ? $defaultValue : ";
$argumentLookupForConversion = "state->uncheckedArgument($argumentIndex)";
- $nativeValueCastFunction = "std::optional<Converter<$argumentIDLType>::ReturnType>";
}
} else {
if ($argument->extendedAttributes->{ReturnValue}) {
@@ -5670,7 +5676,7 @@
$argumentLookupForConversion = "state->uncheckedArgument($argumentIndex)";
}
}
-
+
my $globalObjectReference = $operation->isStatic ? "*jsCast<JSDOMGlobalObject*>(state->lexicalGlobalObject())" : "*castedThis->globalObject()";
my $argumentExceptionThrower = GetArgumentExceptionThrower($interface, $argument, $argumentIndex, $quotedFunctionName);
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (228188 => 228189)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2018-02-06 21:24:09 UTC (rev 228188)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2018-02-06 21:45:21 UTC (rev 228189)
@@ -1492,6 +1492,7 @@
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapperIsNull(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalXPathNSResolver(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalRecord(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalPromise(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithCallbackArg(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNonCallbackArgAndCallbackArg(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithCallbackAndOptionalArg(JSC::ExecState*);
@@ -2166,6 +2167,7 @@
{ "methodWithOptionalNullableWrapperIsNull", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalNullableWrapperIsNull), (intptr_t) (0) } },
{ "methodWithOptionalXPathNSResolver", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalXPathNSResolver), (intptr_t) (0) } },
{ "methodWithOptionalRecord", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalRecord), (intptr_t) (0) } },
+ { "methodWithOptionalPromise", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithOptionalPromise), (intptr_t) (0) } },
{ "methodWithCallbackArg", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithCallbackArg), (intptr_t) (1) } },
{ "methodWithNonCallbackArgAndCallbackArg", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithNonCallbackArgAndCallbackArg), (intptr_t) (2) } },
{ "methodWithCallbackAndOptionalArg", static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithCallbackAndOptionalArg), (intptr_t) (0) } },
@@ -6638,6 +6640,22 @@
return IDLOperation<JSTestObj>::call<jsTestObjPrototypeFunctionMethodWithOptionalRecordBody>(*state, "methodWithOptionalRecord");
}
+static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithOptionalPromiseBody(JSC::ExecState* state, typename IDLOperation<JSTestObj>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ auto promise = state->argument(0).isUndefined() ? nullptr : convert<IDLPromise<IDLVoid>>(*state, state->uncheckedArgument(0));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ impl.methodWithOptionalPromise(WTFMove(promise));
+ return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithOptionalPromise(ExecState* state)
+{
+ return IDLOperation<JSTestObj>::call<jsTestObjPrototypeFunctionMethodWithOptionalPromiseBody>(*state, "methodWithOptionalPromise");
+}
+
static inline JSC::EncodedJSValue jsTestObjPrototypeFunctionMethodWithCallbackArgBody(JSC::ExecState* state, typename IDLOperation<JSTestObj>::ClassParameter castedThis, JSC::ThrowScope& throwScope)
{
UNUSED_PARAM(state);
Modified: trunk/Source/WebCore/bindings/scripts/test/TestObj.idl (228188 => 228189)
--- trunk/Source/WebCore/bindings/scripts/test/TestObj.idl 2018-02-06 21:24:09 UTC (rev 228188)
+++ trunk/Source/WebCore/bindings/scripts/test/TestObj.idl 2018-02-06 21:45:21 UTC (rev 228189)
@@ -239,6 +239,7 @@
void methodWithOptionalNullableWrapperIsNull(optional TestObj? obj = null);
void methodWithOptionalXPathNSResolver(optional XPathNSResolver? resolver);
void methodWithOptionalRecord(optional record<DOMString, long>? record = null);
+ void methodWithOptionalPromise(optional Promise<void> promise);
// Callback interface parameters.
void methodWithCallbackArg(TestCallbackInterface callback);