Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1045)

Unified Diff: src/preparser.h

Issue 206433003: Move ParseLeftHandSideExpression to ParserBase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: code review Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index 7a92347bc86e6b257b3819bb31a8237ce9346abf..7977fe2fd5362df0639cf01f9d9fd8a95064fe19 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -97,6 +97,7 @@ class ParserBase : public Traits {
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 @@ class ParserBase : public Traits {
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 @@ class ParserBase : public Traits {
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 @@ class ParserBase : public Traits {
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 @@ class ParserBase : public Traits {
v8::Extension* extension_;
FuncNameInferrer* fni_;
ParserRecorder* log_;
+ Mode mode_;
private:
Scanner* scanner_;
@@ -585,17 +610,20 @@ class PreParserExpression {
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,26 +701,18 @@ class PreParserScope {
class PreParserFactory {
public:
explicit PreParserFactory(void* extra_param) {}
-
- 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) {
+ PreParserExpression NewLiteral(PreParserIdentifier identifier,
+ int pos) {
return PreParserExpression::Default();
}
- PreParserExpression NewBinaryOperation(Token::Value op,
- PreParserExpression left,
- PreParserExpression right, int pos) {
+ PreParserExpression NewNumberLiteral(double number,
+ int pos) {
return PreParserExpression::Default();
}
- PreParserExpression NewCompareOperation(Token::Value op,
- PreParserExpression left,
- PreParserExpression right, int pos) {
+ PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
+ PreParserIdentifier js_flags,
+ int literal_index,
+ int pos) {
return PreParserExpression::Default();
}
PreParserExpression NewArrayLiteral(PreParserExpressionList values,
@@ -700,18 +720,15 @@ class PreParserFactory {
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 @@ class PreParserFactory {
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();
+ }
};
@@ -839,6 +869,10 @@ class PreParserTraits {
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) {
// TODO(marja): To be able to produce the same errors, the preparser needs
@@ -945,7 +979,7 @@ class PreParserTraits {
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 @@ class PreParser : public ParserBase<PreParserTraits> {
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 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
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();
@@ -1890,6 +1923,77 @@ ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
}
+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
#undef CHECK_OK_CUSTOM
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698