Revision: 19361
Author:   [email protected]
Date:     Thu Feb 13 16:17:55 2014 UTC
Log: (Pre)Parser: Move FunctionState, BlockState and Scope handling to ParserBase.

Notes:
- This removes Parser::FunctionState and PreParser::FunctionState and adds
ParserBase::FunctionState etc.
- Also the scope stacks and function state stacks are moved to ParserBase.
- PreParser::FunctionState didn't add and subtract
JSFunction::kLiteralsPrefixSize (unlike Parser::FunctionState). Since the
actual value of NextMaterializedLiteralIndex is not used in the Preparser,
this change is valid.
- Traits no longer need functions like is_classic_mode(), since now there is a
 unified way of getting the information from the FunctionState / Scope.

[email protected]
BUG=v8:3126
LOG=N

Review URL: https://codereview.chromium.org/135213007
http://code.google.com/p/v8/source/detail?r=19361

Modified:
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/src/preparser.cc
 /branches/bleeding_edge/src/preparser.h

=======================================
--- /branches/bleeding_edge/src/parser.cc       Wed Feb 12 12:02:07 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc       Thu Feb 13 16:17:55 2014 UTC
@@ -460,58 +460,6 @@
   Target** variable_;
   Target* previous_;
 };
-
-
-// ---------------------------------------------------------------------------- -// FunctionState and BlockState together implement the parser's scope stack.
-// The parser's current scope is in scope_.  The BlockState and
-// FunctionState constructors push on the scope stack and the destructors
-// pop.  They are also used to hold the parser's per-function and per-block
-// state.
-
-class Parser::BlockState BASE_EMBEDDED {
- public:
-  BlockState(Scope** scope_stack, Scope* scope)
-      : scope_stack_(scope_stack),
-        outer_scope_(*scope_stack) {
-    *scope_stack = scope;
-  }
-
-  ~BlockState() { *scope_stack_ = outer_scope_; }
-
- private:
-  Scope** scope_stack_;
-  Scope* outer_scope_;
-};
-
-
-Parser::FunctionState::FunctionState(FunctionState** function_state_stack,
-                                     Scope** scope_stack, Scope* scope,
-                                     Zone* zone)
-    : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
-      next_handler_index_(0),
-      expected_property_count_(0),
-      generator_object_variable_(NULL),
-      function_state_stack_(function_state_stack),
-      outer_function_state_(*function_state_stack),
-      scope_stack_(scope_stack),
-      outer_scope_(*scope_stack),
-      isolate_(zone->isolate()),
-      saved_ast_node_id_(isolate_->ast_node_id()),
-      factory_(zone) {
-  *scope_stack_ = scope;
-  *function_state_stack = this;
-  isolate_->set_ast_node_id(BailoutId::FirstUsable().ToInt());
-}
-
-
-Parser::FunctionState::~FunctionState() {
-  *scope_stack_ = outer_scope_;
-  *function_state_stack_ = outer_function_state_;
-  if (outer_function_state_ != NULL) {
-    isolate_->set_ast_node_id(saved_ast_node_id_);
-  }
-}


// ----------------------------------------------------------------------------
@@ -537,27 +485,12 @@
// ----------------------------------------------------------------------------
 // Implementation of Parser

-bool ParserTraits::is_classic_mode() const {
-  return parser_->scope_->is_classic_mode();
-}
-
-
-bool ParserTraits::is_generator() const {
-  return parser_->function_state_->is_generator();
-}
-
-
 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const {
   return identifier.is_identical_to(
              parser_->isolate()->factory()->eval_string()) ||
          identifier.is_identical_to(
              parser_->isolate()->factory()->arguments_string());
 }
-
-
-int ParserTraits::NextMaterializedLiteralIndex() {
-  return parser_->function_state_->NextMaterializedLiteralIndex();
-}


 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
@@ -622,14 +555,6 @@
   }
 }

-
-Expression* ParserTraits::NewRegExpLiteral(Handle<String> js_pattern,
-                                           Handle<String> js_flags,
-                                           int literal_index,
-                                           int pos) {
-  return parser_->factory()->NewRegExpLiteral(
-      js_pattern, js_flags, literal_index, pos);
-}

 Parser::Parser(CompilationInfo* info)
     : ParserBase<ParserTraits>(&scanner_,
@@ -640,9 +565,7 @@
       script_(info->script()),
       scanner_(isolate_->unicode_cache()),
       reusable_preparser_(NULL),
-      scope_(NULL),
       original_scope_(NULL),
-      function_state_(NULL),
       target_stack_(NULL),
       extension_(info->extension()),
       pre_parse_data_(NULL),
@@ -4066,8 +3989,7 @@

// Calling a generator returns a generator object. That object is stored
       // in a temporary variable, a definition that is used by "yield"
- // expressions. Presence of a variable for the generator object in the
-      // FunctionState indicates that this function is a generator.
+      // expressions. This also marks the FunctionState as a generator.
       Variable* temp = scope_->DeclarationScope()->NewTemporary(
           isolate()->factory()->dot_generator_object_string());
       function_state.set_generator_object_variable(temp);
=======================================
--- /branches/bleeding_edge/src/parser.h        Wed Feb 12 12:02:07 2014 UTC
+++ /branches/bleeding_edge/src/parser.h        Thu Feb 13 16:17:55 2014 UTC
@@ -409,18 +409,41 @@

 class ParserTraits {
  public:
-  typedef Parser* ParserType;
-  // Return types for traversing functions.
-  typedef Handle<String> IdentifierType;
-  typedef Expression* ExpressionType;
+  struct Type {
+    typedef v8::internal::Parser* Parser;
+
+    // Types used by FunctionState and BlockState.
+    typedef v8::internal::Scope Scope;
+    typedef AstNodeFactory<AstConstructionVisitor> Factory;
+    typedef Variable GeneratorVariable;
+    typedef v8::internal::Zone Zone;
+
+    // Return types for traversing functions.
+    typedef Handle<String> Identifier;
+    typedef v8::internal::Expression* Expression;
+  };

   explicit ParserTraits(Parser* parser) : parser_(parser) {}
+
+ // Custom operations executed when FunctionStates are created and destructed.
+  template<typename FS>
+  static void SetUpFunctionState(FS* function_state, Zone* zone) {
+    Isolate* isolate = zone->isolate();
+    function_state->isolate_ = isolate;
+    function_state->saved_ast_node_id_ = isolate->ast_node_id();
+    isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
+  }
+
+  template<typename FS>
+  static void TearDownFunctionState(FS* function_state) {
+    if (function_state->outer_function_state_ != NULL) {
+      function_state->isolate_->set_ast_node_id(
+          function_state->saved_ast_node_id_);
+    }
+  }

   // Helper functions for recursive descent.
-  bool is_classic_mode() const;
-  bool is_generator() const;
   bool IsEvalOrArguments(Handle<String> identifier) const;
-  int NextMaterializedLiteralIndex();

   // Reporting errors.
   void ReportMessageAt(Scanner::Location source_location,
@@ -432,20 +455,16 @@
                        Vector<Handle<String> > args);

   // "null" return type creators.
-  static IdentifierType EmptyIdentifier() {
+  static Handle<String> EmptyIdentifier() {
     return Handle<String>();
   }
-  static ExpressionType EmptyExpression() {
+  static Expression* EmptyExpression() {
     return NULL;
   }

   // Producing data during the recursive descent.
-  IdentifierType GetSymbol();
-  IdentifierType NextLiteralString(PretenureFlag tenured);
-  ExpressionType NewRegExpLiteral(IdentifierType js_pattern,
-                                  IdentifierType js_flags,
-                                  int literal_index,
-                                  int pos);
+  Handle<String> GetSymbol();
+  Handle<String> NextLiteralString(PretenureFlag tenured);

  private:
   Parser* parser_;
@@ -494,68 +513,6 @@
     kHasNoInitializers
   };

-  class BlockState;
-
-  class FunctionState BASE_EMBEDDED {
-   public:
-    FunctionState(FunctionState** function_state_stack,
-                  Scope** scope_stack, Scope* scope,
-                  Zone* zone);
-    ~FunctionState();
-
-    int NextMaterializedLiteralIndex() {
-      return next_materialized_literal_index_++;
-    }
-    int materialized_literal_count() {
- return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
-    }
-
-    int NextHandlerIndex() { return next_handler_index_++; }
-    int handler_count() { return next_handler_index_; }
-
-    void AddProperty() { expected_property_count_++; }
-    int expected_property_count() { return expected_property_count_; }
-
-    void set_generator_object_variable(Variable *variable) {
-      ASSERT(variable != NULL);
-      ASSERT(!is_generator());
-      generator_object_variable_ = variable;
-    }
-    Variable* generator_object_variable() const {
-      return generator_object_variable_;
-    }
-    bool is_generator() const {
-      return generator_object_variable_ != NULL;
-    }
-
-    AstNodeFactory<AstConstructionVisitor>* factory() { return &factory_; }
-
-   private:
- // Used to assign an index to each literal that needs materialization in - // the function. Includes regexp literals, and boilerplate for object and
-    // array literals.
-    int next_materialized_literal_index_;
-
-    // Used to assign a per-function index to try and catch handlers.
-    int next_handler_index_;
-
-    // Properties count estimation.
-    int expected_property_count_;
-
-    // For generators, the variable that holds the generator object.  This
-    // variable is used by yield expressions and return statements.  NULL
-    // indicates that this function is not a generator.
-    Variable* generator_object_variable_;
-
-    FunctionState** function_state_stack_;
-    FunctionState* outer_function_state_;
-    Scope** scope_stack_;
-    Scope* outer_scope_;
-    Isolate* isolate_;
-    int saved_ast_node_id_;
-    AstNodeFactory<AstConstructionVisitor> factory_;
-  };
-
   class ParsingModeScope BASE_EMBEDDED {
    public:
     ParsingModeScope(Parser* parser, Mode mode)
@@ -770,19 +727,13 @@
   PreParser::PreParseResult LazyParseFunctionLiteral(
        SingletonLogger* logger);

-  AstNodeFactory<AstConstructionVisitor>* factory() {
-    return function_state_->factory();
-  }
-
   Isolate* isolate_;
   ZoneList<Handle<String> > symbol_cache_;

   Handle<Script> script_;
   Scanner scanner_;
   PreParser* reusable_preparser_;
-  Scope* scope_;  // Scope stack.
   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
-  FunctionState* function_state_;  // Function state stack.
   Target* target_stack_;  // for break, continue statements
   v8::Extension* extension_;
   ScriptDataImpl* pre_parse_data_;
=======================================
--- /branches/bleeding_edge/src/preparser.cc    Wed Feb 12 12:02:07 2014 UTC
+++ /branches/bleeding_edge/src/preparser.cc    Thu Feb 13 16:17:55 2014 UTC
@@ -55,21 +55,6 @@
 namespace v8 {
 namespace internal {

-bool PreParserTraits::is_classic_mode() const {
-  return pre_parser_->scope_->language_mode() == CLASSIC_MODE;
-}
-
-
-bool PreParserTraits::is_generator() const {
-  return pre_parser_->function_state_->is_generator();
-}
-
-
-int PreParserTraits::NextMaterializedLiteralIndex() {
-  return pre_parser_->function_state_->NextMaterializedLiteralIndex();
-}
-
-
 void PreParserTraits::ReportMessageAt(Scanner::Location location,
                                       const char* message,
                                       Vector<const char*> args) {
@@ -126,10 +111,12 @@
     LanguageMode mode, bool is_generator, ParserRecorder* log) {
   log_ = log;
// Lazy functions always have trivial outer scopes (no with/catch scopes).
-  FunctionState top_scope(&function_state_, &scope_, GLOBAL_SCOPE);
+  PreParserScope top_scope(scope_, GLOBAL_SCOPE);
+  FunctionState top_state(&function_state_, &scope_, &top_scope);
   scope_->SetLanguageMode(mode);
-  FunctionState function_scope(&function_state_, &scope_, FUNCTION_SCOPE);
-  function_scope.set_is_generator(is_generator);
+  PreParserScope function_scope(scope_, FUNCTION_SCOPE);
+  FunctionState function_state(&function_state_, &scope_, &function_scope);
+  function_state.set_is_generator(is_generator);
   ASSERT_EQ(Token::LBRACE, scanner()->current_token());
   bool ok = true;
   int start_position = peek_position();
@@ -602,7 +589,8 @@
   ParseExpression(true, CHECK_OK);
   Expect(Token::RPAREN, CHECK_OK);

-  BlockState block_state(&scope_, WITH_SCOPE);
+  PreParserScope with_scope(scope_, WITH_SCOPE);
+  BlockState block_state(&scope_, &with_scope);
   ParseStatement(CHECK_OK);
   return Statement::Default();
 }
@@ -776,7 +764,8 @@
     ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
     Expect(Token::RPAREN, CHECK_OK);
     {
-      BlockState block_state(&scope_, WITH_SCOPE);
+      PreParserScope with_scope(scope_, WITH_SCOPE);
+      BlockState block_state(&scope_, &with_scope);
       ParseBlock(CHECK_OK);
     }
     tok = peek();
@@ -1341,8 +1330,9 @@
   // Parse function body.
   ScopeType outer_scope_type = scope_->type();
   bool inside_with = scope_->inside_with();
-  FunctionState function_scope(&function_state_, &scope_, FUNCTION_SCOPE);
-  function_scope.set_is_generator(is_generator);
+  PreParserScope function_scope(scope_, FUNCTION_SCOPE);
+  FunctionState function_state(&function_state_, &scope_, &function_scope);
+  function_state.set_is_generator(is_generator);
   //  FormalParameterList ::
   //    '(' (Identifier)*[','] ')'
   Expect(Token::LPAREN, CHECK_OK);
@@ -1452,7 +1442,7 @@
   int body_end = scanner()->peek_location().end_pos;
   log_->LogFunction(body_start, body_end,
                     function_state_->materialized_literal_count(),
-                    function_state_->expected_properties(),
+                    function_state_->expected_property_count(),
                     scope_->language_mode());
 }

=======================================
--- /branches/bleeding_edge/src/preparser.h     Thu Feb 13 12:02:57 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h     Thu Feb 13 16:17:55 2014 UTC
@@ -29,6 +29,7 @@
 #define V8_PREPARSER_H

 #include "hashmap.h"
+#include "scopes.h"
 #include "token.h"
 #include "scanner.h"

@@ -40,9 +41,11 @@
 class ParserBase : public Traits {
  public:
   ParserBase(Scanner* scanner, uintptr_t stack_limit,
-             typename Traits::ParserType this_object)
+             typename Traits::Type::Parser this_object)
       : Traits(this_object),
         parenthesized_function_(false),
+        scope_(NULL),
+        function_state_(NULL),
         scanner_(scanner),
         stack_limit_(stack_limit),
         stack_overflow_(false),
@@ -83,6 +86,97 @@
     kDontAllowEvalOrArguments
   };

+ // --------------------------------------------------------------------------- + // FunctionState and BlockState together implement the parser's scope stack.
+  // The parser's current scope is in scope_. BlockState and FunctionState
+ // constructors push on the scope stack and the destructors pop. They are also
+  // used to hold the parser's per-function and per-block state.
+  class BlockState BASE_EMBEDDED {
+   public:
+    BlockState(typename Traits::Type::Scope** scope_stack,
+               typename Traits::Type::Scope* scope)
+        : scope_stack_(scope_stack),
+          outer_scope_(*scope_stack),
+          scope_(scope) {
+      *scope_stack_ = scope_;
+    }
+    ~BlockState() { *scope_stack_ = outer_scope_; }
+
+   private:
+    typename Traits::Type::Scope** scope_stack_;
+    typename Traits::Type::Scope* outer_scope_;
+    typename Traits::Type::Scope* scope_;
+  };
+
+  class FunctionState BASE_EMBEDDED {
+   public:
+    FunctionState(
+        FunctionState** function_state_stack,
+        typename Traits::Type::Scope** scope_stack,
+        typename Traits::Type::Scope* scope,
+        typename Traits::Type::Zone* zone = NULL);
+    ~FunctionState();
+
+    int NextMaterializedLiteralIndex() {
+      return next_materialized_literal_index_++;
+    }
+    int materialized_literal_count() {
+ return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
+    }
+
+    int NextHandlerIndex() { return next_handler_index_++; }
+    int handler_count() { return next_handler_index_; }
+
+    void AddProperty() { expected_property_count_++; }
+    int expected_property_count() { return expected_property_count_; }
+
+ void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
+    bool is_generator() const { return is_generator_; }
+
+    void set_generator_object_variable(
+        typename Traits::Type::GeneratorVariable* variable) {
+      ASSERT(variable != NULL);
+      ASSERT(!is_generator());
+      generator_object_variable_ = variable;
+      is_generator_ = true;
+    }
+    typename Traits::Type::GeneratorVariable* generator_object_variable()
+        const {
+      return generator_object_variable_;
+    }
+
+    typename Traits::Type::Factory* factory() { return &factory_; }
+
+   private:
+ // Used to assign an index to each literal that needs materialization in + // the function. Includes regexp literals, and boilerplate for object and
+    // array literals.
+    int next_materialized_literal_index_;
+
+    // Used to assign a per-function index to try and catch handlers.
+    int next_handler_index_;
+
+    // Properties count estimation.
+    int expected_property_count_;
+
+    // Whether the function is a generator.
+    bool is_generator_;
+ // For generators, this variable may hold the generator object. It variable + // is used by yield expressions and return statements. It is not necessary
+    // for generator functions to have this variable set.
+    Variable* generator_object_variable_;
+
+    FunctionState** function_state_stack_;
+    FunctionState* outer_function_state_;
+    typename Traits::Type::Scope** scope_stack_;
+    typename Traits::Type::Scope* outer_scope_;
+    Isolate* isolate_;   // Only used by ParserTraits.
+    int saved_ast_node_id_;  // Only used by ParserTraits.
+    typename Traits::Type::Factory factory_;
+
+    friend class ParserTraits;
+  };
+
   Scanner* scanner() const { return scanner_; }
   int position() { return scanner_->location().beg_pos; }
   int peek_position() { return scanner_->peek_location().beg_pos; }
@@ -192,6 +286,14 @@
       return 0;  // 0 precedence will terminate binary expression parsing
     return Token::Precedence(token);
   }
+
+  typename Traits::Type::Factory* factory() {
+    return function_state_->factory();
+  }
+
+  bool is_classic_mode() const { return scope_->is_classic_mode(); }
+
+  bool is_generator() const { return function_state_->is_generator(); }

   // Report syntax errors.
   void ReportMessage(const char* message, Vector<const char*> args) {
@@ -212,21 +314,22 @@
   // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or
// "arguments" as identifier even in strict mode (this is needed in cases like
   // "var foo = eval;").
-  typename Traits::IdentifierType ParseIdentifier(
+  typename Traits::Type::Identifier ParseIdentifier(
       AllowEvalOrArgumentsAsIdentifier,
       bool* ok);
// Parses an identifier or a strict mode future reserved word, and indicate
   // whether it is strict mode future reserved.
-  typename Traits::IdentifierType ParseIdentifierOrStrictReservedWord(
+  typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord(
       bool* is_strict_reserved,
       bool* ok);
-  typename Traits::IdentifierType ParseIdentifierName(bool* ok);
+  typename Traits::Type::Identifier ParseIdentifierName(bool* ok);
// Parses an identifier and determines whether or not it is 'get' or 'set'. - typename Traits::IdentifierType ParseIdentifierNameOrGetOrSet(bool* is_get, + typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, bool* is_set,
                                                                 bool* ok);

- typename Traits::ExpressionType ParseRegExpLiteral(bool seen_equal, bool* ok);
+  typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal,
+                                                        bool* ok);

   // Used to detect duplicates in object literals. Each of the values
   // kGetterProperty, kSetterProperty and kValueProperty represents
@@ -288,6 +391,9 @@
   // so never lazily compile it.
   bool parenthesized_function_;

+  typename Traits::Type::Scope* scope_;  // Scope stack.
+  FunctionState* function_state_;  // Function state stack.
+
  private:
   Scanner* scanner_;
   uintptr_t stack_limit_;
@@ -427,26 +533,92 @@

   int code_;
 };
+
+
+class PreParserScope {
+ public:
+ explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
+      : scope_type_(scope_type) {
+    if (outer_scope) {
+      scope_inside_with_ =
+          outer_scope->scope_inside_with_ || is_with_scope();
+      language_mode_ = outer_scope->language_mode();
+    } else {
+      scope_inside_with_ = is_with_scope();
+      language_mode_ = CLASSIC_MODE;
+    }
+  }
+
+  bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
+  bool is_classic_mode() const {
+    return language_mode() == CLASSIC_MODE;
+  }
+  bool is_extended_mode() {
+    return language_mode() == EXTENDED_MODE;
+  }
+  bool inside_with() const {
+    return scope_inside_with_;
+  }
+
+  ScopeType type() { return scope_type_; }
+  LanguageMode language_mode() const { return language_mode_; }
+  void SetLanguageMode(LanguageMode language_mode) {
+    language_mode_ = language_mode;
+  }
+
+ private:
+  ScopeType scope_type_;
+  bool scope_inside_with_;
+  LanguageMode language_mode_;
+};
+
+
+class PreParserFactory {
+ public:
+  explicit PreParserFactory(void* extra_param) {}
+
+  PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
+                                       PreParserIdentifier js_flags,
+                                       int literal_index,
+                                       int pos) {
+    return PreParserExpression::Default();
+  }
+};
+

 class PreParser;

-
 class PreParserTraits {
  public:
-  typedef PreParser* ParserType;
-  // Return types for traversing functions.
-  typedef PreParserIdentifier IdentifierType;
-  typedef PreParserExpression ExpressionType;
+  struct Type {
+    typedef PreParser* Parser;
+
+    // Types used by FunctionState and BlockState.
+    typedef PreParserScope Scope;
+    typedef PreParserFactory Factory;
+    // PreParser doesn't need to store generator variables.
+    typedef void GeneratorVariable;
+    // No interaction with Zones.
+    typedef void Zone;
+
+    // Return types for traversing functions.
+    typedef PreParserIdentifier Identifier;
+    typedef PreParserExpression Expression;
+  };

explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
+
+  // Custom operations executed when FunctionStates are created and
+  // destructed. (The PreParser doesn't need to do anything.)
+  template<typename FS>
+  static void SetUpFunctionState(FS* function_state, void*) {}
+  template<typename FS>
+  static void TearDownFunctionState(FS* function_state) {}

   // Helper functions for recursive descent.
-  bool is_classic_mode() const;
-  bool is_generator() const;
-  static bool IsEvalOrArguments(IdentifierType identifier) {
+  static bool IsEvalOrArguments(PreParserIdentifier identifier) {
     return identifier.IsEvalOrArguments();
   }
-  int NextMaterializedLiteralIndex();

   // Reporting errors.
   void ReportMessageAt(Scanner::Location location,
@@ -461,24 +633,18 @@
                        const char* name_opt);

   // "null" return type creators.
-  static IdentifierType EmptyIdentifier() {
+  static PreParserIdentifier EmptyIdentifier() {
     return PreParserIdentifier::Default();
   }
-  static ExpressionType EmptyExpression() {
+  static PreParserExpression EmptyExpression() {
     return PreParserExpression::Default();
   }

   // Producing data during the recursive descent.
-  IdentifierType GetSymbol();
-  static IdentifierType NextLiteralString(PretenureFlag tenured) {
+  PreParserIdentifier GetSymbol();
+  static PreParserIdentifier NextLiteralString(PretenureFlag tenured) {
     return PreParserIdentifier::Default();
   }
-  ExpressionType NewRegExpLiteral(IdentifierType js_pattern,
-                                  IdentifierType js_flags,
-                                  int literal_index,
-                                  int pos) {
-    return PreParserExpression::Default();
-  }

  private:
   PreParser* pre_parser_;
@@ -511,18 +677,15 @@
             ParserRecorder* log,
             uintptr_t stack_limit)
       : ParserBase<PreParserTraits>(scanner, stack_limit, this),
-        log_(log),
-        function_state_(NULL),
-        scope_(NULL) { }
-
-  ~PreParser() {}
+        log_(log) {}

   // Pre-parse the program from the character stream; returns true on
   // success (even if parsing failed, the pre-parse data successfully
   // captured the syntax error), and false if a stack-overflow happened
   // during parsing.
   PreParseResult PreParseProgram() {
-    FunctionState top_scope(&function_state_, &scope_, GLOBAL_SCOPE);
+    PreParserScope scope(scope_, GLOBAL_SCOPE);
+    FunctionState top_scope(&function_state_, &scope_, &scope, NULL);
     bool ok = true;
     int start_position = scanner()->peek_location().beg_pos;
     ParseSourceElements(Token::EOS, &ok);
@@ -620,98 +783,6 @@

   typedef int Arguments;

-  class Scope {
-   public:
-    explicit Scope(Scope* outer_scope, ScopeType scope_type)
-        : scope_type_(scope_type) {
-      if (outer_scope) {
-        scope_inside_with_ =
-            outer_scope->scope_inside_with_ || is_with_scope();
-        language_mode_ = outer_scope->language_mode();
-      } else {
-        scope_inside_with_ = is_with_scope();
-        language_mode_ = CLASSIC_MODE;
-      }
-    }
-
-    bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
-    bool is_classic_mode() const {
-      return language_mode() == CLASSIC_MODE;
-    }
-    bool is_extended_mode() {
-      return language_mode() == EXTENDED_MODE;
-    }
-    bool inside_with() const {
-      return scope_inside_with_;
-    }
-
-    ScopeType type() { return scope_type_; }
-    LanguageMode language_mode() const { return language_mode_; }
-    void SetLanguageMode(LanguageMode language_mode) {
-      language_mode_ = language_mode;
-    }
-
-   private:
-    ScopeType scope_type_;
-    bool scope_inside_with_;
-    LanguageMode language_mode_;
-  };
-
-  class FunctionState {
-   public:
- FunctionState(FunctionState** function_state_stack, Scope** scope_stack,
-                  ScopeType scope_type)
-        : function_state_stack_(function_state_stack),
-          outer_function_state_(*function_state_stack),
-          scope_stack_(scope_stack),
-          outer_scope_(*scope_stack),
-          scope_(*scope_stack, scope_type),
-          materialized_literal_count_(0),
-          expected_properties_(0),
-          is_generator_(false) {
-      *scope_stack = &scope_;
-      *function_state_stack = this;
-    }
-    ~FunctionState() {
-      *scope_stack_ = outer_scope_;
-      *function_state_stack_ = outer_function_state_;
-    }
- int NextMaterializedLiteralIndex() { return materialized_literal_count_++; }
-    void AddProperty() { expected_properties_++; }
-    int expected_properties() { return expected_properties_; }
- int materialized_literal_count() { return materialized_literal_count_; }
-    bool is_generator() { return is_generator_; }
- void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
-
-   private:
-    FunctionState** const function_state_stack_;
-    FunctionState* const outer_function_state_;
-    Scope** const scope_stack_;
-    Scope* const outer_scope_;
-    Scope scope_;
-
-    int materialized_literal_count_;
-    int expected_properties_;
-    bool is_generator_;
-  };
-
-  class BlockState {
-   public:
-    BlockState(Scope** scope_stack, ScopeType scope_type)
-        : scope_stack_(scope_stack),
-          outer_scope_(*scope_stack),
-          scope_(*scope_stack, scope_type) {
-      *scope_stack_ = &scope_;
-    }
-
-    ~BlockState() { *scope_stack_ = outer_scope_; }
-
-   private:
-    Scope** scope_stack_;
-    Scope* outer_scope_;
-    Scope scope_;
-  };
-
   // All ParseXXX functions take as the last argument an *ok parameter
   // which is set to false if parsing failed; it is unchanged otherwise.
   // By making the 'exception handling' explicit, we are forced to check
@@ -774,9 +845,39 @@
   bool CheckInOrOf(bool accept_OF);

   ParserRecorder* log_;
-  FunctionState* function_state_;
-  Scope* scope_;
 };
+
+
+template<class Traits>
+ParserBase<Traits>::FunctionState::FunctionState(
+    FunctionState** function_state_stack,
+    typename Traits::Type::Scope** scope_stack,
+    typename Traits::Type::Scope* scope,
+    typename Traits::Type::Zone* extra_param)
+    : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
+      next_handler_index_(0),
+      expected_property_count_(0),
+      is_generator_(false),
+      generator_object_variable_(NULL),
+      function_state_stack_(function_state_stack),
+      outer_function_state_(*function_state_stack),
+      scope_stack_(scope_stack),
+      outer_scope_(*scope_stack),
+      isolate_(NULL),
+      saved_ast_node_id_(0),
+      factory_(extra_param) {
+  *scope_stack_ = scope;
+  *function_state_stack = this;
+  Traits::SetUpFunctionState(this, extra_param);
+}
+
+
+template<class Traits>
+ParserBase<Traits>::FunctionState::~FunctionState() {
+  *scope_stack_ = outer_scope_;
+  *function_state_stack_ = outer_function_state_;
+  Traits::TearDownFunctionState(this);
+}


 template<class Traits>
@@ -803,10 +904,9 @@
       return ReportMessageAt(source_location, "unexpected_reserved");
     case Token::YIELD:
     case Token::FUTURE_STRICT_RESERVED_WORD:
-      return ReportMessageAt(
-          source_location,
-          this->is_classic_mode() ? "unexpected_token_identifier"
-                                  : "unexpected_strict_reserved");
+      return ReportMessageAt(source_location,
+ is_classic_mode() ? "unexpected_token_identifier"
+                                               : "unexpected_strict_reserved");
     default:
       const char* name = Token::String(token);
       ASSERT(name != NULL);
@@ -817,21 +917,20 @@


 template<class Traits>
-typename Traits::IdentifierType ParserBase<Traits>::ParseIdentifier(
+typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier(
     AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
     bool* ok) {
   Token::Value next = Next();
   if (next == Token::IDENTIFIER) {
-    typename Traits::IdentifierType name = this->GetSymbol();
+    typename Traits::Type::Identifier name = this->GetSymbol();
     if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
-        !this->is_classic_mode() && this->IsEvalOrArguments(name)) {
+        !is_classic_mode() && this->IsEvalOrArguments(name)) {
       ReportMessageAt(scanner()->location(), "strict_eval_arguments");
       *ok = false;
     }
     return name;
-  } else if (this->is_classic_mode() &&
-             (next == Token::FUTURE_STRICT_RESERVED_WORD ||
-              (next == Token::YIELD && !this->is_generator()))) {
+ } else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD || + (next == Token::YIELD && !is_generator()))) {
     return this->GetSymbol();
   } else {
     this->ReportUnexpectedToken(next);
@@ -842,7 +941,7 @@


 template <class Traits>
-typename Traits::IdentifierType ParserBase<
+typename Traits::Type::Identifier ParserBase<
     Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
                                                  bool* ok) {
   Token::Value next = Next();
@@ -861,7 +960,7 @@


 template <class Traits>
-typename Traits::IdentifierType ParserBase<Traits>::ParseIdentifierName(
+typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifierName(
     bool* ok) {
   Token::Value next = Next();
   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
@@ -875,11 +974,11 @@


 template <class Traits>
-typename Traits::IdentifierType
+typename Traits::Type::Identifier
 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
                                                   bool* is_set,
                                                   bool* ok) {
-  typename Traits::IdentifierType result = ParseIdentifierName(ok);
+  typename Traits::Type::Identifier result = ParseIdentifierName(ok);
   if (!*ok) return Traits::EmptyIdentifier();
   if (scanner()->is_literal_ascii() &&
       scanner()->literal_length() == 3) {
@@ -892,7 +991,7 @@


 template <class Traits>
-typename Traits::ExpressionType
+typename Traits::Type::Expression
 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) {
   int pos = peek_position();
   if (!scanner()->ScanRegExpPattern(seen_equal)) {
@@ -902,18 +1001,20 @@
     return Traits::EmptyExpression();
   }

-  int literal_index = this->NextMaterializedLiteralIndex();
+  int literal_index = function_state_->NextMaterializedLiteralIndex();

- typename Traits::IdentifierType js_pattern = this->NextLiteralString(TENURED);
+  typename Traits::Type::Identifier js_pattern =
+      this->NextLiteralString(TENURED);
   if (!scanner()->ScanRegExpFlags()) {
     Next();
     ReportMessageAt(scanner()->location(), "invalid_regexp_flags");
     *ok = false;
     return Traits::EmptyExpression();
   }
- typename Traits::IdentifierType js_flags = this->NextLiteralString(TENURED);
+  typename Traits::Type::Identifier js_flags =
+      this->NextLiteralString(TENURED);
   Next();
-  return this->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
+ return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
 }


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to