diff --git a/src/parser.cc b/src/parser.cc index a10f9f9c5c..7dbb09dae7 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -246,83 +246,6 @@ void RegExpBuilder::AddQuantifierToAtom(int min, } -// A temporary scope stores information during parsing, just like -// a plain scope. However, temporary scopes are not kept around -// after parsing or referenced by syntax trees so they can be stack- -// allocated and hence used by the pre-parser. -class TemporaryScope BASE_EMBEDDED { - public: - TemporaryScope(TemporaryScope** variable, Isolate* isolate); - ~TemporaryScope(); - - int NextMaterializedLiteralIndex() { - int next_index = - materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; - materialized_literal_count_++; - return next_index; - } - int materialized_literal_count() { return materialized_literal_count_; } - - void SetThisPropertyAssignmentInfo( - bool only_simple_this_property_assignments, - Handle this_property_assignments) { - only_simple_this_property_assignments_ = - only_simple_this_property_assignments; - this_property_assignments_ = this_property_assignments; - } - bool only_simple_this_property_assignments() { - return only_simple_this_property_assignments_; - } - Handle this_property_assignments() { - return this_property_assignments_; - } - - void AddProperty() { expected_property_count_++; } - int expected_property_count() { return expected_property_count_; } - - void AddLoop() { loop_count_++; } - bool ContainsLoops() const { return loop_count_ > 0; } - - private: - // Captures the number of literals that need materialization in the - // function. Includes regexp literals, and boilerplate for object - // and array literals. - int materialized_literal_count_; - - // Properties count estimation. - int expected_property_count_; - - // Keeps track of assignments to properties of this. Used for - // optimizing constructors. - bool only_simple_this_property_assignments_; - Handle this_property_assignments_; - - // Captures the number of loops inside the scope. - int loop_count_; - - // Bookkeeping - TemporaryScope** variable_; - TemporaryScope* parent_; -}; - - -TemporaryScope::TemporaryScope(TemporaryScope** variable, Isolate* isolate) - : materialized_literal_count_(0), - expected_property_count_(0), - only_simple_this_property_assignments_(false), - this_property_assignments_(isolate->factory()->empty_fixed_array()), - loop_count_(0), - variable_(variable), - parent_(*variable) { - *variable = this; -} - - -TemporaryScope::~TemporaryScope() { - *variable_ = parent_; -} - - Handle Parser::LookupSymbol(int symbol_id) { // Length of symbol cache is the number of identified symbols. // If we are larger than that, or negative, it's not a cached symbol. @@ -538,33 +461,94 @@ class TargetScope BASE_EMBEDDED { // LexicalScope is a support class to facilitate manipulation of the // Parser's scope stack. The constructor sets the parser's top scope // to the incoming scope, and the destructor resets it. +// +// Additionlaly, it stores transient information used during parsing. +// These scopes are not kept around after parsing or referenced by syntax +// trees so they can be stack-allocated and hence used by the pre-parser. class LexicalScope BASE_EMBEDDED { public: - LexicalScope(Scope** scope_variable, - int* with_nesting_level_variable, - Scope* scope) - : scope_variable_(scope_variable), - with_nesting_level_variable_(with_nesting_level_variable), - prev_scope_(*scope_variable), - prev_level_(*with_nesting_level_variable) { - *scope_variable = scope; - *with_nesting_level_variable = 0; + LexicalScope(Parser* parser, Scope* scope, Isolate* isolate); + ~LexicalScope(); + + int NextMaterializedLiteralIndex() { + int next_index = + materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; + materialized_literal_count_++; + return next_index; + } + int materialized_literal_count() { return materialized_literal_count_; } + + void SetThisPropertyAssignmentInfo( + bool only_simple_this_property_assignments, + Handle this_property_assignments) { + only_simple_this_property_assignments_ = + only_simple_this_property_assignments; + this_property_assignments_ = this_property_assignments; + } + bool only_simple_this_property_assignments() { + return only_simple_this_property_assignments_; + } + Handle this_property_assignments() { + return this_property_assignments_; } - ~LexicalScope() { - (*scope_variable_)->Leave(); - *scope_variable_ = prev_scope_; - *with_nesting_level_variable_ = prev_level_; - } + void AddProperty() { expected_property_count_++; } + int expected_property_count() { return expected_property_count_; } + + void AddLoop() { loop_count_++; } + bool ContainsLoops() const { return loop_count_ > 0; } private: - Scope** scope_variable_; - int* with_nesting_level_variable_; - Scope* prev_scope_; - int prev_level_; + // Captures the number of literals that need materialization in the + // function. Includes regexp literals, and boilerplate for object + // and array literals. + int materialized_literal_count_; + + // Properties count estimation. + int expected_property_count_; + + // Keeps track of assignments to properties of this. Used for + // optimizing constructors. + bool only_simple_this_property_assignments_; + Handle this_property_assignments_; + + // Captures the number of loops inside the scope. + int loop_count_; + + // Bookkeeping + Parser* parser_; + // Previous values + LexicalScope* lexical_scope_parent_; + Scope* previous_scope_; + int previous_with_nesting_level_; }; + +LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) + : materialized_literal_count_(0), + expected_property_count_(0), + only_simple_this_property_assignments_(false), + this_property_assignments_(isolate->factory()->empty_fixed_array()), + loop_count_(0), + parser_(parser), + lexical_scope_parent_(parser->lexical_scope_), + previous_scope_(parser->top_scope_), + previous_with_nesting_level_(parser->with_nesting_level_) { + parser->top_scope_ = scope; + parser->lexical_scope_ = this; + parser->with_nesting_level_ = 0; +} + + +LexicalScope::~LexicalScope() { + parser_->top_scope_->Leave(); + parser_->top_scope_ = previous_scope_; + parser_->lexical_scope_ = lexical_scope_parent_; + parser_->with_nesting_level_ = previous_with_nesting_level_; +} + + // ---------------------------------------------------------------------------- // The CHECK_OK macro is a convenient macro to enforce error // handling for functions that may fail (by returning !*ok). @@ -598,7 +582,7 @@ Parser::Parser(Handle