Index: src/parser.cc |
=================================================================== |
--- src/parser.cc (revision 1968) |
+++ src/parser.cc (working copy) |
@@ -42,9 +42,50 @@ |
class ParserFactory; |
class ParserLog; |
class TemporaryScope; |
+class Target; |
+ |
template <typename T> class ZoneListWrapper; |
+// PositionStack is used for on-stack allocation of token positions for |
+// new expressions. Please look at ParseNewExpression. |
+ |
+class PositionStack { |
+ public: |
+ PositionStack() : top_(NULL) {} |
+ ~PositionStack() { } |
+ |
+ class Element { |
Kasper Lund
2009/05/15 13:37:11
Couldn't the entire Element class be private?
|
+ public: |
+ Element(PositionStack* stack, int value) { |
+ previous_ = stack->top(); |
+ value_ = value; |
+ stack->set_top(this); |
+ } |
+ protected: |
Kasper Lund
2009/05/15 13:37:11
How about a newline before protected: and private:
Kasper Lund
2009/05/15 13:37:11
Why do you have both private and protected? Do you
|
+ Element* previous() { return previous_; } |
+ int value() { return value_; } |
+ friend class PositionStack; |
+ private: |
+ Element* previous_; |
+ int value_; |
+ }; |
+ |
+ bool is_empty() { return top_ == NULL; } |
+ int pop() { |
+ ASSERT(!is_empty()); |
+ int result = top_->value(); |
+ top_ = top_->previous(); |
+ return result; |
+ } |
+ protected: |
+ Element* top() { return top_; } |
+ void set_top(Element* value) { top_ = value; } |
+ private: |
+ Element* top_; |
+}; |
+ |
+ |
class Parser { |
public: |
Parser(Handle<Script> script, bool allow_natives_syntax, |
@@ -93,7 +134,8 @@ |
TemporaryScope* temp_scope_; |
Mode mode_; |
- List<Node*>* target_stack_; // for break, continue statements |
+ |
+ Target* target_stack_; // for break, continue statements |
bool allow_natives_syntax_; |
v8::Extension* extension_; |
ParserFactory* factory_; |
@@ -150,7 +192,8 @@ |
Expression* ParseLeftHandSideExpression(bool* ok); |
Expression* ParseNewExpression(bool* ok); |
Expression* ParseMemberExpression(bool* ok); |
- Expression* ParseMemberWithNewPrefixesExpression(List<int>* new_prefixes, |
+ Expression* ParseNewPrefix(PositionStack* stack, bool* ok); |
+ Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
bool* ok); |
Expression* ParsePrimaryExpression(bool* ok); |
Expression* ParseArrayLiteral(bool* ok); |
@@ -208,7 +251,7 @@ |
BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok); |
IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok); |
- void RegisterTargetUse(BreakTarget* target, int index); |
+ void RegisterTargetUse(BreakTarget* target, Target* stop); |
// Create a number literal. |
Literal* NewNumberLiteral(double value); |
@@ -971,35 +1014,39 @@ |
class Target BASE_EMBEDDED { |
public: |
- Target(Parser* parser, Node* node) : parser_(parser) { |
- parser_->target_stack_->Add(node); |
+ Target(Parser* parser, Node* node) |
+ : parser_(parser), node_(node), previous_(parser_->target_stack_) { |
+ parser_->target_stack_ = this; |
} |
~Target() { |
- parser_->target_stack_->RemoveLast(); |
+ parser_->target_stack_ = previous_; |
} |
+ Target* previous() { return previous_; } |
+ Node* node() { return node_; } |
+ |
private: |
Parser* parser_; |
+ Node* node_; |
+ Target* previous_; |
}; |
class TargetScope BASE_EMBEDDED { |
public: |
explicit TargetScope(Parser* parser) |
- : parser_(parser), previous_(parser->target_stack_), stack_(0) { |
- parser_->target_stack_ = &stack_; |
+ : parser_(parser), previous_(parser->target_stack_) { |
+ parser->target_stack_ = NULL; |
} |
~TargetScope() { |
- ASSERT(stack_.is_empty()); |
parser_->target_stack_ = previous_; |
} |
private: |
Parser* parser_; |
- List<Node*>* previous_; |
- List<Node*> stack_; |
+ Target* previous_; |
}; |
@@ -2792,7 +2839,8 @@ |
} |
-Expression* Parser::ParseNewExpression(bool* ok) { |
+ |
+Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { |
// NewExpression :: |
// ('new')+ MemberExpression |
@@ -2804,32 +2852,36 @@ |
// many we have parsed. This information is then passed on to the |
// member expression parser, which is only allowed to match argument |
// lists as long as it has 'new' prefixes left |
- List<int> new_positions(4); |
- while (peek() == Token::NEW) { |
- Consume(Token::NEW); |
- new_positions.Add(scanner().location().beg_pos); |
+ Expect(Token::NEW, CHECK_OK); |
+ PositionStack::Element pos(stack, scanner().location().beg_pos); |
+ |
+ Expression* result; |
+ if (peek() == Token::NEW) { |
+ result = ParseNewPrefix(stack, CHECK_OK); |
+ } else { |
+ result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); |
} |
- ASSERT(new_positions.length() > 0); |
- Expression* result = |
- ParseMemberWithNewPrefixesExpression(&new_positions, CHECK_OK); |
- while (!new_positions.is_empty()) { |
- int last = new_positions.RemoveLast(); |
- result = NEW(CallNew(result, new ZoneList<Expression*>(0), last)); |
+ if (!stack->is_empty()) { |
+ result = NEW(CallNew(result, new ZoneList<Expression*>(0), stack->pop())); |
} |
return result; |
} |
+Expression* Parser::ParseNewExpression(bool* ok) { |
+ PositionStack stack; |
+ return ParseNewPrefix(&stack, ok); |
+} |
+ |
+ |
Expression* Parser::ParseMemberExpression(bool* ok) { |
- static List<int> new_positions(0); |
- return ParseMemberWithNewPrefixesExpression(&new_positions, ok); |
+ return ParseMemberWithNewPrefixesExpression(NULL, ok); |
} |
-Expression* Parser::ParseMemberWithNewPrefixesExpression( |
- List<int>* new_positions, |
- bool* ok) { |
+Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
+ bool* ok) { |
// MemberExpression :: |
// (PrimaryExpression | FunctionLiteral) |
// ('[' Expression ']' | '.' Identifier | Arguments)* |
@@ -2865,11 +2917,10 @@ |
break; |
} |
case Token::LPAREN: { |
- if (new_positions->is_empty()) return result; |
+ if ((stack == NULL) || stack->is_empty()) return result; |
// Consume one of the new prefixes (already parsed). |
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
- int last = new_positions->RemoveLast(); |
- result = NEW(CallNew(result, args, last)); |
+ result = NEW(CallNew(result, args, stack->pop())); |
break; |
} |
default: |
@@ -3548,8 +3599,8 @@ |
bool Parser::TargetStackContainsLabel(Handle<String> label) { |
- for (int i = target_stack_->length(); i-- > 0;) { |
- BreakableStatement* stat = target_stack_->at(i)->AsBreakableStatement(); |
+ for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
+ BreakableStatement* stat = t->node()->AsBreakableStatement(); |
if (stat != NULL && ContainsLabel(stat->labels(), label)) |
return true; |
} |
@@ -3559,13 +3610,12 @@ |
BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
bool anonymous = label.is_null(); |
- for (int i = target_stack_->length(); i-- > 0;) { |
- BreakableStatement* stat = target_stack_->at(i)->AsBreakableStatement(); |
+ for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
+ BreakableStatement* stat = t->node()->AsBreakableStatement(); |
if (stat == NULL) continue; |
- |
if ((anonymous && stat->is_target_for_anonymous()) || |
(!anonymous && ContainsLabel(stat->labels(), label))) { |
- RegisterTargetUse(stat->break_target(), i); |
+ RegisterTargetUse(stat->break_target(), t->previous()); |
return stat; |
} |
} |
@@ -3576,13 +3626,13 @@ |
IterationStatement* Parser::LookupContinueTarget(Handle<String> label, |
bool* ok) { |
bool anonymous = label.is_null(); |
- for (int i = target_stack_->length(); i-- > 0;) { |
- IterationStatement* stat = target_stack_->at(i)->AsIterationStatement(); |
+ for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
+ IterationStatement* stat = t->node()->AsIterationStatement(); |
if (stat == NULL) continue; |
ASSERT(stat->is_target_for_anonymous()); |
if (anonymous || ContainsLabel(stat->labels(), label)) { |
- RegisterTargetUse(stat->continue_target(), i); |
+ RegisterTargetUse(stat->continue_target(), t->previous()); |
return stat; |
} |
} |
@@ -3590,12 +3640,12 @@ |
} |
-void Parser::RegisterTargetUse(BreakTarget* target, int index) { |
- // Register that a break target found at the given index in the |
+void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) { |
+ // Register that a break target found at the given stop in the |
// target stack has been used from the top of the target stack. Add |
// the break target to any TargetCollectors passed on the stack. |
- for (int i = target_stack_->length(); i-- > index;) { |
- TargetCollector* collector = target_stack_->at(i)->AsTargetCollector(); |
+ for (Target* t = target_stack_; t != stop; t = t->previous()) { |
+ TargetCollector* collector = t->node()->AsTargetCollector(); |
if (collector != NULL) collector->AddTarget(target); |
} |
} |