Properly handle stack overflows in the AST graph builder.
authormstarzinger@chromium.org <mstarzinger@chromium.org>
Fri, 31 Oct 2014 14:02:05 +0000 (14:02 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org>
Fri, 31 Oct 2014 14:02:46 +0000 (14:02 +0000)
R=jarin@chromium.org
BUG=chromium:429159
TEST=mjsunit/regress/regress-crbug-429159
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#25037}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25037 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/compiler/ast-graph-builder.cc
src/compiler/ast-graph-builder.h
src/compiler/pipeline.cc
test/mjsunit/regress/regress-crbug-429159.js [new file with mode: 0644]

index d7bae5a..7b5abd1 100644 (file)
@@ -339,24 +339,40 @@ void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
 
 void AstGraphBuilder::VisitForValue(Expression* expr) {
   AstValueContext for_value(this);
-  if (!HasStackOverflow()) {
+  if (!CheckStackOverflow()) {
     expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   }
 }
 
 
 void AstGraphBuilder::VisitForEffect(Expression* expr) {
   AstEffectContext for_effect(this);
-  if (!HasStackOverflow()) {
+  if (!CheckStackOverflow()) {
     expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   }
 }
 
 
 void AstGraphBuilder::VisitForTest(Expression* expr) {
   AstTestContext for_condition(this);
-  if (!HasStackOverflow()) {
+  if (!CheckStackOverflow()) {
     expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
+  }
+}
+
+
+void AstGraphBuilder::Visit(Expression* expr) {
+  // Reuses enclosing AstContext.
+  if (!CheckStackOverflow()) {
+    expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   }
 }
 
index 441917f..6e51723 100644 (file)
@@ -159,6 +159,7 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
   void VisitIfNotNull(Statement* stmt);
 
   // Visit expressions.
+  void Visit(Expression* expr);
   void VisitForTest(Expression* expr);
   void VisitForEffect(Expression* expr);
   void VisitForValue(Expression* expr);
index 0dcb408..d1df843 100644 (file)
@@ -319,7 +319,7 @@ Handle<Code> Pipeline::GenerateCode() {
     ZonePool::Scope zone_scope(data.zone_pool());
     AstGraphBuilderWithPositions graph_builder(
         zone_scope.zone(), info(), data.jsgraph(), data.source_positions());
-    graph_builder.CreateGraph();
+    if (!graph_builder.CreateGraph()) return Handle<Code>::null();
     context_node = graph_builder.GetFunctionContext();
   }
 
diff --git a/test/mjsunit/regress/regress-crbug-429159.js b/test/mjsunit/regress/regress-crbug-429159.js
new file mode 100644 (file)
index 0000000..69f1856
--- /dev/null
@@ -0,0 +1,12 @@
+// 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.
+
+try {
+  var src = "return " + Array(12000).join("src,") + "src";
+  var fun = Function(src);
+  assertEquals(src, fun());
+} catch (e) {
+  // Some architectures throw a RangeError, that is fine.
+  assertInstanceof(e, RangeError);
+}