Changeset 205542 in webkit


Ignore:
Timestamp:
Sep 7, 2016 3:03:43 AM (8 years ago)
Author:
nael.ouedraogo@crf.canon.fr
Message:

Templatize JS bindings code generator of functions with variadic parameters
https://bugs.webkit.org/show_bug.cgi?id=158835

Reviewed by Darin Adler.

Add template functions to handle function with variadic parameter for DOM objects.

  • Modules/mediastream/RTCPeerConnection.cpp:

(WebCore::RTCPeerConnection::addTrack):

  • Modules/mediastream/RTCPeerConnection.h:
  • bindings/js/JSDOMBinding.h:

(WebCore::VariadicHelperBase::convert):
(WebCore::toArguments):
(WebCore::jsFrozenArray):
(WebCore::toRefPtrNativeArray):
(WebCore::toNativeArray):

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateParametersCheck):
(GetVariadicType):

  • bindings/scripts/test/JS/JSTestObj.cpp:

(WebCore::jsTestObjPrototypeFunctionOverloadedMethod12):
(WebCore::jsTestObjPrototypeFunctionVariadicStringMethod):
(WebCore::jsTestObjPrototypeFunctionVariadicDoubleMethod):
(WebCore::jsTestObjPrototypeFunctionVariadicNodeMethod):
(WebCore::jsTestObjPrototypeFunctionOverloadedMethod):
(WebCore::jsTestObjPrototypeFunctionAny):

  • bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:

(WebCore::constructJSTestOverloadedConstructors5):

Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r205533 r205542  
     12016-09-07  Nael Ouedraogo  <nael.ouedraogo@crf.canon.fr>
     2
     3        Templatize JS bindings code generator of functions with variadic parameters
     4        https://bugs.webkit.org/show_bug.cgi?id=158835
     5
     6        Reviewed by Darin Adler.
     7
     8        Add template functions to handle function with variadic parameter for DOM objects.
     9
     10        * Modules/mediastream/RTCPeerConnection.cpp:
     11        (WebCore::RTCPeerConnection::addTrack):
     12        * Modules/mediastream/RTCPeerConnection.h:
     13        * bindings/js/JSDOMBinding.h:
     14        (WebCore::VariadicHelperBase::convert):
     15        (WebCore::toArguments):
     16        (WebCore::jsFrozenArray):
     17        (WebCore::toRefPtrNativeArray):
     18        (WebCore::toNativeArray):
     19        * bindings/scripts/CodeGeneratorJS.pm:
     20        (GenerateParametersCheck):
     21        (GetVariadicType):
     22        * bindings/scripts/test/JS/JSTestObj.cpp:
     23        (WebCore::jsTestObjPrototypeFunctionOverloadedMethod12):
     24        (WebCore::jsTestObjPrototypeFunctionVariadicStringMethod):
     25        (WebCore::jsTestObjPrototypeFunctionVariadicDoubleMethod):
     26        (WebCore::jsTestObjPrototypeFunctionVariadicNodeMethod):
     27        (WebCore::jsTestObjPrototypeFunctionOverloadedMethod):
     28        (WebCore::jsTestObjPrototypeFunctionAny):
     29        * bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:
     30        (WebCore::constructJSTestOverloadedConstructors5):
     31
    1322016-09-06  Commit Queue  <commit-queue@webkit.org>
    233
  • trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp

    r202378 r205542  
    9494}
    9595
    96 RefPtr<RTCRtpSender> RTCPeerConnection::addTrack(Ref<MediaStreamTrack>&& track, const Vector<MediaStream*>& streams, ExceptionCode& ec)
     96RefPtr<RTCRtpSender> RTCPeerConnection::addTrack(Ref<MediaStreamTrack>&& track, const Vector<std::reference_wrapper<MediaStream>>& streams, ExceptionCode& ec)
    9797{
    9898    if (m_signalingState == SignalingState::Closed) {
     
    116116    Vector<String> mediaStreamIds;
    117117    for (auto stream : streams)
    118         mediaStreamIds.append(stream->id());
     118        mediaStreamIds.append(stream.get().id());
    119119
    120120    RTCRtpSender* sender = nullptr;
  • trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h

    r202376 r205542  
    7373    Vector<RefPtr<MediaStream>> getRemoteStreams() const { return m_backend->getRemoteStreams(); }
    7474
    75     RefPtr<RTCRtpSender> addTrack(Ref<MediaStreamTrack>&&, const Vector<MediaStream*>&, ExceptionCode&);
     75    RefPtr<RTCRtpSender> addTrack(Ref<MediaStreamTrack>&&, const Vector<std::reference_wrapper<MediaStream>>&, ExceptionCode&);
    7676    void removeTrack(RTCRtpSender&, ExceptionCode&);
    7777
  • trunk/Source/WebCore/bindings/js/JSDOMBinding.h

    r205462 r205542  
    297297template<typename T, typename JSType> Vector<RefPtr<T>> toRefPtrNativeArray(JSC::ExecState*, JSC::JSValue);
    298298template<typename T> Vector<T> toNativeArray(JSC::ExecState&, JSC::JSValue);
    299 template<typename T> Vector<T> toNativeArguments(JSC::ExecState&, size_t startIndex = 0);
    300299bool hasIteratorMethod(JSC::ExecState&, JSC::JSValue);
    301300
     
    324323
    325324template<JSC::NativeFunction, int length> JSC::EncodedJSValue nonCachingStaticFunctionGetter(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
     325
     326template<typename T> struct NativeValueTraits;
     327
     328template<typename JSClass, typename DOMClass, typename Enable = void>
     329struct VariadicHelperBase {
     330    using Item = DOMClass;
     331
     332    static Optional<Item> convert(JSC::ExecState& state, JSC::JSValue jsValue)
     333    {
     334        typedef NativeValueTraits<DOMClass> TraitsType;
     335        DOMClass indexValue;
     336        if (!TraitsType::nativeValue(state, jsValue, indexValue))
     337            return Nullopt;
     338        return indexValue;
     339    }
     340};
     341
     342template<typename JSClass, typename DOMClass>
     343struct VariadicHelperBase<JSClass, DOMClass, typename std::enable_if<!JSDOMObjectInspector<JSClass>::isBuiltin>::type> {
     344    using Class = typename std::remove_reference<decltype(std::declval<JSClass>().wrapped())>::type;
     345    using Item = std::reference_wrapper<Class>;
     346
     347    static Optional<Item> convert(JSC::ExecState&, JSC::JSValue jsValue)
     348    {
     349        auto* value = JSClass::toWrapped(jsValue);
     350        if (!value)
     351            return Nullopt;
     352        return Optional<Item>(*value);
     353    }
     354};
     355
     356template<typename JSClass, typename DOMClass>
     357struct VariadicHelper : public VariadicHelperBase<JSClass, DOMClass> {
     358    using Item = typename VariadicHelperBase<JSClass, DOMClass>::Item;
     359    using Container = Vector<Item>;
     360    using Result = typename std::pair<size_t, Optional<Container>>;
     361};
     362
     363template<typename VariadicHelper> typename VariadicHelper::Result toArguments(JSC::ExecState&, size_t startIndex = 0);
    326364
    327365// Inline functions and template definitions.
     
    705743inline RefPtr<JSC::Float64Array> toFloat64Array(JSC::JSValue value) { return JSC::toNativeTypedView<JSC::Float64Adaptor>(value); }
    706744
    707 template<typename T> struct NativeValueTraits;
    708 
    709745template<> struct NativeValueTraits<String> {
    710746    static inline bool nativeValue(JSC::ExecState& exec, JSC::JSValue jsValue, String& indexedValue)
     
    782818}
    783819
    784 template<typename T> Vector<T> toNativeArguments(JSC::ExecState& exec, size_t startIndex)
    785 {
    786     size_t length = exec.argumentCount();
    787     ASSERT(startIndex <= length);
    788 
    789     Vector<T> result;
    790     result.reserveInitialCapacity(length - startIndex);
    791     typedef NativeValueTraits<T> TraitsType;
    792 
    793     for (size_t i = startIndex; i < length; ++i) {
    794         T indexValue;
    795         if (!TraitsType::nativeValue(exec, exec.uncheckedArgument(i), indexValue))
    796             return Vector<T>();
    797         result.uncheckedAppend(indexValue);
    798     }
    799     return result;
    800 }
    801 
    802820inline String propertyNameToString(JSC::PropertyName propertyName)
    803821{
     
    809827{
    810828    return AtomicString(propertyName.uid() ? propertyName.uid() : propertyName.publicName());
     829}
     830
     831template<typename VariadicHelper> typename VariadicHelper::Result toArguments(JSC::ExecState& state, size_t startIndex)
     832{
     833    size_t length = state.argumentCount();
     834    if (startIndex > length)
     835        return { 0, Nullopt };
     836
     837    typename VariadicHelper::Container result;
     838    result.reserveInitialCapacity(length - startIndex);
     839
     840    for (size_t i = startIndex; i < length; ++i) {
     841        auto value = VariadicHelper::convert(state, state.uncheckedArgument(i));
     842        if (!value)
     843            return { i, Nullopt };
     844        result.uncheckedAppend(WTFMove(value.value()));
     845    }
     846    return { length, WTFMove(result) };
    811847}
    812848
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r205422 r205542  
    39003900        $functionName = "impl.${functionImplementationName}";
    39013901    }
    3902    
     3902
    39033903    my $quotedFunctionName;
    39043904    if (!$function->signature->extendedAttributes->{"Constructor"}) {
     
    39763976            $value = "WTFMove($name)";
    39773977        } elsif ($parameter->isVariadic) {
    3978             my $nativeElementType = GetNativeType($interface, $type);
    3979             if (!IsNativeType($type)) {
    3980                 push(@$outputArray, "    Vector<$nativeElementType> $name;\n");
    3981                 push(@$outputArray, "    ASSERT($argumentIndex <= state->argumentCount());\n");
    3982                 push(@$outputArray, "    $name.reserveInitialCapacity(state->argumentCount() - $argumentIndex);\n");
    3983                 push(@$outputArray, "    for (unsigned i = $argumentIndex, count = state->argumentCount(); i < count; ++i) {\n");
    3984                 push(@$outputArray, "        auto* item = JS${type}::toWrapped(state->uncheckedArgument(i));\n");
    3985                 push(@$outputArray, "        if (!item)\n");
    3986                 push(@$outputArray, "            return throwArgumentTypeError(*state, throwScope, i, \"$name\", \"$visibleInterfaceName\", $quotedFunctionName, \"$type\");\n");
    3987                 push(@$outputArray, "        $name.uncheckedAppend(item);\n");
    3988                 push(@$outputArray, "    }\n")
    3989             } else {
    3990                 push(@$outputArray, "    Vector<$nativeElementType> $name = toNativeArguments<$nativeElementType>(*state, $argumentIndex);\n");
     3978            my ($wrapperType, $wrappedType) = GetVariadicType($interface, $type);
     3979            push(@$outputArray, "    auto $name = toArguments<VariadicHelper<$wrapperType, $wrappedType>>(*state, $argumentIndex);\n");
     3980
     3981            if (IsNativeType($type)) {
    39913982                push(@$outputArray, "    if (UNLIKELY(state->hadException()))\n");
    39923983                push(@$outputArray, "        return JSValue::encode(jsUndefined());\n");
    39933984            }
    3994             $value = "WTFMove($name)";
     3985            else {
     3986                push(@$outputArray, "    if (!$name.second)\n");
     3987                push(@$outputArray, "        return throwArgumentTypeError(*state, throwScope, $name.first, \"$name\", \"$visibleInterfaceName\", $quotedFunctionName, \"$type\");\n");
     3988            }
     3989            $value = "WTFMove(*$name.second)";
     3990
    39953991        } elsif ($codeGenerator->IsEnumType($type)) {
    39963992            my $className = GetEnumerationClassName($interface, $type);
     
    40574053                if ($parameter->isOptional && defined($parameter->default) && !WillConvertUndefinedToDefaultParameterValue($type, $parameter->default)) {
    40584054                    my $defaultValue = $parameter->default;
    4059    
     4055
    40604056                    # String-related optimizations.
    40614057                    if ($codeGenerator->IsStringType($type)) {
     
    40744070                        $defaultValue = "JSValue::JSUndefined" if $defaultValue eq "undefined";
    40754071                    }
    4076    
     4072
    40774073                    $outer = "state->argument($argumentIndex).isUndefined() ? $defaultValue : ";
    40784074                    $inner = "state->uncheckedArgument($argumentIndex)";
     
    46054601);
    46064602
     4603sub GetVariadicType
     4604{
     4605    my ($interface, $type) = @_;
     4606
     4607    my $wrappedType = IsNativeType($type) ? GetNativeType($interface, $type) : $type;
     4608    my $wrapperType = IsNativeType($type) ? "JSC::JSValue" : "JS$wrappedType";
     4609
     4610    return ($wrapperType, $wrappedType);
     4611}
     4612
    46074613sub GetNativeType
    46084614{
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp

    r205458 r205542  
    64766476    ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
    64776477    auto& impl = castedThis->wrapped();
    6478     Vector<Blob*> blobArgs;
    6479     ASSERT(0 <= state->argumentCount());
    6480     blobArgs.reserveInitialCapacity(state->argumentCount() - 0);
    6481     for (unsigned i = 0, count = state->argumentCount(); i < count; ++i) {
    6482         auto* item = JSBlob::toWrapped(state->uncheckedArgument(i));
    6483         if (!item)
    6484             return throwArgumentTypeError(*state, throwScope, i, "blobArgs", "TestObject", "overloadedMethod", "Blob");
    6485         blobArgs.uncheckedAppend(item);
    6486     }
    6487     impl.overloadedMethod(WTFMove(blobArgs));
     6478    auto blobArgs = toArguments<VariadicHelper<JSBlob, Blob>>(*state, 0);
     6479    if (!blobArgs.second)
     6480        return throwArgumentTypeError(*state, throwScope, blobArgs.first, "blobArgs", "TestObject", "overloadedMethod", "Blob");
     6481    impl.overloadedMethod(WTFMove(*blobArgs.second));
    64886482    return JSValue::encode(jsUndefined());
    64896483}
     
    70157009    if (UNLIKELY(state->hadException()))
    70167010        return JSValue::encode(jsUndefined());
    7017     Vector<String> tail = toNativeArguments<String>(*state, 1);
    7018     if (UNLIKELY(state->hadException()))
    7019         return JSValue::encode(jsUndefined());
    7020     impl.variadicStringMethod(WTFMove(head), WTFMove(tail));
     7011    auto tail = toArguments<VariadicHelper<JSC::JSValue, String>>(*state, 1);
     7012    if (UNLIKELY(state->hadException()))
     7013        return JSValue::encode(jsUndefined());
     7014    impl.variadicStringMethod(WTFMove(head), WTFMove(*tail.second));
    70217015    return JSValue::encode(jsUndefined());
    70227016}
     
    70387032    if (UNLIKELY(state->hadException()))
    70397033        return JSValue::encode(jsUndefined());
    7040     Vector<double> tail = toNativeArguments<double>(*state, 1);
    7041     if (UNLIKELY(state->hadException()))
    7042         return JSValue::encode(jsUndefined());
    7043     impl.variadicDoubleMethod(WTFMove(head), WTFMove(tail));
     7034    auto tail = toArguments<VariadicHelper<JSC::JSValue, double>>(*state, 1);
     7035    if (UNLIKELY(state->hadException()))
     7036        return JSValue::encode(jsUndefined());
     7037    impl.variadicDoubleMethod(WTFMove(head), WTFMove(*tail.second));
    70447038    return JSValue::encode(jsUndefined());
    70457039}
     
    70617055    if (UNLIKELY(!head))
    70627056        return throwArgumentTypeError(*state, throwScope, 0, "head", "TestObject", "variadicNodeMethod", "Node");
    7063     Vector<Node*> tail;
    7064     ASSERT(1 <= state->argumentCount());
    7065     tail.reserveInitialCapacity(state->argumentCount() - 1);
    7066     for (unsigned i = 1, count = state->argumentCount(); i < count; ++i) {
    7067         auto* item = JSNode::toWrapped(state->uncheckedArgument(i));
    7068         if (!item)
    7069             return throwArgumentTypeError(*state, throwScope, i, "tail", "TestObject", "variadicNodeMethod", "Node");
    7070         tail.uncheckedAppend(item);
    7071     }
    7072     impl.variadicNodeMethod(*head, WTFMove(tail));
     7057    auto tail = toArguments<VariadicHelper<JSNode, Node>>(*state, 1);
     7058    if (!tail.second)
     7059        return throwArgumentTypeError(*state, throwScope, tail.first, "tail", "TestObject", "variadicNodeMethod", "Node");
     7060    impl.variadicNodeMethod(*head, WTFMove(*tail.second));
    70737061    return JSValue::encode(jsUndefined());
    70747062}
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp

    r205458 r205542  
    141141    auto* castedThis = jsCast<JSTestOverloadedConstructorsConstructor*>(state->callee());
    142142    ASSERT(castedThis);
    143     Vector<int32_t> longArgs = toNativeArguments<int32_t>(*state, 0);
     143    auto longArgs = toArguments<VariadicHelper<JSC::JSValue, int32_t>>(*state, 0);
    144144    if (UNLIKELY(state->hadException()))
    145145        return JSValue::encode(jsUndefined());
Note: See TracChangeset for help on using the changeset viewer.