Fix incorrect function name inference in case of assignment / global assignment.
authormikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 3 Oct 2011 19:18:05 +0000 (19:18 +0000)
committermikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 3 Oct 2011 19:18:05 +0000 (19:18 +0000)
R=kmillikin@chromium.org
BUG=v8:1732
TEST=test-func-name-inference/GlobalAssignmentAndCall,AssignmentAndCall

Review URL: http://codereview.chromium.org/8112007

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

src/func-name-inferrer.h
src/parser.cc
test/cctest/test-func-name-inference.cc

index bec3a5cf9af4477de1e3cd91e9eed2fb36bfe379..1a572683260a1d89ab6fd670edeb8036554f8eb0 100644 (file)
@@ -70,6 +70,12 @@ class FuncNameInferrer : public ZoneObject {
     }
   }
 
+  void RemoveLastFunction() {
+    if (IsOpen() && !funcs_to_infer_.is_empty()) {
+      funcs_to_infer_.RemoveLast();
+    }
+  }
+
   // Infers a function name and leaves names collection state.
   void Infer() {
     ASSERT(IsOpen());
index 887b272cd24a1f7f7dc4de9b17401737d727da6c..ad8850ec81bf9c79ef225e65e436f5e6965f36ee 100644 (file)
@@ -1765,6 +1765,8 @@ Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
           value->AsCall() == NULL &&
           value->AsCallNew() == NULL) {
         fni_->Infer();
+      } else {
+        fni_->RemoveLastFunction();
       }
     }
 
@@ -2515,6 +2517,8 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
          || op == Token::ASSIGN)
         && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
       fni_->Infer();
+    } else {
+      fni_->RemoveLastFunction();
     }
     fni_->Leave();
   }
index bfae4d1360740830a8a789657d270e13453e68a5..8f405b726e2dfca24eb60360edb0585917710886 100644 (file)
@@ -361,3 +361,42 @@ TEST(FactoryHashmapConditional) {
   // Can't infer the function name statically.
   CheckFunctionName(script, "return 1", "obj.(anonymous function)");
 }
+
+
+TEST(GlobalAssignmentAndCall) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  v8::Handle<v8::Script> script = Compile(
+      "var Foo = function() {\n"
+      "  return 1;\n"
+      "}();\n"
+      "var Baz = Bar = function() {\n"
+      "  return 2;\n"
+      "}");
+  // The inferred name is empty, because this is an assignment of a result.
+  CheckFunctionName(script, "return 1", "");
+  // See MultipleAssignments test.
+  CheckFunctionName(script, "return 2", "Bar");
+}
+
+
+TEST(AssignmentAndCall) {
+  InitializeVM();
+  v8::HandleScope scope;
+
+  v8::Handle<v8::Script> script = Compile(
+      "(function Enclosing() {\n"
+      "  var Foo;\n"
+      "  Foo = function() {\n"
+      "    return 1;\n"
+      "  }();\n"
+      "  var Baz = Bar = function() {\n"
+      "    return 2;\n"
+      "  }\n"
+      "})();");
+  // The inferred name is empty, because this is an assignment of a result.
+  CheckFunctionName(script, "return 1", "");
+  // See MultipleAssignments test.
+  CheckFunctionName(script, "return 2", "Enclosing.Bar");
+}