Commit f86a4b77 authored by jl@opera.com's avatar jl@opera.com

Generate missing "block.ReThrow();" before return

After r174546 a v8::TryCatch object is in scope when calling a method's
C++ implementation early due to missing optional arguments.  If the
implementation throws an exception, we need to call ReThrow() on that
v8::TryCatch object for the exception to be propagated correctly.

BUG=362388

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

git-svn-id: svn://svn.chromium.org/blink/trunk@175076 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 283fdd35
...@@ -25,7 +25,7 @@ static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const ...@@ -25,7 +25,7 @@ static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const
{% if interface_name == 'EventTarget' %} {% if interface_name == 'EventTarget' %}
if (DOMWindow* window = impl->toDOMWindow()) { if (DOMWindow* window = impl->toDOMWindow()) {
if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), window->frame(), exceptionState)) { if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), window->frame(), exceptionState)) {
{{throw_from_exception_state(method)}}; {{throw_from_exception_state(method) | indent(12)}}
return; return;
} }
if (!window->document()) if (!window->document())
...@@ -33,14 +33,14 @@ static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const ...@@ -33,14 +33,14 @@ static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const
} }
{% elif method.is_check_security_for_frame %} {% elif method.is_check_security_for_frame %}
if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) { if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
{{throw_from_exception_state(method)}}; {{throw_from_exception_state(method) | indent(8)}}
return; return;
} }
{% endif %} {% endif %}
{% if method.is_check_security_for_node %} {% if method.is_check_security_for_node %}
if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->{{method.name}}(exceptionState), exceptionState)) { if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->{{method.name}}(exceptionState), exceptionState)) {
v8SetReturnValueNull(info); v8SetReturnValueNull(info);
{{throw_from_exception_state(method)}}; {{throw_from_exception_state(method) | indent(8)}}
return; return;
} }
{% endif %} {% endif %}
...@@ -117,9 +117,9 @@ OwnPtr<{{argument.idl_type}}> {{argument.name}} ...@@ -117,9 +117,9 @@ OwnPtr<{{argument.idl_type}}> {{argument.name}}
Optional Dictionary arguments default to empty dictionary. #} Optional Dictionary arguments default to empty dictionary. #}
if (UNLIKELY(info.Length() <= {{argument.index}})) { if (UNLIKELY(info.Length() <= {{argument.index}})) {
{% if world_suffix %} {% if world_suffix %}
{{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argument.cpp_value) | indent}} {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argument.cpp_value, method.arguments_need_try_catch) | indent}}
{% else %} {% else %}
{{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | indent}} {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value, method.arguments_need_try_catch) | indent}}
{% endif %} {% endif %}
{% if argument.has_event_listener_argument %} {% if argument.has_event_listener_argument %}
{{hidden_dependency_action(method.name) | indent}} {{hidden_dependency_action(method.name) | indent}}
...@@ -178,7 +178,7 @@ if (!std::isnan({{argument.name}}NativeValue)) ...@@ -178,7 +178,7 @@ if (!std::isnan({{argument.name}}NativeValue))
{% elif argument.idl_type == 'SerializedScriptValue' %} {% elif argument.idl_type == 'SerializedScriptValue' %}
{{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, exceptionState, info.GetIsolate()); {{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, exceptionState, info.GetIsolate());
if (exceptionState.hadException()) { if (exceptionState.hadException()) {
{{throw_from_exception_state(method)}}; {{throw_from_exception_state(method) | indent}}
return; return;
} }
{% elif argument.is_variadic_wrapper_type %} {% elif argument.is_variadic_wrapper_type %}
...@@ -228,7 +228,7 @@ if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) { ...@@ -228,7 +228,7 @@ if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
{######################################} {######################################}
{% macro cpp_method_call(method, v8_set_return_value, cpp_value) %} {% macro cpp_method_call(method, v8_set_return_value, cpp_value, has_try_catch) %}
{# Local variables #} {# Local variables #}
{% if method.is_call_with_script_state %} {% if method.is_call_with_script_state %}
ScriptState* scriptState = ScriptState::current(info.GetIsolate()); ScriptState* scriptState = ScriptState::current(info.GetIsolate());
...@@ -251,7 +251,7 @@ RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.num ...@@ -251,7 +251,7 @@ RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.num
{# Post-call #} {# Post-call #}
{% if method.is_raises_exception %} {% if method.is_raises_exception %}
if (exceptionState.hadException()) { if (exceptionState.hadException()) {
{{throw_from_exception_state(method)}}; {{throw_from_exception_state(method, has_try_catch) | indent}}
return; return;
} }
{% endif %} {% endif %}
...@@ -289,22 +289,27 @@ v8SetReturnValueNull(info); ...@@ -289,22 +289,27 @@ v8SetReturnValueNull(info);
{% macro throw_type_error(method, error_message) %} {% macro throw_type_error(method, error_message) %}
{% if method.has_exception_state %} {% if method.has_exception_state %}
exceptionState.throwTypeError({{error_message}}); exceptionState.throwTypeError({{error_message}});
{{throw_from_exception_state(method)}}; {{throw_from_exception_state(method, method.arguments_need_try_catch)}}
{% elif method.is_constructor %} {%- else %}{# method.has_exception_state #}
{% if method.is_constructor %}
throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}}), info.GetIsolate()); throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}}), info.GetIsolate());
{% else %}{# method.has_exception_state #} {% else %}{# method.has_exception_state #}
throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}}), info.GetIsolate()); throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}}), info.GetIsolate());
{% endif %} {% endif %}
{% if method.arguments_need_try_catch %} {% if method.arguments_need_try_catch %}
block.ReThrow(); block.ReThrow();
{%- endif %}{# method.has_exception_state #} {% endif %}
{% endif %}{# method.has_exception_state #}
{% endmacro %} {% endmacro %}
{######################################} {######################################}
{# FIXME: return a rejected Promise if method.idl_type == 'Promise' #} {# FIXME: return a rejected Promise if method.idl_type == 'Promise' #}
{% macro throw_from_exception_state(method) %} {% macro throw_from_exception_state(method, has_try_catch) %}
exceptionState.throwIfNeeded() exceptionState.throwIfNeeded();
{% if has_try_catch %}
block.ReThrow();
{%- endif %}
{%- endmacro %} {%- endmacro %}
......
...@@ -8432,6 +8432,7 @@ static void raisesExceptionVoidMethodOptionalLongArgMethod(const v8::FunctionCal ...@@ -8432,6 +8432,7 @@ static void raisesExceptionVoidMethodOptionalLongArgMethod(const v8::FunctionCal
impl->raisesExceptionVoidMethodOptionalLongArg(exceptionState); impl->raisesExceptionVoidMethodOptionalLongArg(exceptionState);
if (exceptionState.hadException()) { if (exceptionState.hadException()) {
exceptionState.throwIfNeeded(); exceptionState.throwIfNeeded();
block.ReThrow();
return; return;
} }
return; return;
......
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