[turbofan] Unify error message on non-callable callback.

R=mvstanton@chromium.org
BUG=chromium:770581
TEST=mjsunit/regress/regress-crbug-770581

Change-Id: I3a5854b6534e67da3e28d9c713830808013675b5
Reviewed-on: https://chromium-review.googlesource.com/702378
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48375}
This commit is contained in:
Michael Starzinger 2017-10-05 15:16:08 +02:00 committed by Commit Bot
parent 2e70adc7e2
commit bb46a592d0
2 changed files with 32 additions and 8 deletions

View File

@ -672,7 +672,8 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY);
Node* check_throw = check_fail = graph()->NewNode(
javascript()->CallRuntime(Runtime::kThrowCalledNonCallable), fncallback,
javascript()->CallRuntime(Runtime::kThrowTypeError, 2),
jsgraph()->Constant(MessageTemplate::kCalledNonCallable), fncallback,
context, check_frame_state, effect, check_fail);
control = graph()->NewNode(common()->IfTrue(), check_branch);
@ -799,9 +800,9 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
control = if_false;
effect = eloop;
// The above %ThrowCalledNonCallable runtime call is an unconditional
// throw, making it impossible to return a successful completion in this
// case. We simply connect the successful completion to the graph end.
// The above %ThrowTypeError runtime call is an unconditional throw, making
// it impossible to return a successful completion in this case. We simply
// connect the successful completion to the graph end.
Node* terminate =
graph()->NewNode(common()->Throw(), check_throw, check_fail);
NodeProperties::MergeControlToEnd(graph(), common(), terminate);
@ -902,7 +903,8 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function,
node->InputAt(0), context, &checkpoint_params[0], stack_parameters,
outer_frame_state, ContinuationFrameStateMode::LAZY);
Node* check_throw = check_fail = graph()->NewNode(
javascript()->CallRuntime(Runtime::kThrowCalledNonCallable), fncallback,
javascript()->CallRuntime(Runtime::kThrowTypeError, 2),
jsgraph()->Constant(MessageTemplate::kCalledNonCallable), fncallback,
context, check_frame_state, effect, check_fail);
control = graph()->NewNode(common()->IfTrue(), check_branch);
@ -1011,9 +1013,9 @@ Reduction JSCallReducer::ReduceArrayMap(Handle<JSFunction> function,
control = if_false;
effect = eloop;
// The above %ThrowCalledNonCallable runtime call is an unconditional
// throw, making it impossible to return a successful completion in this
// case. We simply connect the successful completion to the graph end.
// The above %ThrowTypeError runtime call is an unconditional throw, making
// it impossible to return a successful completion in this case. We simply
// connect the successful completion to the graph end.
Node* terminate =
graph()->NewNode(common()->Throw(), check_throw, check_fail);
NodeProperties::MergeControlToEnd(graph(), common(), terminate);

View File

@ -0,0 +1,22 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function f(callback) {
[Object].forEach(callback);
}
function message_of_f() {
try {
f("a teapot");
} catch(e) {
return String(e);
}
}
assertEquals("TypeError: a teapot is not a function", message_of_f());
assertEquals("TypeError: a teapot is not a function", message_of_f());
%OptimizeFunctionOnNextCall(f);
assertEquals("TypeError: a teapot is not a function", message_of_f());