[turbofan] Lower {JSToObject} nodes inside try-block.

This adds support for lowering of nodes having the {JSToObject} operator
even if they have exceptional control projections (e.g. are inside of a
try-block).

R=bmeurer@chromium.org
TEST=mjsunit/compiler/optimized-with

Change-Id: I711ff4935db68c43243a971a8b21989487c86317
Reviewed-on: https://chromium-review.googlesource.com/554628
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46318}
This commit is contained in:
Michael Starzinger 2017-06-29 11:54:00 +02:00 committed by Commit Bot
parent f419eca9c7
commit 95a436b271
4 changed files with 36 additions and 14 deletions

View File

@ -2416,11 +2416,6 @@ Node* AstGraphBuilder::BuildToBoolean(Node* input) {
return NewNode(javascript()->ToBoolean(hints), input);
}
Node* AstGraphBuilder::BuildToObject(Node* input) {
Node* object = NewNode(javascript()->ToObject(), input);
return object;
}
Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
LiteralProperty* property,
int slot_number) {

View File

@ -269,7 +269,6 @@ class AstGraphBuilder : public AstVisitor<AstGraphBuilder> {
// Builders for automatic type conversion.
Node* BuildToBoolean(Node* input);
Node* BuildToObject(Node* input);
// Builder for adding the [[HomeObject]] to a value if the value came from a
// function literal and needs a home object. Do nothing otherwise.

View File

@ -1329,13 +1329,6 @@ Reduction JSTypedLowering::ReduceJSToObject(Node* node) {
return Replace(receiver);
}
// TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks.
if (receiver_type->Maybe(Type::NullOrUndefined()) &&
NodeProperties::IsExceptionalCall(node)) {
// ToObject throws for null or undefined inputs.
return NoChange();
}
// Check whether {receiver} is a spec object.
Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver);
Node* branch =
@ -1359,6 +1352,18 @@ Reduction JSTypedLowering::ReduceJSToObject(Node* node) {
receiver, context, frame_state, efalse, if_false);
}
// Update potential {IfException} uses of {node} to point to the above
// ToObject stub call node instead. Note that the stub can only throw on
// receivers that can be null or undefined.
Node* on_exception = nullptr;
if (receiver_type->Maybe(Type::NullOrUndefined()) &&
NodeProperties::IsExceptionalCall(node, &on_exception)) {
NodeProperties::ReplaceControlInput(on_exception, if_false);
NodeProperties::ReplaceEffectInput(on_exception, efalse);
if_false = graph()->NewNode(common()->IfSuccess(), if_false);
Revisit(on_exception);
}
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
@ -2359,7 +2364,7 @@ Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
common()->Call(desc), jsgraph()->HeapConstant(callable.code()), key,
receiver, context, frame_state, effect, if_false0);
// Update potential {IfException} uses of {node} to point to the ahove
// Update potential {IfException} uses of {node} to point to the above
// ForInFilter stub call node instead.
Node* if_exception = nullptr;
if (NodeProperties::IsExceptionalCall(node, &if_exception)) {

View File

@ -0,0 +1,23 @@
// 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
// Test with-statements inside a try-catch block.
(() => {
function f(object) {
try {
with (object) { return x }
} catch(e) {
return e
}
}
assertEquals(23, f({ x:23 }));
assertEquals(42, f({ x:42 }));
assertInstanceof(f(null), TypeError);
assertInstanceof(f(undefined), TypeError);
%OptimizeFunctionOnNextCall(f);
assertInstanceof(f(null), TypeError);
assertInstanceof(f(undefined), TypeError);
})();