| Index: Source/bindings/templates/methods.cpp
|
| diff --git a/Source/bindings/templates/methods.cpp b/Source/bindings/templates/methods.cpp
|
| index d0410ba52948db887ff030ea4544ce7ac32e54aa..373ef448bb56654d2512d6ba4cfcae65e818a8ca 100644
|
| --- a/Source/bindings/templates/methods.cpp
|
| +++ b/Source/bindings/templates/methods.cpp
|
| @@ -12,7 +12,9 @@ static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const
|
| {% else %}
|
| {% if method.number_of_required_arguments %}
|
| if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
|
| - throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", ExceptionMessages::notEnoughArguments({{method.number_of_required_arguments}}, info.Length())), info.GetIsolate());
|
| + {{throw_type_error(method,
|
| + 'ExceptionMessages::notEnoughArguments(%s, info.Length())' %
|
| + method.number_of_required_arguments)}}
|
| return;
|
| }
|
| {% endif %}
|
| @@ -73,50 +75,7 @@ if (listener) {
|
|
|
|
|
| {######################################}
|
| -{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
|
| -{% if method.is_call_with_script_state %}
|
| -ScriptState* currentState = ScriptState::current();
|
| -if (!currentState)
|
| - return;
|
| -ScriptState& state = *currentState;
|
| -{% endif %}
|
| -{% if method.is_call_with_execution_context %}
|
| -ExecutionContext* scriptContext = getExecutionContext();
|
| -{% endif %}
|
| -{% if method.is_call_with_script_arguments %}
|
| -RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.number_of_arguments}}));
|
| -{% endif %}
|
| -{% if method.idl_type == 'void' %}
|
| -{{cpp_value}};
|
| -{% elif method.is_call_with_script_state %}
|
| -{# FIXME: consider always using a local variable #}
|
| -{{method.cpp_type}} result = {{cpp_value}};
|
| -{% endif %}
|
| -{% if method.is_raises_exception %}
|
| -if (exceptionState.throwIfNeeded())
|
| - return;
|
| -{% endif %}
|
| -{% if method.is_call_with_script_state %}
|
| -if (state.hadException()) {
|
| - v8::Local<v8::Value> exception = state.exception();
|
| - state.clearException();
|
| - throwError(exception, info.GetIsolate());
|
| - return;
|
| -}
|
| -{% endif %}
|
| -{% if v8_set_return_value %}{{v8_set_return_value}};{% endif %}{# None for void #}
|
| -{% endmacro %}
|
| -
|
| -
|
| -{######################################}
|
| {% macro generate_argument(method, argument) %}
|
| -{% macro throw_type_error(error_message) %}
|
| -{% if method.is_constructor %}
|
| -throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", "{{error_message}}"), info.GetIsolate());
|
| -{%- else %}
|
| -throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", "{{error_message}}"), info.GetIsolate());
|
| -{%- endif %}
|
| -{% endmacro %}
|
| {% if argument.is_optional and not argument.has_default and
|
| argument.idl_type != 'Dictionary' %}
|
| {# Optional arguments without a default value generate an early call with
|
| @@ -131,8 +90,8 @@ if (UNLIKELY(info.Length() <= {{argument.index}})) {
|
| {# Type checking for wrapper interface types (if interface not implemented,
|
| throw TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
|
| if (info.Length() > {{argument.index}} && !isUndefinedOrNull(info[{{argument.index}}]) && !V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate(), worldType(info.GetIsolate()))) {
|
| - {{throw_type_error("parameter %s is not of type '%s'." %
|
| - (argument.index + 1, argument.idl_type))}}
|
| + {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
|
| + (argument.index + 1, argument.idl_type))}}
|
| return;
|
| }
|
| {% endif %}
|
| @@ -145,16 +104,17 @@ if (!std::isnan({{argument.name}}NativeValue))
|
| IDL integer types have same internal C++ type (int or unsigned) #}
|
| {{argument.name}} = clampTo<{{argument.idl_type}}>({{argument.name}}NativeValue);
|
| {% elif argument.idl_type == 'SerializedScriptValue' %}
|
| -bool {{argument.name}}DidThrow = false;
|
| -{{argument.cpp_type}} {{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, {{argument.name}}DidThrow, info.GetIsolate());
|
| -if ({{argument.name}}DidThrow)
|
| +{% set did_throw = argument.name + 'DidThrow' %}
|
| +bool {{did_throw}} = false;
|
| +{{argument.cpp_type}} {{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, {{did_throw}}, info.GetIsolate());
|
| +if ({{did_throw}})
|
| return;
|
| {% elif argument.is_variadic_wrapper_type %}
|
| Vector<{{argument.cpp_type}} > {{argument.name}};
|
| for (int i = {{argument.index}}; i < info.Length(); ++i) {
|
| if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate(), worldType(info.GetIsolate()))) {
|
| - {{throw_type_error("parameter %s is not of type '%s'." %
|
| - (argument.index + 1, argument.idl_type))}}
|
| + {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
|
| + (argument.index + 1, argument.idl_type))}}
|
| return;
|
| }
|
| {{argument.name}}.append(V8{{argument.idl_type}}::toNative(v8::Handle<v8::Object>::Cast(info[i])));
|
| @@ -166,20 +126,68 @@ for (int i = {{argument.index}}; i < info.Length(); ++i) {
|
| {# Methods throw on invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
|
| String string = {{argument.name}};
|
| if (!({{argument.enum_validation_expression}})) {
|
| - {{throw_type_error("parameter %s ('\" + string + \"') is not a valid enum value." % (argument.index + 1))}}
|
| + {{throw_type_error(method,
|
| + '"parameter %s (\'" + string + "\') is not a valid enum value."' %
|
| + (argument.index + 1))}}
|
| return;
|
| }
|
| {% endif %}
|
| {% if argument.idl_type in ['Dictionary', 'Promise'] %}
|
| if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
|
| - {{throw_type_error("parameter %s ('%s') is not an object." %
|
| - (argument.index + 1, argument.name))}}
|
| + {{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
|
| + (argument.index + 1, argument.name))}}
|
| return;
|
| }
|
| {% endif %}
|
| {% endmacro %}
|
|
|
|
|
| +{######################################}
|
| +{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
|
| +{% if method.is_call_with_script_state %}
|
| +ScriptState* currentState = ScriptState::current();
|
| +if (!currentState)
|
| + return;
|
| +ScriptState& state = *currentState;
|
| +{% endif %}
|
| +{% if method.is_call_with_execution_context %}
|
| +ExecutionContext* scriptContext = getExecutionContext();
|
| +{% endif %}
|
| +{% if method.is_call_with_script_arguments %}
|
| +RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.number_of_arguments}}));
|
| +{% endif %}
|
| +{% if method.idl_type == 'void' %}
|
| +{{cpp_value}};
|
| +{% elif method.is_call_with_script_state %}
|
| +{# FIXME: consider always using a local variable #}
|
| +{{method.cpp_type}} result = {{cpp_value}};
|
| +{% endif %}
|
| +{% if method.is_raises_exception %}
|
| +if (exceptionState.throwIfNeeded())
|
| + return;
|
| +{% endif %}
|
| +{% if method.is_call_with_script_state %}
|
| +if (state.hadException()) {
|
| + v8::Local<v8::Value> exception = state.exception();
|
| + state.clearException();
|
| + throwError(exception, info.GetIsolate());
|
| + return;
|
| +}
|
| +{% endif %}
|
| +{% if v8_set_return_value %}{{v8_set_return_value}};{% endif %}{# None for void #}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{######################################}
|
| +{% macro throw_type_error(method, error_message) %}
|
| +{% if method.is_constructor %}
|
| +throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}}), info.GetIsolate());
|
| +{%- else %}
|
| +throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}}), info.GetIsolate());
|
| +{%- endif %}
|
| +{% endmacro %}
|
| +
|
| +
|
| {##############################################################################}
|
| {% macro overload_resolution_method(overloads, world_suffix) %}
|
| static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
|
| @@ -200,7 +208,7 @@ static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
|
| exceptionState.throwTypeError("No function was found that matched the signature provided.");
|
| exceptionState.throwIfNeeded();
|
| {% else %}
|
| - throwTypeError(ExceptionMessages::failedToExecute("{{overloads.name}}", "{{interface_name}}", "No function was found that matched the signature provided."), info.GetIsolate());
|
| + {{throw_type_error(overloads, '"No function was found that matched the signature provided."')}}
|
| {% endif %}
|
| }
|
| {% endmacro %}
|
| @@ -281,3 +289,43 @@ static void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Lo
|
| TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
|
| }
|
| {% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro constructor_callback(constructor) %}
|
| +static void constructor{{constructor.overload_index}}(const v8::FunctionCallbackInfo<v8::Value>& info)
|
| +{
|
| + {% if interface_length and not constructor.overload_index %}
|
| + {# FIXME: remove this UNLIKELY: constructors are heavy, so no difference. #}
|
| + if (UNLIKELY(info.Length() < {{interface_length}})) {
|
| + {{throw_type_error({'name': 'Constructor'},
|
| + 'ExceptionMessages::notEnoughArguments(%s, info.Length())' %
|
| + interface_length)}}
|
| + return;
|
| + }
|
| + {% endif %}
|
| + {% if is_constructor_raises_exception %}
|
| + ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
|
| + {% endif %}
|
| + {% for argument in constructor.arguments %}
|
| + {{generate_argument(constructor, argument) | indent}}
|
| + {% endfor %}
|
| + {% if is_constructor_call_with_execution_context %}
|
| + ExecutionContext* context = getExecutionContext();
|
| + {% endif %}
|
| + {% if is_constructor_call_with_document %}
|
| + Document& document = *toDocument(getExecutionContext());
|
| + {% endif %}
|
| + RefPtr<{{cpp_class}}> impl = {{cpp_class}}::create({{constructor.argument_list | join(', ')}});
|
| + v8::Handle<v8::Object> wrapper = info.Holder();
|
| + {% if is_constructor_raises_exception %}
|
| + if (exceptionState.throwIfNeeded())
|
| + return;
|
| + {% endif %}
|
| +
|
| + {# FIXME: Should probably be Independent unless [ActiveDOMObject]
|
| + or [DependentLifetime]. #}
|
| + V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl.release(), &{{v8_class}}::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
|
| + v8SetReturnValue(info, wrapper);
|
| +}
|
| +{% endmacro %}
|
|
|