Title: [228189] trunk/Source/WebCore
Revision
228189
Author
aes...@apple.com
Date
2018-02-06 13:45:21 -0800 (Tue, 06 Feb 2018)

Log Message

[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:

Modified Paths

Diff

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);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to