Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Unified Diff: third_party/WebKit/Source/bindings/templates/methods.cpp

Issue 2301993002: binding: Introduces ExceptionToPromiseScope. (Closed)
Patch Set: . Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/bindings/templates/methods.cpp
diff --git a/third_party/WebKit/Source/bindings/templates/methods.cpp b/third_party/WebKit/Source/bindings/templates/methods.cpp
index ec510b906fc7784d030228c0fe858b20a12588a8..fd4d6d82f65b3fb628cce79bceef2f6aaaa6f3bf 100644
--- a/third_party/WebKit/Source/bindings/templates/methods.cpp
+++ b/third_party/WebKit/Source/bindings/templates/methods.cpp
@@ -2,28 +2,40 @@
{##############################################################################}
{% macro generate_method(method, world_suffix) %}
-{% if method.returns_promise and method.has_exception_state %}
-static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}Promise(const v8::FunctionCallbackInfo<v8::Value>& info, ExceptionState& exceptionState)
-{% else %}
static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
-{% endif %}
+{% filter format_remove_duplicates([
+ 'ScriptState* scriptState = ']) %}
haraken 2016/09/02 16:24:13 Honestly speaking, I'm neutral about this formatte
Yuki 2016/09/05 07:19:25 I'm not sure what is the best way, but we definite
haraken 2016/09/05 08:24:22 I won't object if you strongly want to do this, bu
{
{# Local variables #}
- {% if method.has_exception_state and not method.returns_promise %}
- ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% if method.has_exception_state %}
+ ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "{{interface_name}}", "{{method.name}}");
+ {% if method.returns_promise %}
+ {% if method.is_static %}
+ ScriptState* scriptState = ScriptState::forFunctionObject(info);
+ {% else %}
+ ScriptState* scriptState = ScriptState::forReceiverObject(info);
+ {% endif %}
+ ExceptionToPromiseScope exceptionToPromiseScope(info, scriptState, exceptionState);
{% endif %}
+ {% endif %}
+
{# Overloaded methods have length checked during overload resolution #}
- {% if method.number_of_required_arguments and not method.overload_index %}
+ {% if method.number_of_required_arguments and
+ not method.overload_index %}
if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
- {{throw_minimum_arity_type_error(method, method.number_of_required_arguments) | indent(8)}}
+ {{throw_minimum_arity_error(method, method.number_of_required_arguments)}}
+ return;
}
{% endif %}
+
{% if not method.is_static %}
{{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
{% endif %}
+
{% if method.is_custom_element_callbacks %}
V0CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
{% endif %}
+
{# Security checks #}
{% if method.is_check_security_for_receiver %}
{% if interface_name == 'EventTarget' %}
@@ -48,7 +60,16 @@ static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const
return;
}
{% endif %}
+
{# Call method #}
+ {% if method.is_call_with_script_state or
+ method.is_call_with_this_value %}
+ {% if method.is_static %}
+ ScriptState* scriptState = ScriptState::forFunctionObject(info);
+ {% else %}
+ ScriptState* scriptState = ScriptState::forReceiverObject(info);
+ {% endif %}
+ {% endif %}
{% if method.arguments %}
{{generate_arguments(method, world_suffix) | indent}}
{% endif %}
@@ -58,16 +79,7 @@ static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const
{{cpp_method_call(method, method.v8_set_return_value, method.cpp_value) | indent}}
{% endif %}
}
-{% if method.returns_promise and method.has_exception_state %}
-
-static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
-{
- ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
- {{method.name}}{{method.overload_index}}Method{{world_suffix}}Promise(info, exceptionState);
- if (exceptionState.hadException())
- v8SetReturnValue(info, exceptionState.reject(ScriptState::current(info.GetIsolate())).v8Value());
-}
-{% endif %}
+{% endfilter %}
{% endmacro %}
@@ -137,7 +149,8 @@ if (!isUndefinedOrNull(info[{{argument.index}}])) {
if (!info[{{argument.index}}]->IsFunction()) {
{{throw_type_error(method,
'"The callback provided as parameter %s is not a function."' %
- (argument.index + 1)) | indent(8)}}
+ (argument.index + 1))}}
+ return;
}
{{argument.name}} = V8{{argument.idl_type}}::create(v8::Local<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
} else {
@@ -147,7 +160,8 @@ if (!isUndefinedOrNull(info[{{argument.index}}])) {
if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{{argument.index}}]->IsFunction() || info[{{argument.index}}]->IsNull()){% else %}info[{{argument.index}}]->IsFunction(){% endif %}) {
{{throw_type_error(method,
'"The callback provided as parameter %s is not a function."' %
- (argument.index + 1)) | indent}}
+ (argument.index + 1))}}
+ return;
}
{{argument.name}} = {% if argument.is_nullable %}info[{{argument.index}}]->IsNull() ? nullptr : {% endif %}V8{{argument.idl_type}}::create(v8::Local<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
{% endif %}{# argument.is_optional #}
@@ -156,14 +170,16 @@ if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{
if (!info[{{argument.index}}]->IsFunction(){% if argument.is_nullable %} && !info[{{argument.index}}]->IsNull(){% endif %}) {
{{throw_type_error(method,
'"The callback provided as parameter %s is not a function."' %
- (argument.index + 1)) | indent}}
+ (argument.index + 1))}}
+ return;
}
{{v8_value_to_local_cpp_value(argument)}}
{% elif argument.is_variadic_wrapper_type %}
for (int i = {{argument.index}}; i < info.Length(); ++i) {
if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate())) {
{{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
- (argument.index + 1, argument.idl_type)) | indent(8)}}
+ (argument.index + 1, argument.idl_type))}}
+ return;
}
{{argument.name}}.append(V8{{argument.idl_type}}::toImpl(v8::Local<v8::Object>::Cast(info[i])));
}
@@ -173,7 +189,8 @@ for (int i = {{argument.index}}; i < info.Length(); ++i) {
http://heycam.github.io/webidl/#es-dictionary #}
if (!isUndefinedOrNull(info[{{argument.index}}]) && !info[{{argument.index}}]->IsObject()) {
{{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
- (argument.index + 1, argument.name)) | indent}}
+ (argument.index + 1, argument.name))}}
+ return;
}
{% endif %}{# not argument.use_permissive_dictionary_conversion #}
{{v8_value_to_local_cpp_value(argument)}}
@@ -193,7 +210,8 @@ if (!isUndefinedOrNull(info[{{argument.index}}])) {
argument instead; see argument.is_variadic_wrapper_type code-path above. #}
if (!{{argument.name}}{% if argument.is_nullable %} && !isUndefinedOrNull(info[{{argument.index}}]){% endif %}) {
{{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
- (argument.index + 1, argument.idl_type)) | indent}}
+ (argument.index + 1, argument.idl_type))}}
+ return;
}
{% elif argument.enum_values %}
{# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
@@ -206,7 +224,8 @@ if (!isValidEnum({{argument.name}}, validValues, WTF_ARRAY_LENGTH(validValues),
http://heycam.github.io/webidl/#es-promise #}
if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
{{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
- (argument.index + 1, argument.name)) | indent}}
+ (argument.index + 1, argument.name))}}
+ return;
}
{% endif %}
{% endmacro %}
@@ -218,15 +237,6 @@ if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
{{v8_class}}::{{method.name}}MethodPrologueCustom(info, impl);
{% endif %}
{# Local variables #}
-{% if method.is_call_with_script_state or method.is_call_with_this_value %}
-{# [ConstructorCallWith=ScriptState] #}
-{# [CallWith=ScriptState] #}
-{% if method.is_static %}
-ScriptState* scriptState = ScriptState::forFunctionObject(info);
-{% else %}
-ScriptState* scriptState = ScriptState::forReceiverObject(info);
-{% endif %}
-{% endif %}
{% if method.is_call_with_execution_context %}
{# [ConstructorCallWith=ExecutionContext] #}
{# [CallWith=ExecutionContext] #}
@@ -258,7 +268,7 @@ if (!{{method.cpp_value}})
{# Post-call #}
{% if method.is_raises_exception %}
if (exceptionState.hadException()) {
- {{propagate_error_with_exception_state(method) | indent}}
+ return;
}
{% endif %}
{# Set return value #}
@@ -289,60 +299,24 @@ else
{% macro throw_type_error(method, error_message) %}
{% if method.has_exception_state %}
exceptionState.throwTypeError({{error_message}});
-{{propagate_error_with_exception_state(method)}}
-{% elif method.idl_type == 'Promise' %}
-v8SetReturnValue(info, ScriptPromise::rejectRaw(ScriptState::current(info.GetIsolate()), V8ThrowException::createTypeError(info.GetIsolate(), {{type_error_message(method, error_message)}})));
-return;
-{% else %}
-V8ThrowException::throwTypeError(info.GetIsolate(), {{type_error_message(method, error_message)}});
-return;
-{% endif %}{# method.has_exception_state #}
-{% endmacro %}
-
-
-{######################################}
-{% macro type_error_message(method, error_message) %}
-{% if method.is_constructor %}
-ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}})
+{%- elif method.is_constructor %}
+V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}}));
{%- else %}
-ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}})
+V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}}));
{%- endif %}
-{%- endmacro %}
-
-
-{######################################}
-{% macro propagate_error_with_exception_state(method_or_overloads) %}
-{% if method_or_overloads.returns_promise_all or
- method_or_overloads.returns_promise %}
-v8SetReturnValue(info, exceptionState.reject(ScriptState::current(info.GetIsolate())).v8Value());
-{% endif %}
-return;
-{%- endmacro %}
+{% endmacro %}
{######################################}
-{% macro throw_minimum_arity_type_error(method, number_of_required_arguments) %}
+{% macro throw_minimum_arity_error(method, number_of_required_arguments) %}
{% if method.has_exception_state %}
-setMinimumArityTypeError(exceptionState, {{number_of_required_arguments}}, info.Length());
-{{propagate_error_with_exception_state(method)}}
-{%- elif method.idl_type == 'Promise' %}
-v8SetReturnValue(info, ScriptPromise::rejectRaw(ScriptState::current(info.GetIsolate()), {{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}}));
-return;
+throwMinimumArityError(exceptionState, {{number_of_required_arguments}}, info.Length());
+{%- elif method.is_constructor %}
+throwMinimumArityErrorForConstructor(info.GetIsolate(), "{{interface_name}}", {{number_of_required_arguments}}, info.Length());
{%- else %}
-V8ThrowException::throwException(info.GetIsolate(), {{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}});
-return;
+throwMinimumArityErrorForMethod(info.GetIsolate(), "{{interface_name}}", "{{method.name}}", {{number_of_required_arguments}}, info.Length());
{%- endif %}
-{%- endmacro %}
-
-
-{######################################}
-{% macro create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments) %}
-{% if method.is_constructor %}
-createMinimumArityTypeErrorForConstructor(info.GetIsolate(), "{{interface_name}}", {{number_of_required_arguments}}, info.Length())
-{%- else %}
-createMinimumArityTypeErrorForMethod(info.GetIsolate(), "{{method.name}}", "{{interface_name}}", {{number_of_required_arguments}}, info.Length())
-{%- endif %}
-{%- endmacro %}
+{% endmacro %}
{##############################################################################}
@@ -426,8 +400,8 @@ static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
{# Report full list of valid arities if gaps and above minimum #}
{% if overloads.valid_arities %}
if (info.Length() >= {{overloads.length}}) {
- setArityTypeError(exceptionState, "{{overloads.valid_arities}}", info.Length());
- {{propagate_error_with_exception_state(overloads) | indent(12)}}
+ throwInvalidArityError(exceptionState, "{{overloads.valid_arities}}", info.Length());
+ return;
}
{% endif %}
break;
@@ -441,24 +415,23 @@ static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
if (info.Length() < {{overloads.length}}) {
{# Otherwise just report "not enough arguments" #}
exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{overloads.length}}, info.Length()));
- {{propagate_error_with_exception_state(overloads) | indent(8)}}
+ return;
}
{% endif %}
{# No match, throw error #}
exceptionState.throwTypeError("No function was found that matched the signature provided.");
- {{propagate_error_with_exception_state(overloads) | indent}}
{% endif %}
}
{% endmacro %}
{##############################################################################}
-{% macro generate_post_message_impl() %}
+{% macro generate_post_message_impl(method) %}
void postMessageImpl(const char* interfaceName, {{cpp_class}}* instance, const v8::FunctionCallbackInfo<v8::Value>& info)
{
ExceptionState exceptionState(ExceptionState::ExecutionContext, "postMessage", interfaceName, info.Holder(), info.GetIsolate());
- if (UNLIKELY(info.Length() < 1)) {
- setMinimumArityTypeError(exceptionState, 1, info.Length());
+ if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
+ {{throw_minimum_arity_error(method, method.number_of_required_arguments)}}
return;
}
Transferables transferables;
@@ -477,6 +450,7 @@ void postMessageImpl(const char* interfaceName, {{cpp_class}}* instance, const v
}
{% endmacro %}
+
{##############################################################################}
{% macro method_callback(method, world_suffix) %}
static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
@@ -616,9 +590,14 @@ static void {{name}}(const v8::FunctionCallbackInfo<v8::Value>& info)
{# Overloaded constructors have length checked during overload resolution #}
{% if constructor.number_of_required_arguments and not constructor.overload_index %}
if (UNLIKELY(info.Length() < {{constructor.number_of_required_arguments}})) {
- {{throw_minimum_arity_type_error(constructor, constructor.number_of_required_arguments) | indent(8)}}
+ {{throw_minimum_arity_error(constructor, constructor.number_of_required_arguments)}}
+ return;
}
{% endif %}
+ {% if constructor.is_call_with_script_state or
+ constructor.is_call_with_this_value %}
+ ScriptState* scriptState = ScriptState::forReceiverObject(info);
+ {% endif %}
{% if constructor.arguments %}
{{generate_arguments(constructor) | indent}}
{% endif %}
@@ -660,6 +639,7 @@ const V8DOMConfiguration::MethodConfiguration {{method.name}}MethodConfiguration
V8DOMConfiguration::installMethod(isolate, world, {{instance_template}}, {{prototype_template}}, {{interface_template}}, {{signature}}, {{method.name}}MethodConfiguration);
{%- endmacro %}
+
{######################################}
{% macro install_conditionally_enabled_methods() %}
{% if methods | conditionally_exposed(is_partial) %}

Powered by Google App Engine
This is Rietveld 408576698