Commit 7708d4a2 authored by marja@chromium.org's avatar marja@chromium.org

Move ParseLeftHandSideExpression to ParserBase.

Includes cleanups:
- Reorganized functions in PreParserFactory to be in the logical order.
- De-hackified things PreParser doesn't need to track, such as IsCall & IsCallNew.

R=mstarzinger@chromium.org
BUG=

Review URL: https://codereview.chromium.org/206433003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20150 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 84520308
......@@ -449,6 +449,16 @@ void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
}
void ParserTraits::CheckPossibleEvalCall(Expression* expression,
Scope* scope) {
VariableProxy* callee = expression->AsVariableProxy();
if (callee != NULL &&
callee->IsVariable(parser_->isolate()->factory()->eval_string())) {
scope->DeclarationScope()->RecordEvalCall();
}
}
Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) {
VariableProxy* proxy = expression != NULL
? expression->AsVariableProxy()
......@@ -740,8 +750,8 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral(
}
Expression* ParserTraits::ParseLeftHandSideExpression(bool* ok) {
return parser_->ParseLeftHandSideExpression(ok);
Expression* ParserTraits::ParseMemberWithNewPrefixesExpression(bool* ok) {
return parser_->ParseMemberWithNewPrefixesExpression(ok);
}
......@@ -3043,79 +3053,6 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
}
Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
// LeftHandSideExpression ::
// (NewExpression | MemberExpression) ...
Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
while (true) {
switch (peek()) {
case Token::LBRACK: {
Consume(Token::LBRACK);
int pos = position();
Expression* index = ParseExpression(true, CHECK_OK);
result = factory()->NewProperty(result, index, pos);
Expect(Token::RBRACK, CHECK_OK);
break;
}
case Token::LPAREN: {
int pos;
if (scanner()->current_token() == Token::IDENTIFIER) {
// For call of an identifier we want to report position of
// the identifier as position of the call in the stack trace.
pos = position();
} else {
// For other kinds of calls we record position of the parenthesis as
// position of the call. Note that this is extremely important for
// expressions of the form function(){...}() for which call position
// should not point to the closing brace otherwise it will intersect
// with positions recorded for function literal and confuse debugger.
pos = peek_position();
// Also the trailing parenthesis are a hint that the function will
// be called immediately. If we happen to have parsed a preceding
// function literal eagerly, we can also compile it eagerly.
if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
result->AsFunctionLiteral()->set_parenthesized();
}
}
ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
// Keep track of eval() calls since they disable all local variable
// optimizations.
// The calls that need special treatment are the
// direct eval calls. These calls are all of the form eval(...), with
// no explicit receiver.
// These calls are marked as potentially direct eval calls. Whether
// they are actually direct calls to eval is determined at run time.
VariableProxy* callee = result->AsVariableProxy();
if (callee != NULL &&
callee->IsVariable(isolate()->factory()->eval_string())) {
scope_->DeclarationScope()->RecordEvalCall();
}
result = factory()->NewCall(result, args, pos);
if (fni_ != NULL) fni_->RemoveLastFunction();
break;
}
case Token::PERIOD: {
Consume(Token::PERIOD);
int pos = position();
Handle<String> name = ParseIdentifierName(CHECK_OK);
result = factory()->NewProperty(
result, factory()->NewLiteral(name, pos), pos);
if (fni_ != NULL) fni_->PushLiteralName(name);
break;
}
default:
return result;
}
}
}
Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) {
// NewExpression ::
// ('new')+ MemberExpression
......
......@@ -490,6 +490,11 @@ class ParserTraits {
static void CheckAssigningFunctionLiteralToProperty(Expression* left,
Expression* right);
// Keep track of eval() calls since they disable all local variable
// optimizations. This checks if expression is an eval call, and if yes,
// forwards the information to scope.
void CheckPossibleEvalCall(Expression* expression, Scope* scope);
// Determine if the expression is a variable proxy and mark it as being used
// in an assignment or with a increment/decrement operator. This is currently
// used on for the statically checking assignments to harmony const bindings.
......@@ -497,7 +502,7 @@ class ParserTraits {
// Checks LHS expression for assignment and prefix/postfix increment/decrement
// in strict mode.
void CheckStrictModeLValue(Expression*expression, bool* ok);
void CheckStrictModeLValue(Expression* expression, bool* ok);
// Returns true if we have a binary expression between two numeric
// literals. In that case, *x will be changed to an expression which is the
......@@ -584,7 +589,7 @@ class ParserTraits {
int function_token_position,
FunctionLiteral::FunctionType type,
bool* ok);
Expression* ParseLeftHandSideExpression(bool* ok);
Expression* ParseMemberWithNewPrefixesExpression(bool* ok);
private:
Parser* parser_;
......@@ -622,11 +627,6 @@ class Parser : public ParserBase<ParserTraits> {
// https://codereview.chromium.org/7003030/ ).
static const int kMaxNumFunctionLocals = 4194303; // 2^22-1
enum Mode {
PARSE_LAZILY,
PARSE_EAGERLY
};
enum VariableDeclarationContext {
kModuleElement,
kBlockElement,
......@@ -640,22 +640,6 @@ class Parser : public ParserBase<ParserTraits> {
kHasNoInitializers
};
class ParsingModeScope BASE_EMBEDDED {
public:
ParsingModeScope(Parser* parser, Mode mode)
: parser_(parser),
old_mode_(parser->mode()) {
parser_->mode_ = mode;
}
~ParsingModeScope() {
parser_->mode_ = old_mode_;
}
private:
Parser* parser_;
Mode old_mode_;
};
// Returns NULL if parsing failed.
FunctionLiteral* ParseProgram();
......@@ -685,7 +669,6 @@ class Parser : public ParserBase<ParserTraits> {
}
bool inside_with() const { return scope_->inside_with(); }
Mode mode() const { return mode_; }
ScriptDataImpl** cached_data() const { return cached_data_; }
CachedDataMode cached_data_mode() const { return cached_data_mode_; }
Scope* DeclarationScope(VariableMode mode) {
......@@ -742,14 +725,10 @@ class Parser : public ParserBase<ParserTraits> {
// Support for hamony block scoped bindings.
Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
Expression* ParseUnaryExpression(bool* ok);
Expression* ParseLeftHandSideExpression(bool* ok);
Expression* ParseMemberWithNewPrefixesExpression(bool* ok);
Expression* ParseMemberExpression(bool* ok);
Expression* ParseMemberExpressionContinuation(Expression* expression,
bool* ok);
Expression* ParseObjectLiteral(bool* ok);
// Initialize the components of a for-in / for-of statement.
void InitializeForEachStatement(ForEachStatement* stmt,
Expression* each,
......@@ -835,8 +814,6 @@ class Parser : public ParserBase<ParserTraits> {
ScriptDataImpl** cached_data_;
CachedDataMode cached_data_mode_;
Mode mode_;
CompilationInfo* info_;
};
......
......@@ -146,8 +146,9 @@ PreParserExpression PreParserTraits::ParseFunctionLiteral(
}
PreParserExpression PreParserTraits::ParseLeftHandSideExpression(bool* ok) {
return pre_parser_->ParseLeftHandSideExpression(ok);
PreParserExpression PreParserTraits::ParseMemberWithNewPrefixesExpression(
bool* ok) {
return pre_parser_->ParseMemberWithNewPrefixesExpression(ok);
}
......@@ -842,50 +843,6 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
#undef DUMMY
PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) {
// LeftHandSideExpression ::
// (NewExpression | MemberExpression) ...
Expression result = ParseMemberWithNewPrefixesExpression(CHECK_OK);
while (true) {
switch (peek()) {
case Token::LBRACK: {
Consume(Token::LBRACK);
ParseExpression(true, CHECK_OK);
Expect(Token::RBRACK, CHECK_OK);
if (result.IsThis()) {
result = Expression::ThisProperty();
} else {
result = Expression::Property();
}
break;
}
case Token::LPAREN: {
ParseArguments(CHECK_OK);
result = Expression::Default();
break;
}
case Token::PERIOD: {
Consume(Token::PERIOD);
ParseIdentifierName(CHECK_OK);
if (result.IsThis()) {
result = Expression::ThisProperty();
} else {
result = Expression::Property();
}
break;
}
default:
return result;
}
}
}
PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
bool* ok) {
// NewExpression ::
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment