Commit 2469bf5b authored by jl@opera.com's avatar jl@opera.com

IDL: Improve overload resolution for methods with variadic arguments

When calculating "optionality list" for a method (as part of calculating
the effective overload set), treat variadic arguments as optional instead
as required.

WebIDL defines the optionality list as a list of "required", "optional"
and "variadic", whereas we implement it as a list of booleans. A list of
booleans is enough to achieve correct behavior, assuming both "optional"
and "variadic" are considered to be optional (true).

BUG=293561

Review URL: https://codereview.chromium.org/723013003

git-svn-id: svn://svn.chromium.org/blink/trunk@185289 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 38a81a20
...@@ -636,8 +636,9 @@ def effective_overload_set(F): ...@@ -636,8 +636,9 @@ def effective_overload_set(F):
# if X’s argument at index i is a final, variadic argument, “optional” # if X’s argument at index i is a final, variadic argument, “optional”
# if the argument is optional, and “required” otherwise. # if the argument is optional, and “required” otherwise.
# (“optionality list”) # (“optionality list”)
# (We’re just using a boolean for optional vs. required.) # (We’re just using a boolean for optional/variadic vs. required.)
o = tuple(argument['is_optional'] for argument in arguments) o = tuple(argument['is_optional'] or argument['is_variadic']
for argument in arguments)
# 4. Add to S the tuple <X, t0..n−1, o0..n−1>. # 4. Add to S the tuple <X, t0..n−1, o0..n−1>.
S.append((X, t, o)) S.append((X, t, o))
# 5. If X is declared to be variadic, then: # 5. If X is declared to be variadic, then:
......
...@@ -235,6 +235,7 @@ def argument_context(interface, method, argument, index): ...@@ -235,6 +235,7 @@ def argument_context(interface, method, argument, index):
'is_dictionary': idl_type.is_dictionary or idl_type.base_type == 'Dictionary', 'is_dictionary': idl_type.is_dictionary or idl_type.base_type == 'Dictionary',
'is_nullable': idl_type.is_nullable, 'is_nullable': idl_type.is_nullable,
'is_optional': argument.is_optional, 'is_optional': argument.is_optional,
'is_variadic': argument.is_variadic,
'is_variadic_wrapper_type': is_variadic_wrapper_type, 'is_variadic_wrapper_type': is_variadic_wrapper_type,
'is_wrapper_type': idl_type.is_wrapper_type, 'is_wrapper_type': idl_type.is_wrapper_type,
'name': argument.name, 'name': argument.name,
......
...@@ -450,6 +450,8 @@ interface TestObject { ...@@ -450,6 +450,8 @@ interface TestObject {
void overloadedMethodJ(TestDictionary testDictionaryArg); void overloadedMethodJ(TestDictionary testDictionaryArg);
void overloadedMethodK(Function functionArg); void overloadedMethodK(Function functionArg);
void overloadedMethodK(DOMString stringArg); void overloadedMethodK(DOMString stringArg);
void overloadedMethodL(long longArg, any... restArgs);
void overloadedMethodL(DOMString stringArg, any... restArgs);
Promise promiseOverloadMethod(); Promise promiseOverloadMethod();
Promise promiseOverloadMethod(Window arg1, double arg2); Promise promiseOverloadMethod(Window arg1, double arg2);
......
...@@ -8323,6 +8323,80 @@ static void overloadedMethodKMethodCallback(const v8::FunctionCallbackInfo<v8::V ...@@ -8323,6 +8323,80 @@ static void overloadedMethodKMethodCallback(const v8::FunctionCallbackInfo<v8::V
TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution"); TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
} }
static void overloadedMethodL1Method(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "overloadedMethodL", "TestObject", info.Holder(), info.GetIsolate());
TestObject* impl = V8TestObject::toImpl(info.Holder());
int longArg;
Vector<ScriptValue> restArgs;
{
TONATIVE_VOID_EXCEPTIONSTATE_INTERNAL(longArg, toInt32(info[0], exceptionState), exceptionState);
TONATIVE_VOID_EXCEPTIONSTATE_INTERNAL(restArgs, toImplArguments<ScriptValue>(info, 1, exceptionState), exceptionState);
}
impl->overloadedMethodL(longArg, restArgs);
}
static void overloadedMethodL2Method(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "overloadedMethodL", "TestObject", info.Holder(), info.GetIsolate());
TestObject* impl = V8TestObject::toImpl(info.Holder());
V8StringResource<> stringArg;
Vector<ScriptValue> restArgs;
{
TOSTRING_VOID_INTERNAL(stringArg, info[0]);
TONATIVE_VOID_EXCEPTIONSTATE_INTERNAL(restArgs, toImplArguments<ScriptValue>(info, 1, exceptionState), exceptionState);
}
impl->overloadedMethodL(stringArg, restArgs);
}
static void overloadedMethodLMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "overloadedMethodL", "TestObject", info.Holder(), info.GetIsolate());
switch (std::min(2, info.Length())) {
case 1:
if (info[0]->IsNumber()) {
overloadedMethodL1Method(info);
return;
}
if (true) {
overloadedMethodL2Method(info);
return;
}
if (true) {
overloadedMethodL1Method(info);
return;
}
break;
case 2:
if (info[0]->IsNumber()) {
overloadedMethodL1Method(info);
return;
}
if (true) {
overloadedMethodL2Method(info);
return;
}
if (true) {
overloadedMethodL1Method(info);
return;
}
break;
default:
exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
exceptionState.throwIfNeeded();
return;
}
exceptionState.throwTypeError("No function was found that matched the signature provided.");
exceptionState.throwIfNeeded();
}
static void overloadedMethodLMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMMethod");
TestObjectV8Internal::overloadedMethodLMethod(info);
TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
}
static void promiseOverloadMethod1Method(const v8::FunctionCallbackInfo<v8::Value>& info) static void promiseOverloadMethod1Method(const v8::FunctionCallbackInfo<v8::Value>& info)
{ {
TestObject* impl = V8TestObject::toImpl(info.Holder()); TestObject* impl = V8TestObject::toImpl(info.Holder());
...@@ -10732,6 +10806,7 @@ static const V8DOMConfiguration::MethodConfiguration V8TestObjectMethods[] = { ...@@ -10732,6 +10806,7 @@ static const V8DOMConfiguration::MethodConfiguration V8TestObjectMethods[] = {
{"overloadedMethodI", TestObjectV8Internal::overloadedMethodIMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts}, {"overloadedMethodI", TestObjectV8Internal::overloadedMethodIMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts},
{"overloadedMethodJ", TestObjectV8Internal::overloadedMethodJMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts}, {"overloadedMethodJ", TestObjectV8Internal::overloadedMethodJMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts},
{"overloadedMethodK", TestObjectV8Internal::overloadedMethodKMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts}, {"overloadedMethodK", TestObjectV8Internal::overloadedMethodKMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts},
{"overloadedMethodL", TestObjectV8Internal::overloadedMethodLMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts},
{"promiseOverloadMethod", TestObjectV8Internal::promiseOverloadMethodMethodCallback, 0, 0, V8DOMConfiguration::ExposedToAllScripts}, {"promiseOverloadMethod", TestObjectV8Internal::promiseOverloadMethodMethodCallback, 0, 0, V8DOMConfiguration::ExposedToAllScripts},
{"overloadedPerWorldBindingsMethod", TestObjectV8Internal::overloadedPerWorldBindingsMethodMethodCallback, TestObjectV8Internal::overloadedPerWorldBindingsMethodMethodCallbackForMainWorld, 0, V8DOMConfiguration::ExposedToAllScripts}, {"overloadedPerWorldBindingsMethod", TestObjectV8Internal::overloadedPerWorldBindingsMethodMethodCallback, TestObjectV8Internal::overloadedPerWorldBindingsMethodMethodCallbackForMainWorld, 0, V8DOMConfiguration::ExposedToAllScripts},
{"voidMethodClampUnsignedShortArg", TestObjectV8Internal::voidMethodClampUnsignedShortArgMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts}, {"voidMethodClampUnsignedShortArg", TestObjectV8Internal::voidMethodClampUnsignedShortArgMethodCallback, 0, 1, V8DOMConfiguration::ExposedToAllScripts},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment