diff --git a/src/func-name-inferrer.cc b/src/func-name-inferrer.cc index 2d6a86a6f7..f12d026bdb 100644 --- a/src/func-name-inferrer.cc +++ b/src/func-name-inferrer.cc @@ -44,6 +44,20 @@ void FuncNameInferrer::PushEnclosingName(Handle name) { } +void FuncNameInferrer::PushLiteralName(Handle name) { + if (IsOpen() && !Heap::prototype_symbol()->Equals(*name)) { + names_stack_.Add(name); + } +} + + +void FuncNameInferrer::PushVariableName(Handle name) { + if (IsOpen() && !Heap::result_symbol()->Equals(*name)) { + names_stack_.Add(name); + } +} + + Handle FuncNameInferrer::MakeNameFromStack() { if (names_stack_.is_empty()) { return Factory::empty_string(); diff --git a/src/func-name-inferrer.h b/src/func-name-inferrer.h index e88586a445..a35034ecb5 100644 --- a/src/func-name-inferrer.h +++ b/src/func-name-inferrer.h @@ -36,11 +36,12 @@ namespace internal { // Inference is performed in cases when an anonymous function is assigned // to a variable or a property (see test-func-name-inference.cc for examples.) // -// The basic idea is that during AST traversal LHSs of expressions are -// always visited before RHSs. Thus, during visiting the LHS, a name can be -// collected, and during visiting the RHS, a function literal can be collected. -// Inference is performed while leaving the assignment node. -class FuncNameInferrer BASE_EMBEDDED { +// The basic idea is that during parsing of LHSs of certain expressions +// (assignments, declarations, object literals) we collect name strings, +// and during parsing of the RHS, a function literal can be collected. After +// parsing the RHS we can infer a name for function literals that do not have +// a name. +class FuncNameInferrer : public ZoneObject { public: FuncNameInferrer() : entries_stack_(10), @@ -61,11 +62,9 @@ class FuncNameInferrer BASE_EMBEDDED { } // Pushes an encountered name onto names stack when in collection state. - void PushName(Handle name) { - if (IsOpen()) { - names_stack_.Add(name); - } - } + void PushLiteralName(Handle name); + + void PushVariableName(Handle name); // Adds a function to infer name for. void AddFunction(FunctionLiteral* func_to_infer) { @@ -75,11 +74,16 @@ class FuncNameInferrer BASE_EMBEDDED { } // Infers a function name and leaves names collection state. - void InferAndLeave() { + void Infer() { ASSERT(IsOpen()); if (!funcs_to_infer_.is_empty()) { InferFunctionsNames(); } + } + + // Infers a function name and leaves names collection state. + void Leave() { + ASSERT(IsOpen()); names_stack_.Rewind(entries_stack_.RemoveLast()); } @@ -102,34 +106,6 @@ class FuncNameInferrer BASE_EMBEDDED { }; -// A wrapper class that automatically calls InferAndLeave when -// leaving scope. -class ScopedFuncNameInferrer BASE_EMBEDDED { - public: - explicit ScopedFuncNameInferrer(FuncNameInferrer* inferrer) - : inferrer_(inferrer), - is_entered_(false) {} - - ~ScopedFuncNameInferrer() { - if (is_entered_) { - inferrer_->InferAndLeave(); - } - } - - // Triggers the wrapped inferrer into name collection state. - void Enter() { - inferrer_->Enter(); - is_entered_ = true; - } - - private: - FuncNameInferrer* inferrer_; - bool is_entered_; - - DISALLOW_COPY_AND_ASSIGN(ScopedFuncNameInferrer); -}; - - } } // namespace v8::internal #endif // V8_FUNC_NAME_INFERRER_H_ diff --git a/src/parser.cc b/src/parser.cc index 0fef2e2b0e..016869a732 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -32,6 +32,7 @@ #include "bootstrapper.h" #include "codegen.h" #include "compiler.h" +#include "func-name-inferrer.h" #include "messages.h" #include "parser.h" #include "platform.h" @@ -154,6 +155,7 @@ class Parser { bool is_pre_parsing_; ScriptDataImpl* pre_data_; bool seen_loop_stmt_; // Used for inner loop detection. + FuncNameInferrer* fni_; bool inside_with() const { return with_nesting_level_ > 0; } ParserFactory* factory() const { return factory_; } @@ -1214,7 +1216,8 @@ Parser::Parser(Handle