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
parent 5edf6f35
......@@ -63,11 +63,12 @@ Handle<String> 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<String> 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);
}
......
......@@ -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<String> 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<String> MakeNameFromStack();
Handle<String> MakeNameFromStackHelper(int pos, Handle<String> prev);
void MaybeInferFunctionName();
void InferFunctionsNames();
List<int> entries_stack_;
List<Handle<String> > names_stack_;
FunctionLiteral* func_to_infer_;
List<FunctionLiteral*> funcs_to_infer_;
Handle<String> dot_;
DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
......
......@@ -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:
......
......@@ -221,3 +221,30 @@ TEST(AsParameter) {
CheckFunctionName(script, "return 2", "");
CheckFunctionName(script, "return 3", "");
}
TEST(MultipleFuncsConditional) {
InitializeVM();
v8::HandleScope scope;
v8::Handle<v8::Script> 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<v8::Script> 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");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment