Chromium Code Reviews| 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) %} |