Commit df79808d authored by Hitoshi Yoshida's avatar Hitoshi Yoshida Committed by Commit Bot

bindings: Update overload resolution algorithm in bindings

Before this CL, overload resolution algorithm was based on old
version, and had some Blink specific customizes.
This CL updates it to be almost compatible with current spec,
except for types that Blink does not support.


Bug: 828401
Change-Id: Ia2ee07a08f45390f39258268608fd71fdd06da89
Reviewed-on: https://chromium-review.googlesource.com/1013798
Commit-Queue: Hitoshi Yoshida <peria@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558311}
parent b6b8be9d
......@@ -791,18 +791,26 @@ void {{v8_class}}Constructor::NamedConstructorAttributeGetter(
{% if constructor_overloads %}
static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info) {
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kConstructionContext, "{{interface_name}}");
{# 2. Initialize argcount to be min(maxarg, n). #}
{# This follows the overload resolution algorithm. #}
{# https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm #}
{# 3. Initialize argcount to be min(maxarg, n). #}
switch (std::min({{constructor_overloads.maxarg}}, info.Length())) {
{# 3. Remove from S all entries whose type list is not of length argcount. #}
{# 4. Remove from S all entries whose type list is not of length argcount. #}
{% for length, tests_constructors in constructor_overloads.length_tests_methods %}
{# 12. If i = d, then: #}
case {{length}}:
{# Then resolve by testing argument #}
{% for test, constructor in tests_constructors %}
{# 10. If i = d, then: #}
if ({{test}}) {
{{cpp_class}}V8Internal::constructor{{constructor.overload_index}}(info);
return;
}
{% if "exceptionState" in test %}
if (exceptionState.HadException()) {
exceptionState.RethrowV8Exception(exceptionState.GetException());
return;
}
{% endif %}
{% endfor %}
break;
{% endfor %}
......
......@@ -380,26 +380,32 @@ static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
{% if not fall_through_to_partial_overloads %}
bool isArityError = false;
{% endif %}
{# 2. Initialize argcount to be min(maxarg, n). #}
{# This follows the overload resolution algorithm. #}
{# https://heycam.github.io/webidl/#dfn-overload-resolution-algorithm #}
{# 3. Initialize argcount to be min(maxarg, n). #}
switch (std::min({{overloads.maxarg}}, info.Length())) {
{# 3. Remove from S all entries whose type list is not of length argcount. #}
{# 4. Remove from S all entries whose type list is not of length argcount. #}
{% for length, tests_methods in overloads.length_tests_methods %}
{# 10. If i = d, then: #}
{# 12. If i = d, then: #}
case {{length}}:
{# Then resolve by testing argument #}
{% for test, method in tests_methods %}
{% if method.visible %}
{% filter runtime_enabled(not overloads.runtime_enabled_all and method.runtime_enabled_feature_name) %}
if ({{test}}) {
{% if method.measure_as and not overloads.measure_all_as %}
UseCounter::Count(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{method.measure_as('Method')}});
{% endif %}
{% if method.deprecate_as and not overloads.deprecate_all_as %}
Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{method.deprecate_as}});
{% endif %}
{{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
return;
{% if "exceptionState" in test %}
{
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext,
"{{interface_name}}", "{{overloads.name}}");
{{ test_and_call_overloaded_method(test, method, overloads, world_suffix) | trim | indent(8) }}
if (exceptionState.HadException()) {
exceptionState.RethrowV8Exception(exceptionState.GetException());
return;
}
}
{% else %}{# exceptionState #}
{{ test_and_call_overloaded_method(test, method, overloads, world_suffix) | trim | indent(6) }}
{% endif %}{# exceptionState #}
{% endfilter %}
{% endif %}
{% endfor %}
......@@ -407,23 +413,19 @@ static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
{% endfor %}{# length, tests_methods #}
{% if not fall_through_to_partial_overloads %}
default:
{# 4. If S is empty, then throw a TypeError. #}
{# 12.19. Otherwise: throw a TypeError. #}
isArityError = true;
{% endif %}
}
{% if fall_through_to_partial_overloads %}
DCHECK({{overloads.name}}MethodForPartialInterface);
({{overloads.name}}MethodForPartialInterface)(info);
{% else %}{# fall_through_to_partial_overloads #}
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "{{interface_name}}", "{{overloads.name}}");
{% if overloads.returns_promise_all %}
ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState);
{% endif %}
if (isArityError) {
{% if overloads.length != 0 %}
if (info.Length() < {{overloads.length}}) {
......@@ -439,11 +441,23 @@ static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
{% endif %}
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
{% endif %}{# fall_through_to_partial_overloads #}
}
{% endmacro %}
{% macro test_and_call_overloaded_method(test, method, overloads, world_suffix) %}
if ({{test}}) {
{% if method.measure_as and not overloads.measure_all_as %}
UseCounter::Count(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{method.measure_as('Method')}});
{% endif %}
{% if method.deprecate_as and not overloads.deprecate_all_as %}
Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{method.deprecate_as}});
{% endif %}
{{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
return;
}
{% endmacro %}
{##############################################################################}
{% macro generate_post_message_impl(method) %}
......
......@@ -1695,6 +1695,7 @@ static void overloadMethodWithExposedAndRuntimeEnabledFlag3Method(const v8::Func
static void overloadMethodWithExposedAndRuntimeEnabledFlagMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 1:
if (RuntimeEnabledFeatures::FeatureName2Enabled()) {
......@@ -1723,7 +1724,6 @@ static void overloadMethodWithExposedAndRuntimeEnabledFlagMethod(const v8::Funct
}
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterface", "overloadMethodWithExposedAndRuntimeEnabledFlag");
if (isArityError) {
if (info.Length() < 1) {
exceptionState.ThrowTypeError(ExceptionMessages::NotEnoughArguments(1, info.Length()));
......
......@@ -185,6 +185,14 @@ static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info) {
TestInterfaceConstructor2V8Internal::constructor3(info);
return;
}
if (HasCallableIteratorSymbol(info.GetIsolate(), info[0], exceptionState)) {
TestInterfaceConstructor2V8Internal::constructor3(info);
return;
}
if (exceptionState.HadException()) {
exceptionState.RethrowV8Exception(exceptionState.GetException());
return;
}
if (info[0]->IsObject()) {
TestInterfaceConstructor2V8Internal::constructor2(info);
return;
......
......@@ -192,6 +192,7 @@ static void voidMethodPartialOverload2Method(const v8::FunctionCallbackInfo<v8::
static void voidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 0:
if (true) {
......@@ -210,7 +211,6 @@ static void voidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::V
}
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterfaceOriginTrialEnabled", "voidMethodPartialOverload");
if (isArityError) {
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
......
......@@ -95,6 +95,7 @@ static void voidMethodPartialOverload3Method(const v8::FunctionCallbackInfo<v8::
static void voidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 0:
break;
......@@ -109,7 +110,6 @@ static void voidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::V
}
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterface", "voidMethodPartialOverload");
if (isArityError) {
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
......@@ -126,6 +126,7 @@ static void staticVoidMethodPartialOverload2Method(const v8::FunctionCallbackInf
static void staticVoidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 0:
break;
......@@ -140,7 +141,6 @@ static void staticVoidMethodPartialOverloadMethod(const v8::FunctionCallbackInfo
}
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterface", "staticVoidMethodPartialOverload");
if (isArityError) {
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
......@@ -170,6 +170,7 @@ static void promiseMethodPartialOverload3Method(const v8::FunctionCallbackInfo<v
static void promiseMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 0:
break;
......@@ -185,7 +186,6 @@ static void promiseMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterface", "promiseMethodPartialOverload");
ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState);
if (isArityError) {
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
......@@ -205,6 +205,7 @@ static void staticPromiseMethodPartialOverload2Method(const v8::FunctionCallback
static void staticPromiseMethodPartialOverloadMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 0:
break;
......@@ -220,7 +221,6 @@ static void staticPromiseMethodPartialOverloadMethod(const v8::FunctionCallbackI
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterface", "staticPromiseMethodPartialOverload");
ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState);
if (isArityError) {
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
......@@ -252,6 +252,7 @@ static void partial2VoidMethod3Method(const v8::FunctionCallbackInfo<v8::Value>&
static void partial2VoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 0:
break;
......@@ -270,7 +271,6 @@ static void partial2VoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>&
}
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterface", "partial2VoidMethod");
if (isArityError) {
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
......@@ -312,6 +312,7 @@ static void partial2StaticVoidMethod2Method(const v8::FunctionCallbackInfo<v8::V
static void partial2StaticVoidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info) {
bool isArityError = false;
switch (std::min(1, info.Length())) {
case 0:
break;
......@@ -326,7 +327,6 @@ static void partial2StaticVoidMethodMethod(const v8::FunctionCallbackInfo<v8::Va
}
ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kExecutionContext, "TestInterface", "partial2StaticVoidMethod");
if (isArityError) {
}
exceptionState.ThrowTypeError("No function was found that matched the signature provided.");
......
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