Revision: 20150
Author: [email protected]
Date: Fri Mar 21 09:51:33 2014 UTC
Log: 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.
[email protected]
BUG=
Review URL: https://codereview.chromium.org/206433003
http://code.google.com/p/v8/source/detail?r=20150
Modified:
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/src/preparser.cc
/branches/bleeding_edge/src/preparser.h
=======================================
--- /branches/bleeding_edge/src/parser.cc Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/parser.cc Fri Mar 21 09:51:33 2014 UTC
@@ -447,6 +447,16 @@
right->AsFunctionLiteral()->set_pretenure();
}
}
+
+
+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) {
@@ -740,8 +750,8 @@
}
-Expression* ParserTraits::ParseLeftHandSideExpression(bool* ok) {
- return parser_->ParseLeftHandSideExpression(ok);
+Expression* ParserTraits::ParseMemberWithNewPrefixesExpression(bool* ok) {
+ return parser_->ParseMemberWithNewPrefixesExpression(ok);
}
@@ -3041,79 +3051,6 @@
return loop;
}
}
-
-
-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) {
=======================================
--- /branches/bleeding_edge/src/parser.h Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/parser.h Fri Mar 21 09:51:33 2014 UTC
@@ -490,6 +490,11 @@
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 @@
// 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 @@
int function_token_position,
FunctionLiteral::FunctionType type,
bool* ok);
- Expression* ParseLeftHandSideExpression(bool* ok);
+ Expression* ParseMemberWithNewPrefixesExpression(bool* ok);
private:
Parser* parser_;
@@ -622,11 +627,6 @@
// 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 @@
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 @@
}
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 @@
// 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 @@
ScriptDataImpl** cached_data_;
CachedDataMode cached_data_mode_;
- Mode mode_;
-
CompilationInfo* info_;
};
=======================================
--- /branches/bleeding_edge/src/preparser.cc Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/preparser.cc Fri Mar 21 09:51:33 2014 UTC
@@ -146,8 +146,9 @@
}
-PreParserExpression PreParserTraits::ParseLeftHandSideExpression(bool* ok)
{
- return pre_parser_->ParseLeftHandSideExpression(ok);
+PreParserExpression PreParserTraits::ParseMemberWithNewPrefixesExpression(
+ bool* ok) {
+ return pre_parser_->ParseMemberWithNewPrefixesExpression(ok);
}
@@ -842,50 +843,6 @@
#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 ::
=======================================
--- /branches/bleeding_edge/src/preparser.h Fri Mar 21 09:46:18 2014 UTC
+++ /branches/bleeding_edge/src/preparser.h Fri Mar 21 09:51:33 2014 UTC
@@ -97,6 +97,7 @@
extension_(extension),
fni_(NULL),
log_(log),
+ mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
scanner_(scanner),
stack_limit_(stack_limit),
stack_overflow_(false),
@@ -138,6 +139,11 @@
kDontAllowEvalOrArguments
};
+ enum Mode {
+ PARSE_LAZILY,
+ PARSE_EAGERLY
+ };
+
//
---------------------------------------------------------------------------
// FunctionState and BlockState together implement the parser's scope
stack.
// The parser's current scope is in scope_. BlockState and FunctionState
@@ -229,11 +235,28 @@
friend class ParserTraits;
};
+ class ParsingModeScope BASE_EMBEDDED {
+ public:
+ ParsingModeScope(ParserBase* parser, Mode mode)
+ : parser_(parser),
+ old_mode_(parser->mode()) {
+ parser_->mode_ = mode;
+ }
+ ~ParsingModeScope() {
+ parser_->mode_ = old_mode_;
+ }
+
+ private:
+ ParserBase* parser_;
+ Mode old_mode_;
+ };
+
Scanner* scanner() const { return scanner_; }
int position() { return scanner_->location().beg_pos; }
int peek_position() { return scanner_->peek_location().beg_pos; }
bool stack_overflow() const { return stack_overflow_; }
void set_stack_overflow() { stack_overflow_ = true; }
+ Mode mode() const { return mode_; }
typename Traits::Type::Zone* zone() const { return zone_; }
INLINE(Token::Value peek()) {
@@ -396,6 +419,7 @@
ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
ExpressionT ParseUnaryExpression(bool* ok);
ExpressionT ParsePostfixExpression(bool* ok);
+ ExpressionT ParseLeftHandSideExpression(bool* ok);
// Used to detect duplicates in object literals. Each of the values
// kGetterProperty, kSetterProperty and kValueProperty represents
@@ -462,6 +486,7 @@
v8::Extension* extension_;
FuncNameInferrer* fni_;
ParserRecorder* log_;
+ Mode mode_;
private:
Scanner* scanner_;
@@ -584,18 +609,21 @@
bool IsValidLeftHandSide() {
return IsIdentifier() || IsProperty();
}
+
+ // At the moment PreParser doesn't track these expression types.
+ bool IsFunctionLiteral() const { return false; }
+ bool IsCall() const { return false; }
+ bool IsCallNew() const { return false; }
+
+ PreParserExpression AsFunctionLiteral() { return *this; }
// Dummy implementation for making expression->somefunc() work in both
Parser
// and PreParser.
PreParserExpression* operator->() { return this; }
-
- // These are only used when doing function name inferring, and PreParser
- // doesn't do function name inferring.
- void* AsCall() const { return NULL; }
- void* AsCallNew() const { return NULL; }
// More dummy implementations of things PreParser doesn't need to track:
void set_index(int index) {} // For YieldExpressions
+ void set_parenthesized() {}
private:
// Least significant 2 bits are used as flags. Bits 0 and 1 represent
@@ -673,45 +701,34 @@
class PreParserFactory {
public:
explicit PreParserFactory(void* extra_param) {}
-
+ PreParserExpression NewLiteral(PreParserIdentifier identifier,
+ int pos) {
+ return PreParserExpression::Default();
+ }
+ PreParserExpression NewNumberLiteral(double number,
+ int pos) {
+ return PreParserExpression::Default();
+ }
PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
PreParserIdentifier js_flags,
int literal_index,
int pos) {
return PreParserExpression::Default();
}
- PreParserExpression NewUnaryOperation(Token::Value op,
- PreParserExpression expression,
- int pos) {
- return PreParserExpression::Default();
- }
- PreParserExpression NewBinaryOperation(Token::Value op,
- PreParserExpression left,
- PreParserExpression right, int
pos) {
- return PreParserExpression::Default();
- }
- PreParserExpression NewCompareOperation(Token::Value op,
- PreParserExpression left,
- PreParserExpression right, int
pos) {
- return PreParserExpression::Default();
- }
PreParserExpression NewArrayLiteral(PreParserExpressionList values,
int literal_index,
int pos) {
return PreParserExpression::Default();
}
-
PreParserExpression NewObjectLiteralProperty(bool is_getter,
PreParserExpression value,
int pos) {
return PreParserExpression::Default();
}
-
PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
PreParserExpression value) {
return PreParserExpression::Default();
}
-
PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
int literal_index,
int boilerplate_properties,
@@ -719,48 +736,61 @@
int pos) {
return PreParserExpression::Default();
}
-
- PreParserExpression NewLiteral(PreParserIdentifier identifier,
- int pos) {
+ PreParserExpression NewVariableProxy(void* generator_variable) {
return PreParserExpression::Default();
}
-
- PreParserExpression NewNumberLiteral(double number,
- int pos) {
+ PreParserExpression NewProperty(PreParserExpression obj,
+ PreParserExpression key,
+ int pos) {
+ if (obj.IsThis()) {
+ return PreParserExpression::ThisProperty();
+ }
+ return PreParserExpression::Property();
+ }
+ PreParserExpression NewUnaryOperation(Token::Value op,
+ PreParserExpression expression,
+ int pos) {
+ return PreParserExpression::Default();
+ }
+ PreParserExpression NewBinaryOperation(Token::Value op,
+ PreParserExpression left,
+ PreParserExpression right, int
pos) {
return PreParserExpression::Default();
}
-
+ PreParserExpression NewCompareOperation(Token::Value op,
+ PreParserExpression left,
+ PreParserExpression right, int
pos) {
+ return PreParserExpression::Default();
+ }
PreParserExpression NewAssignment(Token::Value op,
PreParserExpression left,
PreParserExpression right,
int pos) {
return PreParserExpression::Default();
}
-
- PreParserExpression NewVariableProxy(void* generator_variable) {
- return PreParserExpression::Default();
- }
-
PreParserExpression NewYield(PreParserExpression generator_object,
PreParserExpression expression,
Yield::Kind yield_kind,
int pos) {
return PreParserExpression::Default();
}
-
PreParserExpression NewConditional(PreParserExpression condition,
PreParserExpression then_expression,
PreParserExpression else_expression,
int pos) {
return PreParserExpression::Default();
}
-
PreParserExpression NewCountOperation(Token::Value op,
bool is_prefix,
PreParserExpression expression,
int pos) {
return PreParserExpression::Default();
}
+ PreParserExpression NewCall(PreParserExpression expression,
+ PreParserExpressionList arguments,
+ int pos) {
+ return PreParserExpression::Default();
+ }
};
@@ -838,6 +868,10 @@
static void CheckAssigningFunctionLiteralToProperty(
PreParserExpression left, PreParserExpression right) {}
+
+ // PreParser doesn't need to keep track of eval calls.
+ static void CheckPossibleEvalCall(PreParserExpression expression,
+ PreParserScope* scope) {}
static PreParserExpression MarkExpressionAsLValue(
PreParserExpression expression) {
@@ -945,7 +979,7 @@
int function_token_position,
FunctionLiteral::FunctionType type,
bool* ok);
- PreParserExpression ParseLeftHandSideExpression(bool* ok);
+ PreParserExpression ParseMemberWithNewPrefixesExpression(bool* ok);
private:
PreParser* pre_parser_;
@@ -1109,7 +1143,6 @@
Statement ParseTryStatement(bool* ok);
Statement ParseDebuggerStatement(bool* ok);
Expression ParseConditionalExpression(bool accept_IN, bool* ok);
- Expression ParseLeftHandSideExpression(bool* ok);
Expression ParseMemberExpression(bool* ok);
Expression ParseMemberExpressionContinuation(PreParserExpression
expression,
bool* ok);
@@ -1698,7 +1731,7 @@
if ((op == Token::INIT_VAR
|| op == Token::INIT_CONST_LEGACY
|| op == Token::ASSIGN)
- && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
+ && (!right->IsCall() && !right->IsCallNew())) {
fni_->Infer();
} else {
fni_->RemoveLastFunction();
@@ -1888,6 +1921,77 @@
}
return expression;
}
+
+
+template <class Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::ParseLeftHandSideExpression(bool* ok) {
+ // LeftHandSideExpression ::
+ // (NewExpression | MemberExpression) ...
+
+ ExpressionT result =
this->ParseMemberWithNewPrefixesExpression(CHECK_OK);
+
+ while (true) {
+ switch (peek()) {
+ case Token::LBRACK: {
+ Consume(Token::LBRACK);
+ int pos = position();
+ ExpressionT 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();
+ }
+ }
+ typename Traits::Type::ExpressionList 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.
+ this->CheckPossibleEvalCall(result, scope_);
+ result = factory()->NewCall(result, args, pos);
+ if (fni_ != NULL) fni_->RemoveLastFunction();
+ break;
+ }
+
+ case Token::PERIOD: {
+ Consume(Token::PERIOD);
+ int pos = position();
+ IdentifierT name = ParseIdentifierName(CHECK_OK);
+ result = factory()->NewProperty(
+ result, factory()->NewLiteral(name, pos), pos);
+ if (fni_ != NULL) this->PushLiteralName(fni_, name);
+ break;
+ }
+
+ default:
+ return result;
+ }
+ }
+}
#undef CHECK_OK
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.