From: jarin Date: Tue, 27 Jan 2015 06:57:30 +0000 (-0800) Subject: [turbofan] Handle cyclic dependencies in context typing. X-Git-Tag: upstream/4.7.83~4759 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4c79f55c320b348ac341b8d3cffa269922f49546;p=platform%2Fupstream%2Fv8.git [turbofan] Handle cyclic dependencies in context typing. BUG=chromium:451012 LOG=n R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/874983002 Cr-Commit-Position: refs/heads/master@{#26281} --- diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index 2f0cbf1ab..c8c6aba87 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -316,14 +316,7 @@ class Typer::Visitor : public Reducer { return BoundsOrNone(operand_node); } - Bounds ContextOperand(Node* node) { - Bounds result = BoundsOrNone(NodeProperties::GetContextInput(node)); - DCHECK(result.upper->Maybe(Type::Internal())); - // TODO(rossberg): More precisely, instead of the above assertion, we should - // back-propagate the constraint that it has to be a subtype of Internal. - return result; - } - + Bounds WrapContextBoundsForInput(Node* node); Type* Weaken(Type* current_type, Type* previous_type); Zone* zone() { return typer_->zone(); } @@ -1387,40 +1380,45 @@ Bounds Typer::Visitor::TypeJSStoreContext(Node* node) { } +Bounds Typer::Visitor::WrapContextBoundsForInput(Node* node) { + Bounds outer = BoundsOrNone(NodeProperties::GetContextInput(node)); + if (outer.upper->Is(Type::None())) { + return Bounds(Type::None()); + } else { + DCHECK(outer.upper->Maybe(Type::Internal())); + return Bounds(Type::Context(outer.upper, zone())); + } +} + + Bounds Typer::Visitor::TypeJSCreateFunctionContext(Node* node) { - Bounds outer = ContextOperand(node); - return Bounds(Type::Context(outer.upper, zone())); + return WrapContextBoundsForInput(node); } Bounds Typer::Visitor::TypeJSCreateCatchContext(Node* node) { - Bounds outer = ContextOperand(node); - return Bounds(Type::Context(outer.upper, zone())); + return WrapContextBoundsForInput(node); } Bounds Typer::Visitor::TypeJSCreateWithContext(Node* node) { - Bounds outer = ContextOperand(node); - return Bounds(Type::Context(outer.upper, zone())); + return WrapContextBoundsForInput(node); } Bounds Typer::Visitor::TypeJSCreateBlockContext(Node* node) { - Bounds outer = ContextOperand(node); - return Bounds(Type::Context(outer.upper, zone())); + return WrapContextBoundsForInput(node); } Bounds Typer::Visitor::TypeJSCreateModuleContext(Node* node) { // TODO(rossberg): this is probably incorrect - Bounds outer = ContextOperand(node); - return Bounds(Type::Context(outer.upper, zone())); + return WrapContextBoundsForInput(node); } Bounds Typer::Visitor::TypeJSCreateScriptContext(Node* node) { - Bounds outer = ContextOperand(node); - return Bounds(Type::Context(outer.upper, zone())); + return WrapContextBoundsForInput(node); } diff --git a/test/mjsunit/compiler/regress-451012.js b/test/mjsunit/compiler/regress-451012.js new file mode 100644 index 000000000..bffc8bc5b --- /dev/null +++ b/test/mjsunit/compiler/regress-451012.js @@ -0,0 +1,12 @@ +// Copyright 2015 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. + +"use strict"; +function f() { + for (let v; v; ) { + let x; + } +} + +f();