Skip to content

Commit

Permalink
Variadic params to callbacks aren't handled correctly
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=267332

Reviewed by Chris Dumez.

Updates code generator to handle variadic params to callbacks.

* Source/WebCore/bindings/scripts/CodeGeneratorJS.pm:
(GenerateCallbackHeaderContent):
(GenerateCallbackImplementationContent):
* Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithVariadic.cpp: Added.
(WebCore::JSTestCallbackFunctionWithVariadic::JSTestCallbackFunctionWithVariadic):
(WebCore::JSTestCallbackFunctionWithVariadic::~JSTestCallbackFunctionWithVariadic):
(WebCore::JSTestCallbackFunctionWithVariadic::handleEvent):
(WebCore::toJS):
* Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithVariadic.h: Added.
(WebCore::toJS):
* Source/WebCore/bindings/scripts/test/SupplementalDependencies.dep:
* Source/WebCore/bindings/scripts/test/TestCallbackFunctionWithVariadic.idl: Added.

Canonical link: https://commits.webkit.org/272855@main
  • Loading branch information
lukewarlow authored and cdumez committed Jan 10, 2024
1 parent 90db5be commit fcfe0a5
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 4 deletions.
24 changes: 20 additions & 4 deletions Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6672,7 +6672,12 @@ sub GenerateCallbackHeaderContent

foreach my $argument (@{$operation->arguments}) {
my $IDLType = GetIDLType($interfaceOrCallback, $argument->type);
push(@arguments, "typename ${IDLType}::ParameterType " . $argument->name);
if ($argument->isVariadic) {
AddToIncludes("JSDOMConvertVariadic.h", $includesRef, 1);
push(@arguments, "FixedVector<typename VariadicConverter<${IDLType}>::Item>&& " . $argument->name);
} else {
push(@arguments, "typename ${IDLType}::ParameterType " . $argument->name);
}
}

my $nativeReturnType = "CallbackResult<typename " . GetIDLType($interfaceOrCallback, $operation->type) . "::ImplementationType>";
Expand Down Expand Up @@ -6815,9 +6820,13 @@ sub GenerateCallbackImplementationContent
}

foreach my $argument (@{$operation->arguments}) {
AddToIncludesForIDLType($argument->type, $includesRef, 1);
my $IDLType = GetIDLType($interfaceOrCallback, $argument->type);
push(@arguments, "typename ${IDLType}::ParameterType " . $argument->name);
if ($argument->isVariadic) {
push(@arguments, "FixedVector<typename VariadicConverter<${IDLType}>::Item>&& " . $argument->name);
} else {
AddToIncludesForIDLType($argument->type, $includesRef, 1);
push(@arguments, "typename ${IDLType}::ParameterType " . $argument->name);
}
}

push(@$contentRef, "${nativeReturnType} ${className}::${functionImplementationName}(" . join(", ", @arguments) . ")\n");
Expand All @@ -6841,7 +6850,14 @@ sub GenerateCallbackImplementationContent
push(@$contentRef, " MarkedArgumentBuffer args;\n");

foreach my $argument (@{$operation->arguments}) {
push(@$contentRef, " args.append(" . NativeToJSValueUsingReferences($argument, $interfaceOrCallback, $argument->name, "globalObject") . ");\n");
if ($argument->isVariadic) {
my $argumentName = $argument->name;
push(@$contentRef, " for (auto&& ${argumentName}Item : WTFMove(${argumentName})) {\n");
push(@$contentRef, " args.append(" . NativeToJSValueUsingReferences($argument, $interfaceOrCallback, "WTFMove(${argumentName}Item)", "globalObject") . ");\n");
push(@$contentRef, " }\n");
} else {
push(@$contentRef, " args.append(" . NativeToJSValueUsingReferences($argument, $interfaceOrCallback, $argument->name, "globalObject") . ");\n");
}
}
push(@$contentRef, " ASSERT(!args.hasOverflowed());\n");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "JSTestCallbackFunctionWithVariadic.h"

#include "ContextDestructionObserverInlines.h"
#include "JSDOMConvertAny.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMExceptionHandling.h"
#include "ScriptExecutionContext.h"


namespace WebCore {
using namespace JSC;

JSTestCallbackFunctionWithVariadic::JSTestCallbackFunctionWithVariadic(JSObject* callback, JSDOMGlobalObject* globalObject)
: TestCallbackFunctionWithVariadic(globalObject->scriptExecutionContext())
, m_data(new JSCallbackDataStrong(callback, globalObject, this))
{
}

JSTestCallbackFunctionWithVariadic::~JSTestCallbackFunctionWithVariadic()
{
ScriptExecutionContext* context = scriptExecutionContext();
// When the context is destroyed, all tasks with a reference to a callback
// should be deleted. So if the context is 0, we are on the context thread.
if (!context || context->isContextThread())
delete m_data;
else
context->postTask(DeleteCallbackDataTask(m_data));
#ifndef NDEBUG
m_data = nullptr;
#endif
}

CallbackResult<typename IDLDOMString::ImplementationType> JSTestCallbackFunctionWithVariadic::handleEvent(FixedVector<typename VariadicConverter<IDLAny>::Item>&& arguments)
{
if (!canInvokeCallback())
return CallbackResultType::UnableToExecute;

Ref<JSTestCallbackFunctionWithVariadic> protectedThis(*this);

auto& globalObject = *m_data->globalObject();
auto& vm = globalObject.vm();

JSLockHolder lock(vm);
auto& lexicalGlobalObject = globalObject;
JSValue thisValue = jsUndefined();
MarkedArgumentBuffer args;
for (auto&& argumentsItem : WTFMove(arguments)) {
args.append(toJS<IDLAny>(WTFMove(argumentsItem)));
}
ASSERT(!args.hasOverflowed());

NakedPtr<JSC::Exception> returnedException;
auto jsResult = m_data->invokeCallback(thisValue, args, JSCallbackData::CallbackType::Function, Identifier(), returnedException);
if (returnedException) {
UNUSED_PARAM(lexicalGlobalObject);
reportException(m_data->callback()->globalObject(), returnedException);
return CallbackResultType::ExceptionThrown;
}

auto throwScope = DECLARE_THROW_SCOPE(vm);
auto returnValue = convert<IDLDOMString>(lexicalGlobalObject, jsResult);
RETURN_IF_EXCEPTION(throwScope, CallbackResultType::ExceptionThrown);
return { WTFMove(returnValue) };
}

JSC::JSValue toJS(TestCallbackFunctionWithVariadic& impl)
{
if (!static_cast<JSTestCallbackFunctionWithVariadic&>(impl).callbackData())
return jsNull();

return static_cast<JSTestCallbackFunctionWithVariadic&>(impl).callbackData()->callback();
}

} // namespace WebCore
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/

#pragma once

#include "IDLTypes.h"
#include "JSCallbackData.h"
#include "JSDOMConvertVariadic.h"
#include "TestCallbackFunctionWithVariadic.h"
#include <wtf/Forward.h>

namespace WebCore {

class JSTestCallbackFunctionWithVariadic final : public TestCallbackFunctionWithVariadic {
public:
static Ref<JSTestCallbackFunctionWithVariadic> create(JSC::JSObject* callback, JSDOMGlobalObject* globalObject)
{
return adoptRef(*new JSTestCallbackFunctionWithVariadic(callback, globalObject));
}

ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }

~JSTestCallbackFunctionWithVariadic() final;
JSCallbackDataStrong* callbackData() { return m_data; }

// Functions
CallbackResult<typename IDLDOMString::ImplementationType> handleEvent(FixedVector<typename VariadicConverter<IDLAny>::Item>&& arguments) override;

private:
JSTestCallbackFunctionWithVariadic(JSC::JSObject*, JSDOMGlobalObject*);

JSCallbackDataStrong* m_data;
};

JSC::JSValue toJS(TestCallbackFunctionWithVariadic&);
inline JSC::JSValue toJS(TestCallbackFunctionWithVariadic* impl) { return impl ? toJS(*impl) : JSC::jsNull(); }

} // namespace WebCore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ JSTestCallbackFunction.h:
JSTestCallbackFunctionRethrow.h:
JSTestCallbackFunctionWithThisObject.h:
JSTestCallbackFunctionWithTypedefs.h:
JSTestCallbackFunctionWithVariadic.h:
JSTestCallbackInterface.h:
JSTestClassWithJSBuiltinConstructor.h:
JSTestConditionalIncludes.h: TestMixinInterface.idl
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (C) 2024 Igalia S.L. 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. ``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
* 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.
*/

callback TestCallbackFunctionWithVariadic = DOMString (any... arguments);

0 comments on commit fcfe0a5

Please sign in to comment.