Index: src/preparser.h |
diff --git a/src/preparser.h b/src/preparser.h |
index 5dd41da7eeecd9bbe2087eb768ec1587b4a8c36f..cbc92da851454a7a173abe51d49ec8c464a06930 100644 |
--- a/src/preparser.h |
+++ b/src/preparser.h |
@@ -32,6 +32,7 @@ |
#include "scopes.h" |
#include "token.h" |
#include "scanner.h" |
+#include "v8.h" |
namespace v8 { |
namespace internal { |
@@ -41,11 +42,13 @@ template <typename Traits> |
class ParserBase : public Traits { |
public: |
ParserBase(Scanner* scanner, uintptr_t stack_limit, |
+ v8::Extension* extension, |
typename Traits::Type::Parser this_object) |
: Traits(this_object), |
parenthesized_function_(false), |
scope_(NULL), |
function_state_(NULL), |
+ extension_(extension), |
scanner_(scanner), |
stack_limit_(stack_limit), |
stack_overflow_(false), |
@@ -329,7 +332,9 @@ class ParserBase : public Traits { |
bool* ok); |
typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, |
- bool* ok); |
+ bool* ok); |
+ |
+ typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); |
// Used to detect duplicates in object literals. Each of the values |
// kGetterProperty, kSetterProperty and kValueProperty represents |
@@ -393,6 +398,7 @@ class ParserBase : public Traits { |
typename Traits::Type::Scope* scope_; // Scope stack. |
FunctionState* function_state_; // Function state stack. |
+ v8::Extension* extension_; |
private: |
Scanner* scanner_; |
@@ -641,11 +647,39 @@ class PreParserTraits { |
} |
// Producing data during the recursive descent. |
- PreParserIdentifier GetSymbol(); |
- static PreParserIdentifier NextLiteralString(PretenureFlag tenured) { |
+ PreParserIdentifier GetSymbol(Scanner* scanner); |
+ static PreParserIdentifier NextLiteralString(Scanner* scanner, |
+ PretenureFlag tenured) { |
return PreParserIdentifier::Default(); |
} |
+ static PreParserExpression ThisExpression(PreParserScope* scope, |
+ PreParserFactory* factory) { |
+ return PreParserExpression::This(); |
+ } |
+ |
+ static PreParserExpression ExpressionFromLiteral( |
+ Token::Value token, int pos, Scanner* scanner, |
+ PreParserFactory* factory) { |
+ return PreParserExpression::Default(); |
+ } |
+ |
+ static PreParserExpression ExpressionFromIdentifier( |
+ PreParserIdentifier name, int pos, PreParserScope* scope, |
+ PreParserFactory* factory) { |
+ return PreParserExpression::FromIdentifier(name); |
+ } |
+ |
+ PreParserExpression ExpressionFromString(int pos, |
+ Scanner* scanner, |
+ PreParserFactory* factory = NULL); |
+ |
+ // Temporary glue; these functions will move to ParserBase. |
+ PreParserExpression ParseArrayLiteral(bool* ok); |
+ PreParserExpression ParseObjectLiteral(bool* ok); |
+ PreParserExpression ParseExpression(bool accept_IN, bool* ok); |
+ PreParserExpression ParseV8Intrinsic(bool* ok); |
+ |
private: |
PreParser* pre_parser_; |
}; |
@@ -676,7 +710,7 @@ class PreParser : public ParserBase<PreParserTraits> { |
PreParser(Scanner* scanner, |
ParserRecorder* log, |
uintptr_t stack_limit) |
- : ParserBase<PreParserTraits>(scanner, stack_limit, this), |
+ : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, this), |
log_(log) {} |
// Pre-parse the program from the character stream; returns true on |
@@ -823,7 +857,6 @@ class PreParser : public ParserBase<PreParserTraits> { |
Expression ParseNewExpression(bool* ok); |
Expression ParseMemberExpression(bool* ok); |
Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok); |
- Expression ParsePrimaryExpression(bool* ok); |
Expression ParseArrayLiteral(bool* ok); |
Expression ParseObjectLiteral(bool* ok); |
Expression ParseV8Intrinsic(bool* ok); |
@@ -922,7 +955,7 @@ typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier( |
bool* ok) { |
Token::Value next = Next(); |
if (next == Token::IDENTIFIER) { |
- typename Traits::Type::Identifier name = this->GetSymbol(); |
+ typename Traits::Type::Identifier name = this->GetSymbol(scanner()); |
if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
!is_classic_mode() && this->IsEvalOrArguments(name)) { |
ReportMessageAt(scanner()->location(), "strict_eval_arguments"); |
@@ -931,7 +964,7 @@ typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier( |
return name; |
} else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD || |
(next == Token::YIELD && !is_generator()))) { |
- return this->GetSymbol(); |
+ return this->GetSymbol(scanner()); |
} else { |
this->ReportUnexpectedToken(next); |
*ok = false; |
@@ -955,7 +988,7 @@ typename Traits::Type::Identifier ParserBase< |
*ok = false; |
return Traits::EmptyIdentifier(); |
} |
- return this->GetSymbol(); |
+ return this->GetSymbol(scanner()); |
} |
@@ -969,7 +1002,7 @@ typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifierName( |
*ok = false; |
return Traits::EmptyIdentifier(); |
} |
- return this->GetSymbol(); |
+ return this->GetSymbol(scanner()); |
} |
@@ -1004,7 +1037,7 @@ ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
int literal_index = function_state_->NextMaterializedLiteralIndex(); |
typename Traits::Type::Identifier js_pattern = |
- this->NextLiteralString(TENURED); |
+ this->NextLiteralString(scanner(), TENURED); |
if (!scanner()->ScanRegExpFlags()) { |
Next(); |
ReportMessageAt(scanner()->location(), "invalid_regexp_flags"); |
@@ -1012,12 +1045,115 @@ ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
return Traits::EmptyExpression(); |
} |
typename Traits::Type::Identifier js_flags = |
- this->NextLiteralString(TENURED); |
+ this->NextLiteralString(scanner(), TENURED); |
Next(); |
return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
} |
+#define CHECK_OK ok); \ |
+ if (!*ok) return this->EmptyExpression(); \ |
+ ((void)0 |
+#define DUMMY ) // to make indentation work |
+#undef DUMMY |
+ |
+template <class Traits> |
+typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression( |
+ bool* ok) { |
+ // PrimaryExpression :: |
+ // 'this' |
+ // 'null' |
+ // 'true' |
+ // 'false' |
+ // Identifier |
+ // Number |
+ // String |
+ // ArrayLiteral |
+ // ObjectLiteral |
+ // RegExpLiteral |
+ // '(' Expression ')' |
+ |
+ int pos = peek_position(); |
+ typename Traits::Type::Expression result = this->EmptyExpression(); |
+ Token::Value token = peek(); |
+ switch (token) { |
+ case Token::THIS: { |
+ Consume(Token::THIS); |
+ result = this->ThisExpression(scope_, factory()); |
+ break; |
+ } |
+ |
+ case Token::NULL_LITERAL: |
+ case Token::TRUE_LITERAL: |
+ case Token::FALSE_LITERAL: |
+ case Token::NUMBER: |
+ Next(); |
+ result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
+ break; |
+ |
+ case Token::IDENTIFIER: |
+ case Token::YIELD: |
+ case Token::FUTURE_STRICT_RESERVED_WORD: { |
+ // Using eval or arguments in this context is OK even in strict mode. |
+ typename Traits::Type::Identifier name = |
+ ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
+ result = |
+ this->ExpressionFromIdentifier(name, pos, scope_, factory()); |
+ break; |
+ } |
+ |
+ case Token::STRING: { |
+ Consume(Token::STRING); |
+ result = this->ExpressionFromString(pos, scanner(), factory()); |
+ break; |
+ } |
+ |
+ case Token::ASSIGN_DIV: |
+ result = this->ParseRegExpLiteral(true, CHECK_OK); |
+ break; |
+ |
+ case Token::DIV: |
+ result = this->ParseRegExpLiteral(false, CHECK_OK); |
+ break; |
+ |
+ case Token::LBRACK: |
+ result = this->ParseArrayLiteral(CHECK_OK); |
+ break; |
+ |
+ case Token::LBRACE: |
+ result = this->ParseObjectLiteral(CHECK_OK); |
+ break; |
+ |
+ case Token::LPAREN: |
+ Consume(Token::LPAREN); |
+ // Heuristically try to detect immediately called functions before |
+ // seeing the call parentheses. |
+ parenthesized_function_ = (peek() == Token::FUNCTION); |
+ result = this->ParseExpression(true, CHECK_OK); |
+ Expect(Token::RPAREN, CHECK_OK); |
+ break; |
+ |
+ case Token::MOD: |
+ if (allow_natives_syntax() || extension_ != NULL) { |
+ result = this->ParseV8Intrinsic(CHECK_OK); |
+ break; |
+ } |
+ // If we're not allowing special syntax we fall-through to the |
+ // default case. |
+ |
+ default: { |
+ Next(); |
+ ReportUnexpectedToken(token); |
+ *ok = false; |
+ } |
+ } |
+ |
+ return result; |
+} |
+ |
+#undef CHECK_OK |
+ |
+ |
template <typename Traits> |
void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( |
Token::Value property, |