[turbofan] Properly handle IfException projections on JSForInNext.
Don't ignore IfException (and IfSuccess) projections on JSForInNext nodes during JSTypedLowering::ReduceJSForInNext, but instead rewrire the IfException projection to the ForInFilter stub call, which can throw exceptions in case of proxies. R=yangguo@chromium.org BUG=v8:6121 Review-Url: https://codereview.chromium.org/2761703002 Cr-Commit-Position: refs/heads/master@{#43925}
This commit is contained in:
parent
a2588a5ada
commit
a93e5221d8
@ -2199,11 +2199,23 @@ Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
|
||||
vfalse0 = efalse0 = if_false0 = graph()->NewNode(
|
||||
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
|
||||
// ForInFilter stub call node instead.
|
||||
Node* if_exception = nullptr;
|
||||
if (NodeProperties::IsExceptionalCall(node, &if_exception)) {
|
||||
if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
|
||||
NodeProperties::ReplaceControlInput(if_exception, vfalse0);
|
||||
NodeProperties::ReplaceEffectInput(if_exception, efalse0);
|
||||
Revisit(if_exception);
|
||||
}
|
||||
}
|
||||
|
||||
control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
|
||||
effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
|
||||
ReplaceWithValue(node, node, effect, control);
|
||||
|
||||
// Morph the {node} into a Phi.
|
||||
node->ReplaceInput(0, vtrue0);
|
||||
node->ReplaceInput(1, vfalse0);
|
||||
node->ReplaceInput(2, control);
|
||||
|
23
test/mjsunit/regress/regress-6121.js
Normal file
23
test/mjsunit/regress/regress-6121.js
Normal 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
|
||||
|
||||
function foo(o) {
|
||||
try {
|
||||
for (var x in o) {}
|
||||
return false;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var o = new Proxy({a:1},{
|
||||
getOwnPropertyDescriptor(target, property) { throw target; }
|
||||
});
|
||||
|
||||
assertTrue(foo(o));
|
||||
assertTrue(foo(o));
|
||||
%OptimizeFunctionOnNextCall(foo);
|
||||
assertTrue(foo(o));
|
Loading…
Reference in New Issue
Block a user