Hydrogen: bailout when there is a throw statement in a non-effect context.
authorjkummerow@chromium.org <jkummerow@chromium.org>
Tue, 9 Sep 2014 12:16:33 +0000 (12:16 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org>
Tue, 9 Sep 2014 12:16:33 +0000 (12:16 +0000)
This mirrors the behavior of the compilation pipeline before recent OptimizeFunctionOnNextCall changes.

BUG=chromium:412208
LOG=n
R=jarin@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23799 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen.cc
test/mjsunit/regress/regress-crbug-412208.js [new file with mode: 0644]

index b1b4dfc..35efe63 100644 (file)
@@ -6753,10 +6753,12 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
   DCHECK(!HasStackOverflow());
   DCHECK(current_block() != NULL);
   DCHECK(current_block()->HasPredecessor());
-  // We don't optimize functions with invalid left-hand sides in
-  // assignments, count operations, or for-in.  Consequently throw can
-  // currently only occur in an effect context.
-  DCHECK(ast_context()->IsEffect());
+  if (!ast_context()->IsEffect()) {
+    // The parser turns invalid left-hand sides in assignments into throw
+    // statements, which may not be in effect contexts. We might still try
+    // to optimize such functions; bail out now if we do.
+    return Bailout(kInvalidLeftHandSideInAssignment);
+  }
   CHECK_ALIVE(VisitForValue(expr->exception()));
 
   HValue* value = environment()->Pop();
diff --git a/test/mjsunit/regress/regress-crbug-412208.js b/test/mjsunit/regress/regress-crbug-412208.js
new file mode 100644 (file)
index 0000000..a194f85
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2014 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
+
+var non_const_true = true;
+
+function f() {
+  return non_const_true || (f() = this);
+}
+
+assertTrue(f());
+assertTrue(f());
+%OptimizeFunctionOnNextCall(f);
+assertTrue(f());