M src/jump-target.cc

M    src/parser.cc


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1975 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
bak@chromium.org 2009-05-15 14:58:02 +00:00
parent 566d088ee3
commit cadd98f860
2 changed files with 97 additions and 44 deletions

View File

@ -104,7 +104,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// A list of pointers to frame elements in the entry frame. NULL // A list of pointers to frame elements in the entry frame. NULL
// indicates that the element has not yet been determined. // indicates that the element has not yet been determined.
int length = initial_frame->elements_.length(); int length = initial_frame->elements_.length();
List<FrameElement*> elements(length); ZoneList<FrameElement*> elements(length);
// Convert the number of mergable elements (counted from the top // Convert the number of mergable elements (counted from the top
// down) to a frame high-water mark (counted from the bottom up). // down) to a frame high-water mark (counted from the bottom up).

View File

@ -42,9 +42,51 @@ namespace v8 { namespace internal {
class ParserFactory; class ParserFactory;
class ParserLog; class ParserLog;
class TemporaryScope; class TemporaryScope;
class Target;
template <typename T> class ZoneListWrapper; 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:
explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {}
~PositionStack() { ASSERT(!*ok_ || is_empty()); }
class Element {
public:
Element(PositionStack* stack, int value) {
previous_ = stack->top();
value_ = value;
stack->set_top(this);
}
private:
Element* previous() { return previous_; }
int value() { return value_; }
friend class PositionStack;
Element* previous_;
int value_;
};
bool is_empty() { return top_ == NULL; }
int pop() {
ASSERT(!is_empty());
int result = top_->value();
top_ = top_->previous();
return result;
}
private:
Element* top() { return top_; }
void set_top(Element* value) { top_ = value; }
Element* top_;
bool* ok_;
};
class Parser { class Parser {
public: public:
Parser(Handle<Script> script, bool allow_natives_syntax, Parser(Handle<Script> script, bool allow_natives_syntax,
@ -93,7 +135,8 @@ class Parser {
TemporaryScope* temp_scope_; TemporaryScope* temp_scope_;
Mode mode_; Mode mode_;
List<Node*>* target_stack_; // for break, continue statements
Target* target_stack_; // for break, continue statements
bool allow_natives_syntax_; bool allow_natives_syntax_;
v8::Extension* extension_; v8::Extension* extension_;
ParserFactory* factory_; ParserFactory* factory_;
@ -150,7 +193,8 @@ class Parser {
Expression* ParseLeftHandSideExpression(bool* ok); Expression* ParseLeftHandSideExpression(bool* ok);
Expression* ParseNewExpression(bool* ok); Expression* ParseNewExpression(bool* ok);
Expression* ParseMemberExpression(bool* ok); Expression* ParseMemberExpression(bool* ok);
Expression* ParseMemberWithNewPrefixesExpression(List<int>* new_prefixes, Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
bool* ok); bool* ok);
Expression* ParsePrimaryExpression(bool* ok); Expression* ParsePrimaryExpression(bool* ok);
Expression* ParseArrayLiteral(bool* ok); Expression* ParseArrayLiteral(bool* ok);
@ -208,7 +252,7 @@ class Parser {
BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok); BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
IterationStatement* LookupContinueTarget(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. // Create a number literal.
Literal* NewNumberLiteral(double value); Literal* NewNumberLiteral(double value);
@ -971,35 +1015,39 @@ VariableProxy* PreParser::Declare(Handle<String> name, Variable::Mode mode,
class Target BASE_EMBEDDED { class Target BASE_EMBEDDED {
public: public:
Target(Parser* parser, Node* node) : parser_(parser) { Target(Parser* parser, Node* node)
parser_->target_stack_->Add(node); : parser_(parser), node_(node), previous_(parser_->target_stack_) {
parser_->target_stack_ = this;
} }
~Target() { ~Target() {
parser_->target_stack_->RemoveLast(); parser_->target_stack_ = previous_;
} }
Target* previous() { return previous_; }
Node* node() { return node_; }
private: private:
Parser* parser_; Parser* parser_;
Node* node_;
Target* previous_;
}; };
class TargetScope BASE_EMBEDDED { class TargetScope BASE_EMBEDDED {
public: public:
explicit TargetScope(Parser* parser) explicit TargetScope(Parser* parser)
: parser_(parser), previous_(parser->target_stack_), stack_(0) { : parser_(parser), previous_(parser->target_stack_) {
parser_->target_stack_ = &stack_; parser->target_stack_ = NULL;
} }
~TargetScope() { ~TargetScope() {
ASSERT(stack_.is_empty());
parser_->target_stack_ = previous_; parser_->target_stack_ = previous_;
} }
private: private:
Parser* parser_; Parser* parser_;
List<Node*>* previous_; Target* previous_;
List<Node*> stack_;
}; };
@ -2792,7 +2840,8 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
} }
Expression* Parser::ParseNewExpression(bool* ok) {
Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
// NewExpression :: // NewExpression ::
// ('new')+ MemberExpression // ('new')+ MemberExpression
@ -2804,31 +2853,36 @@ Expression* Parser::ParseNewExpression(bool* ok) {
// many we have parsed. This information is then passed on to the // many we have parsed. This information is then passed on to the
// member expression parser, which is only allowed to match argument // member expression parser, which is only allowed to match argument
// lists as long as it has 'new' prefixes left // lists as long as it has 'new' prefixes left
List<int> new_positions(4); Expect(Token::NEW, CHECK_OK);
while (peek() == Token::NEW) { PositionStack::Element pos(stack, scanner().location().beg_pos);
Consume(Token::NEW);
new_positions.Add(scanner().location().beg_pos);
}
ASSERT(new_positions.length() > 0);
Expression* result = Expression* result;
ParseMemberWithNewPrefixesExpression(&new_positions, CHECK_OK); if (peek() == Token::NEW) {
while (!new_positions.is_empty()) { result = ParseNewPrefix(stack, CHECK_OK);
int last = new_positions.RemoveLast(); } else {
result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
}
if (!stack->is_empty()) {
int last = stack->pop();
result = NEW(CallNew(result, new ZoneList<Expression*>(0), last)); result = NEW(CallNew(result, new ZoneList<Expression*>(0), last));
} }
return result; return result;
} }
Expression* Parser::ParseMemberExpression(bool* ok) { Expression* Parser::ParseNewExpression(bool* ok) {
static List<int> new_positions(0); PositionStack stack(ok);
return ParseMemberWithNewPrefixesExpression(&new_positions, ok); return ParseNewPrefix(&stack, ok);
} }
Expression* Parser::ParseMemberWithNewPrefixesExpression( Expression* Parser::ParseMemberExpression(bool* ok) {
List<int>* new_positions, return ParseMemberWithNewPrefixesExpression(NULL, ok);
}
Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
bool* ok) { bool* ok) {
// MemberExpression :: // MemberExpression ::
// (PrimaryExpression | FunctionLiteral) // (PrimaryExpression | FunctionLiteral)
@ -2865,10 +2919,10 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(
break; break;
} }
case Token::LPAREN: { 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). // Consume one of the new prefixes (already parsed).
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
int last = new_positions->RemoveLast(); int last = stack->pop();
result = NEW(CallNew(result, args, last)); result = NEW(CallNew(result, args, last));
break; break;
} }
@ -3548,8 +3602,8 @@ Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
bool Parser::TargetStackContainsLabel(Handle<String> label) { bool Parser::TargetStackContainsLabel(Handle<String> label) {
for (int i = target_stack_->length(); i-- > 0;) { for (Target* t = target_stack_; t != NULL; t = t->previous()) {
BreakableStatement* stat = target_stack_->at(i)->AsBreakableStatement(); BreakableStatement* stat = t->node()->AsBreakableStatement();
if (stat != NULL && ContainsLabel(stat->labels(), label)) if (stat != NULL && ContainsLabel(stat->labels(), label))
return true; return true;
} }
@ -3559,13 +3613,12 @@ bool Parser::TargetStackContainsLabel(Handle<String> label) {
BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
bool anonymous = label.is_null(); bool anonymous = label.is_null();
for (int i = target_stack_->length(); i-- > 0;) { for (Target* t = target_stack_; t != NULL; t = t->previous()) {
BreakableStatement* stat = target_stack_->at(i)->AsBreakableStatement(); BreakableStatement* stat = t->node()->AsBreakableStatement();
if (stat == NULL) continue; if (stat == NULL) continue;
if ((anonymous && stat->is_target_for_anonymous()) || if ((anonymous && stat->is_target_for_anonymous()) ||
(!anonymous && ContainsLabel(stat->labels(), label))) { (!anonymous && ContainsLabel(stat->labels(), label))) {
RegisterTargetUse(stat->break_target(), i); RegisterTargetUse(stat->break_target(), t->previous());
return stat; return stat;
} }
} }
@ -3576,13 +3629,13 @@ BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
IterationStatement* Parser::LookupContinueTarget(Handle<String> label, IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
bool* ok) { bool* ok) {
bool anonymous = label.is_null(); bool anonymous = label.is_null();
for (int i = target_stack_->length(); i-- > 0;) { for (Target* t = target_stack_; t != NULL; t = t->previous()) {
IterationStatement* stat = target_stack_->at(i)->AsIterationStatement(); IterationStatement* stat = t->node()->AsIterationStatement();
if (stat == NULL) continue; if (stat == NULL) continue;
ASSERT(stat->is_target_for_anonymous()); ASSERT(stat->is_target_for_anonymous());
if (anonymous || ContainsLabel(stat->labels(), label)) { if (anonymous || ContainsLabel(stat->labels(), label)) {
RegisterTargetUse(stat->continue_target(), i); RegisterTargetUse(stat->continue_target(), t->previous());
return stat; return stat;
} }
} }
@ -3590,12 +3643,12 @@ IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
} }
void Parser::RegisterTargetUse(BreakTarget* target, int index) { void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) {
// Register that a break target found at the given index in the // 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 // target stack has been used from the top of the target stack. Add
// the break target to any TargetCollectors passed on the stack. // the break target to any TargetCollectors passed on the stack.
for (int i = target_stack_->length(); i-- > index;) { for (Target* t = target_stack_; t != stop; t = t->previous()) {
TargetCollector* collector = target_stack_->at(i)->AsTargetCollector(); TargetCollector* collector = t->node()->AsTargetCollector();
if (collector != NULL) collector->AddTarget(target); if (collector != NULL) collector->AddTarget(target);
} }
} }