Skip to content
Permalink
Browse files
IPC testing JS API should expose a reply and describe the list of arg…
…uments for each message

https://bugs.webkit.org/show_bug.cgi?id=217565

Reviewed by Geoffrey Garen.

Source/WebKit:

This patch makes IPC.sendMessage and IPC.sendSyncMessage decode the reply. IPC.sendSyncMessage now returns
a dictionary with two keys: "buffer" and "arguments", the first of which returns ArrayBuffer of the decoded
message reply and the second of which is an array of decoded arguments where there was an appropriate JS
binding code existed for the argument type. IPC.sendMessage now returns a Promise which can either resolve
with the same dictionary as IPC.sendSyncMessage or reject when the decoding fails.

In addition, this patch exposes a dictionary describing each IPC message argument's type and parameter name.

In order to add these two functionalities, this patch adds a new step in generate-message-receiver.py to
generate MessageArgumentDescriptions.cpp, which contains functions which know how to decode arguments of
any IPC message and create a JS dictionary describing it as well as functions that return descriptions of
arguments or reply arguments.

Finally, this patch adds encoders for a few types found to be very common after r268239 had been landed.

Tests: TestWebKitAPI.IPCTestingAPI.DecodesReplyArgumentsForPrompt
       TestWebKitAPI.IPCTestingAPI.DecodesReplyArgumentsForAsyncMessage
       TestWebKitAPI.IPCTestingAPI.DescribesArguments

* CMakeLists.txt:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Platform/IPC/Decoder.h:
(IPC::Decoder::buffer const):
* Platform/IPC/JSIPCBinding.h: Added.
(jsValueForDecodedArgumentValue): Added. A template function to construct a JS value for a given C++ value.
(jsValueForDecodedNumericArgumentValue): Added. A helper for constructing a JS value for numeric values.
(jsValueForDecodedArgumentRect): Added. Ditto for IntRect and FloatRect.
(DecodedArgumentJSValueConverter): Added. A helper class to construct JS values for a tuple of values using
partial template specializations.
(DecodedArgumentJSValueConverter::convert): Added.
(jsValueForArgumentTuple): Added. A helper to construct a JS array for the decoded IPC arguments.
(jsValueForDecodedArguments): Added.
* Platform/IPC/MessageArgumentDescriptions.h: Added.
(IPC::ArgumentDescription): Added.
* Scripts/generate-message-receiver.py:
(main): Generate MessageArgumentDescriptions.cpp.
* Scripts/webkit/messages.py:
(headers_for_type): Removed the special case for PaymentMethodUpdate now that it's in its own header. Also
added made webrtc::WebKitEncodedFrameInfo include LibWebRTCEnumTraits.h as it uses webrtc::VideoFrameType.
(collect_header_conditions_for_receiver): Extracted from generate_message_handler.
(generate_header_includes_from_conditions): Ditto.
(generate_message_handler):
(generate_js_value_conversion_function): Added.
(generate_js_argument_descriptions): Added.
(generate_message_argument_description_implementation): Added.
* Shared/ApplePay/ApplePayPaymentSetupFeaturesWebKit.h: Fixed a bug that we were not forward declaring NSArray.
* SourcesCocoa.txt: Added MessageArgumentDescriptions.cpp as a non-unified cpp file as its size is around 1MB.
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebPage/IPCTestingAPI.cpp:
(WebKit::IPCTestingAPI::JSIPC::staticValues): Added the session ID and page ID as static variables.
(WebKit::IPCTestingAPI::encodePointType): Added.
(WebKit::IPCTestingAPI::encodeRectType): Fixed the bug was that this code wasn't checking for any exceptions.
(WebKit::IPCTestingAPI::encodeNumericType): Renamed from encodeIntegralType since this function is now used
to encode double and float, not just integral types.
(WebKit::IPCTestingAPI::encodeArgument): Added the support for IntPoint, FloatPoint, URL, RegistrableDomain,
double, and float all of which turned out to be in the top 20 most common types.
(WebKit::IPCTestingAPI::jsResultFromReplyDecoder): Added.
(WebKit::IPCTestingAPI::JSIPC::sendMessage): Added the code to return Promise when there is a reply and resolve
it with the JS object describing the decoded argument. We use messageReplyArgumentDescriptions to figure out
whether there is a reply or not.
(WebKit::IPCTestingAPI::JSIPC::sendSyncMessage): Decode the reply and return a JS object which describes it.
(WebKit::IPCTestingAPI::JSIPC::frameID): Renamed from frameIdentifier to be consistent.
(WebKit::IPCTestingAPI::JSIPC::pageID): Added.
(WebKit::IPCTestingAPI::JSIPC::sessionID): Added.
(WebKit::IPCTestingAPI::createJSArrayForArgumentDescriptions): Added.
(WebKit::IPCTestingAPI::JSIPC::messages): Added the code to generate descriptions for arguments.

Tools:

Added tests for decoding replies for sync and async messages and one for argument descriptions.

* TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm:
(-[IPCTestingAPIDelegate webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:]):
(-[IPCTestingAPIDelegate _webView:webContentProcessDidTerminateWithReason:]):
(IPCTestingAPI.DecodesReplyArgumentsForPrompt):
(IPCTestingAPI.DecodesReplyArgumentsForAsyncMessage):
(IPCTestingAPI.DescribesArguments):


Canonical link: https://commits.webkit.org/230426@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@268431 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
rniwa committed Oct 13, 2020
1 parent 33f5010 commit d078e28a4657db20c7d7de356c562fd5f6dda1e1
Showing 15 changed files with 931 additions and 60 deletions.
@@ -428,6 +428,7 @@ macro(GENERATE_MESSAGE_SOURCES _output_source _inputs)

add_custom_command(
OUTPUT
${WebKit_DERIVED_SOURCES_DIR}/MessageArgumentDescriptions.cpp
${WebKit_DERIVED_SOURCES_DIR}/MessageNames.cpp
${WebKit_DERIVED_SOURCES_DIR}/MessageNames.h
${_outputs}
@@ -1,3 +1,78 @@
2020-10-12 Ryosuke Niwa <rniwa@webkit.org>

IPC testing JS API should expose a reply and describe the list of arguments for each message
https://bugs.webkit.org/show_bug.cgi?id=217565

Reviewed by Geoffrey Garen.

This patch makes IPC.sendMessage and IPC.sendSyncMessage decode the reply. IPC.sendSyncMessage now returns
a dictionary with two keys: "buffer" and "arguments", the first of which returns ArrayBuffer of the decoded
message reply and the second of which is an array of decoded arguments where there was an appropriate JS
binding code existed for the argument type. IPC.sendMessage now returns a Promise which can either resolve
with the same dictionary as IPC.sendSyncMessage or reject when the decoding fails.

In addition, this patch exposes a dictionary describing each IPC message argument's type and parameter name.

In order to add these two functionalities, this patch adds a new step in generate-message-receiver.py to
generate MessageArgumentDescriptions.cpp, which contains functions which know how to decode arguments of
any IPC message and create a JS dictionary describing it as well as functions that return descriptions of
arguments or reply arguments.

Finally, this patch adds encoders for a few types found to be very common after r268239 had been landed.

Tests: TestWebKitAPI.IPCTestingAPI.DecodesReplyArgumentsForPrompt
TestWebKitAPI.IPCTestingAPI.DecodesReplyArgumentsForAsyncMessage
TestWebKitAPI.IPCTestingAPI.DescribesArguments

* CMakeLists.txt:
* DerivedSources-output.xcfilelist:
* DerivedSources.make:
* Platform/IPC/Decoder.h:
(IPC::Decoder::buffer const):
* Platform/IPC/JSIPCBinding.h: Added.
(jsValueForDecodedArgumentValue): Added. A template function to construct a JS value for a given C++ value.
(jsValueForDecodedNumericArgumentValue): Added. A helper for constructing a JS value for numeric values.
(jsValueForDecodedArgumentRect): Added. Ditto for IntRect and FloatRect.
(DecodedArgumentJSValueConverter): Added. A helper class to construct JS values for a tuple of values using
partial template specializations.
(DecodedArgumentJSValueConverter::convert): Added.
(jsValueForArgumentTuple): Added. A helper to construct a JS array for the decoded IPC arguments.
(jsValueForDecodedArguments): Added.
* Platform/IPC/MessageArgumentDescriptions.h: Added.
(IPC::ArgumentDescription): Added.
* Scripts/generate-message-receiver.py:
(main): Generate MessageArgumentDescriptions.cpp.
* Scripts/webkit/messages.py:
(headers_for_type): Removed the special case for PaymentMethodUpdate now that it's in its own header. Also
added made webrtc::WebKitEncodedFrameInfo include LibWebRTCEnumTraits.h as it uses webrtc::VideoFrameType.
(collect_header_conditions_for_receiver): Extracted from generate_message_handler.
(generate_header_includes_from_conditions): Ditto.
(generate_message_handler):
(generate_js_value_conversion_function): Added.
(generate_js_argument_descriptions): Added.
(generate_message_argument_description_implementation): Added.
* Shared/ApplePay/ApplePayPaymentSetupFeaturesWebKit.h: Fixed a bug that we were not forward declaring NSArray.
* SourcesCocoa.txt: Added MessageArgumentDescriptions.cpp as a non-unified cpp file as its size is around 1MB.
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/WebPage/IPCTestingAPI.cpp:
(WebKit::IPCTestingAPI::JSIPC::staticValues): Added the session ID and page ID as static variables.
(WebKit::IPCTestingAPI::encodePointType): Added.
(WebKit::IPCTestingAPI::encodeRectType): Fixed the bug was that this code wasn't checking for any exceptions.
(WebKit::IPCTestingAPI::encodeNumericType): Renamed from encodeIntegralType since this function is now used
to encode double and float, not just integral types.
(WebKit::IPCTestingAPI::encodeArgument): Added the support for IntPoint, FloatPoint, URL, RegistrableDomain,
double, and float all of which turned out to be in the top 20 most common types.
(WebKit::IPCTestingAPI::jsResultFromReplyDecoder): Added.
(WebKit::IPCTestingAPI::JSIPC::sendMessage): Added the code to return Promise when there is a reply and resolve
it with the JS object describing the decoded argument. We use messageReplyArgumentDescriptions to figure out
whether there is a reply or not.
(WebKit::IPCTestingAPI::JSIPC::sendSyncMessage): Decode the reply and return a JS object which describes it.
(WebKit::IPCTestingAPI::JSIPC::frameID): Renamed from frameIdentifier to be consistent.
(WebKit::IPCTestingAPI::JSIPC::pageID): Added.
(WebKit::IPCTestingAPI::JSIPC::sessionID): Added.
(WebKit::IPCTestingAPI::createJSArrayForArgumentDescriptions): Added.
(WebKit::IPCTestingAPI::JSIPC::messages): Added the code to generate descriptions for arguments.

2020-10-13 Ellie Epskamp-Hunt <eepskamphunt@apple.com>

Expose a property on WKWebView to know if it's being inspected.
@@ -68,6 +68,7 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/LibWebRTCRemoteCodecsMessagesReplie
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/MediaPlayerPrivateRemoteMessageReceiver.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/MediaPlayerPrivateRemoteMessages.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/MediaPlayerPrivateRemoteMessagesReplies.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/MessageArgumentDescriptions.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/MessageNames.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/MessageNames.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/WebKit2/NPObjectMessageReceiverMessageReceiver.cpp
@@ -257,7 +257,7 @@ MESSAGE_RECEIVER_FILES := $(addsuffix MessageReceiver.cpp,$(notdir $(MESSAGE_REC
MESSAGES_FILES := $(addsuffix Messages.h,$(notdir $(MESSAGE_RECEIVERS)))
MESSAGE_REPLIES_FILES := $(addsuffix MessagesReplies.h,$(notdir $(MESSAGE_RECEIVERS)))

GENERATED_MESSAGES_FILES := $(MESSAGE_RECEIVER_FILES) $(MESSAGES_FILES) $(MESSAGE_REPLIES_FILES) MessageNames.h MessageNames.cpp
GENERATED_MESSAGES_FILES := $(MESSAGE_RECEIVER_FILES) $(MESSAGES_FILES) $(MESSAGE_REPLIES_FILES) MessageNames.h MessageNames.cpp MessageArgumentDescriptions.cpp
GENERATED_MESSAGES_FILES_AS_PATTERNS := $(subst .,%,$(GENERATED_MESSAGES_FILES))

MESSAGES_IN_FILES := $(addsuffix .messages.in,$(MESSAGE_RECEIVERS))
@@ -72,6 +72,7 @@ class Decoder {

static std::unique_ptr<Decoder> unwrapForTesting(Decoder&);

const uint8_t* buffer() const { return m_buffer; }
size_t length() const { return m_bufferEnd - m_buffer; }

WARN_UNUSED_RETURN bool isValid() const { return m_bufferPos != nullptr; }
@@ -0,0 +1,255 @@
/*
* Copyright (C) 2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include "Decoder.h"
#include "HandleMessage.h"
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSGlobalObject.h>
#include <JavaScriptCore/JSObject.h>
#include <JavaScriptCore/ObjectConstructor.h>
#include <WebCore/FloatRect.h>
#include <WebCore/IntRect.h>
#include <WebCore/RegistrableDomain.h>
#include <wtf/ObjectIdentifier.h>
#include <wtf/URL.h>
#include <wtf/text/WTFString.h>

template<typename T, std::enable_if_t<!std::is_arithmetic<T>::value && !std::is_enum<T>::value>* = nullptr>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject*, const T&)
{
return JSC::jsUndefined();
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, const String& value)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto* object = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "type"_s), JSC::jsNontrivialString(vm, "String"_s));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "value"_s), JSC::jsNontrivialString(vm, value));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
return object;
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, const URL& value)
{
return jsValueForDecodedArgumentValue(globalObject, value.string());
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, const WebCore::RegistrableDomain& value)
{
return jsValueForDecodedArgumentValue(globalObject, value.string());
}

template<typename T, std::enable_if_t<std::is_arithmetic<T>::value>* = nullptr>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject*, T)
{
}

template<typename E, std::enable_if_t<std::is_enum<E>::value>* = nullptr>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, E value)
{
return jsValueForDecodedArgumentValue(globalObject, static_cast<std::underlying_type_t<E>>(value));
}

template<typename NumericType>
JSC::JSValue jsValueForDecodedNumericArgumentValue(JSC::JSGlobalObject* globalObject, NumericType value, const String& type)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto* object = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "type"_s), JSC::jsNontrivialString(vm, type));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "value"_s), JSC::JSValue(value));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
return object;
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, bool value)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto* object = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "type"_s), JSC::jsNontrivialString(vm, "bool"));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "value"_s), JSC::jsBoolean(value));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
return object;
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, double value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "double");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, float value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "float");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, int8_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "int8_t");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, int16_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "int16_t");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, int32_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "int32_t");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, int64_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "int64_t");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, uint8_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "uint8_t");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, uint16_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "uint16_t");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, uint32_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "uint32_t");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, uint64_t value)
{
return jsValueForDecodedNumericArgumentValue(globalObject, value, "uint64_t");
}

template<typename U>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, const ObjectIdentifier<U>& value)
{
return jsValueForDecodedArgumentValue(globalObject, value.toUInt64());
}

template<typename RectType>
JSC::JSValue jsValueForDecodedArgumentRect(JSC::JSGlobalObject* globalObject, const RectType& value, const String& type)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
auto* object = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "type"_s), JSC::jsNontrivialString(vm, type));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "x"_s), JSC::JSValue(value.x()));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "y"_s), JSC::JSValue(value.y()));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "width"_s), JSC::JSValue(value.width()));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
object->putDirect(vm, JSC::Identifier::fromString(vm, "height"_s), JSC::JSValue(value.height()));
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
return object;
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, const WebCore::IntRect& value)
{
return jsValueForDecodedArgumentRect(globalObject, value, "IntRect");
}

template<>
JSC::JSValue jsValueForDecodedArgumentValue(JSC::JSGlobalObject* globalObject, const WebCore::FloatRect& value)
{
return jsValueForDecodedArgumentRect(globalObject, value, "FloatRect");
}

template<size_t remainingSize, typename... Elements>
struct DecodedArgumentJSValueConverter {
static bool convert(JSC::JSGlobalObject* globalObject, JSC::JSArray* array, const std::tuple<Elements...>& tuple)
{
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());

auto jsValue = jsValueForDecodedArgumentValue(globalObject, std::get<sizeof...(Elements) - remainingSize>(tuple));
if (jsValue.isEmpty())
return false;

unsigned index = sizeof...(Elements) - remainingSize;
array->putDirectIndex(globalObject, index, jsValue);
RETURN_IF_EXCEPTION(scope, false);

return DecodedArgumentJSValueConverter<remainingSize - 1, Elements...>::convert(globalObject, array, tuple);
}
};

template<typename... Elements>
struct DecodedArgumentJSValueConverter<0, Elements...> {
static bool convert(JSC::JSGlobalObject*, JSC::JSArray*, const std::tuple<Elements...>&)
{
return true;
}
};

template<typename... Elements>
static JSC::JSValue jsValueForArgumentTuple(JSC::JSGlobalObject* globalObject, const std::tuple<Elements...>& tuple)
{
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
auto* array = JSC::constructEmptyArray(globalObject, nullptr);
RETURN_IF_EXCEPTION(scope, JSC::JSValue());
if (!DecodedArgumentJSValueConverter<sizeof...(Elements), Elements...>::convert(globalObject, array, tuple))
return JSC::JSValue();
return JSC::JSValue(array);
}

template<typename T>
static Optional<JSC::JSValue> jsValueForDecodedArguments(JSC::JSGlobalObject* globalObject, IPC::Decoder& decoder)
{
Optional<typename IPC::CodingType<T>::Type> arguments;
decoder >> arguments;
if (!arguments)
return WTF::nullopt;
return jsValueForArgumentTuple(globalObject, *arguments);
}

0 comments on commit d078e28

Please sign in to comment.