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:
parent
566d088ee3
commit
cadd98f860
@ -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).
|
||||||
|
137
src/parser.cc
137
src/parser.cc
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user