From: mikhail.naganov@gmail.com Date: Thu, 16 Apr 2009 16:34:24 +0000 (+0000) Subject: Allow multiple function literals to be assigned to the same var / property. X-Git-Tag: upstream/4.7.83~24301 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7aacf00933a112ec388a51c11615f031ea05393a;p=platform%2Fupstream%2Fv8.git Allow multiple function literals to be assigned to the same var / property. In such a case all functions get the same name. I think it's a good performance / usability tradeoff. In case a developer wants more clarity, it's up to him to give names to functions. Review URL: http://codereview.chromium.org/67168 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1727 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/func-name-inferrer.cc b/src/func-name-inferrer.cc index ef0c7dbb4..75f7a9937 100644 --- a/src/func-name-inferrer.cc +++ b/src/func-name-inferrer.cc @@ -63,11 +63,12 @@ Handle FuncNameInferrer::MakeNameFromStackHelper(int pos, } -void FuncNameInferrer::MaybeInferFunctionName() { - if (func_to_infer_ != NULL) { - func_to_infer_->set_inferred_name(MakeNameFromStack()); - func_to_infer_ = NULL; +void FuncNameInferrer::InferFunctionsNames() { + Handle func_name = MakeNameFromStack(); + for (int i = 0; i < funcs_to_infer_.length(); ++i) { + funcs_to_infer_[i]->set_inferred_name(func_name); } + funcs_to_infer_.Rewind(0); } diff --git a/src/func-name-inferrer.h b/src/func-name-inferrer.h index 9dcf7c59f..d8270c364 100644 --- a/src/func-name-inferrer.h +++ b/src/func-name-inferrer.h @@ -45,7 +45,7 @@ class FuncNameInferrer BASE_EMBEDDED { FuncNameInferrer() : entries_stack_(10), names_stack_(5), - func_to_infer_(NULL), + funcs_to_infer_(4), dot_(Factory::NewStringFromAscii(CStrVector("."))) { } @@ -57,39 +57,34 @@ class FuncNameInferrer BASE_EMBEDDED { entries_stack_.Add(names_stack_.length()); } - void Leave() { - ASSERT(IsOpen()); - names_stack_.Rewind(entries_stack_.RemoveLast()); - } - void PushName(Handle name) { if (IsOpen()) { names_stack_.Add(name); } } - void SetFuncToInfer(FunctionLiteral* func_to_infer) { + void AddFunction(FunctionLiteral* func_to_infer) { if (IsOpen()) { - // If we encounter another function literal after already having - // encountered one, the second one replaces the first. - func_to_infer_ = func_to_infer; + funcs_to_infer_.Add(func_to_infer); } } void InferAndLeave() { ASSERT(IsOpen()); - MaybeInferFunctionName(); - Leave(); + if (!funcs_to_infer_.is_empty()) { + InferFunctionsNames(); + } + names_stack_.Rewind(entries_stack_.RemoveLast()); } private: Handle MakeNameFromStack(); Handle MakeNameFromStackHelper(int pos, Handle prev); - void MaybeInferFunctionName(); + void InferFunctionsNames(); List entries_stack_; List > names_stack_; - FunctionLiteral* func_to_infer_; + List funcs_to_infer_; Handle dot_; DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer); diff --git a/src/rewriter.cc b/src/rewriter.cc index 6641f2615..4e3676b7d 100644 --- a/src/rewriter.cc +++ b/src/rewriter.cc @@ -194,7 +194,7 @@ void AstOptimizer::VisitFunctionLiteral(FunctionLiteral* node) { if (node->name()->length() == 0) { // Anonymous function. - func_name_inferrer_.SetFuncToInfer(node); + func_name_inferrer_.AddFunction(node); } } @@ -282,10 +282,7 @@ void AstOptimizer::VisitAssignment(Assignment* node) { case Token::ASSIGN: // No type can be infered from the general assignment. - if (node->value()->AsFunctionLiteral() != NULL || - node->value()->AsObjectLiteral() != NULL) { - scoped_fni.Enter(); - } + scoped_fni.Enter(); break; case Token::ASSIGN_BIT_OR: case Token::ASSIGN_BIT_XOR: diff --git a/test/cctest/test-func-name-inference.cc b/test/cctest/test-func-name-inference.cc index 505862984..d91f75fa0 100644 --- a/test/cctest/test-func-name-inference.cc +++ b/test/cctest/test-func-name-inference.cc @@ -221,3 +221,30 @@ TEST(AsParameter) { CheckFunctionName(script, "return 2", ""); CheckFunctionName(script, "return 3", ""); } + + +TEST(MultipleFuncsConditional) { + InitializeVM(); + v8::HandleScope scope; + + v8::Handle script = Compile( + "fun1 = 0 ?\n" + " function() { return 1; } :\n" + " function() { return 2; }"); + CheckFunctionName(script, "return 1", "fun1"); + CheckFunctionName(script, "return 2", "fun1"); +} + + +TEST(MultipleFuncsInLiteral) { + InitializeVM(); + v8::HandleScope scope; + + v8::Handle script = Compile( + "function MyClass() {}\n" + "MyClass.prototype = {\n" + " method1: 0 ? function() { return 1; } :\n" + " function() { return 2; } }"); + CheckFunctionName(script, "return 1", "MyClass.method1"); + CheckFunctionName(script, "return 2", "MyClass.method1"); +}