| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index b783d65db32468c6395a76ecd046399cd6d851c6..893b575198bf0cf0cdd775d458ca310d1cddae76 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -46,56 +46,24 @@ namespace preparser {
|
|
|
| namespace i = v8::internal;
|
|
|
| -enum StatementType {
|
| - kUnknownStatement
|
| -};
|
| -
|
| -enum ExpressionType {
|
| - kUnknownExpression,
|
| - kIdentifierExpression, // Used to detect labels.
|
| - kThisExpression,
|
| - kThisPropertyExpression
|
| -};
|
| -
|
| -enum IdentifierType {
|
| - kUnknownIdentifier
|
| -};
|
| -
|
| -enum SourceElementTypes {
|
| - kUnknownSourceElements
|
| -};
|
| -
|
| -
|
| -typedef int SourceElements;
|
| -typedef int Expression;
|
| -typedef int Statement;
|
| -typedef int Identifier;
|
| -typedef int Arguments;
|
| -
|
| -
|
| class PreParser {
|
| public:
|
| - PreParser() : scope_(NULL), allow_lazy_(true) { }
|
| + enum PreParseResult {
|
| + kPreParseStackOverflow,
|
| + kPreParseSuccess
|
| + };
|
| +
|
| ~PreParser() { }
|
|
|
| // Pre-parse the program from the character stream; returns true on
|
| // success (even if parsing failed, the pre-parse data successfully
|
| // captured the syntax error), and false if a stack-overflow happened
|
| // during parsing.
|
| - bool PreParseProgram(i::JavaScriptScanner* scanner,
|
| - i::ParserRecorder* log,
|
| - bool allow_lazy) {
|
| - allow_lazy_ = allow_lazy;
|
| - scanner_ = scanner;
|
| - log_ = log;
|
| - Scope top_scope(&scope_, kTopLevelScope);
|
| - bool ok = true;
|
| - ParseSourceElements(i::Token::EOS, &ok);
|
| - bool stack_overflow = scanner_->stack_overflow();
|
| - if (!ok && !stack_overflow) {
|
| - ReportUnexpectedToken(scanner_->current_token());
|
| - }
|
| - return !stack_overflow;
|
| + static PreParseResult PreParseProgram(i::JavaScriptScanner* scanner,
|
| + i::ParserRecorder* log,
|
| + bool allow_lazy,
|
| + uintptr_t stack_limit) {
|
| + return PreParser(scanner, log, stack_limit, allow_lazy).PreParse();
|
| }
|
|
|
| private:
|
| @@ -104,6 +72,38 @@ class PreParser {
|
| kFunctionScope
|
| };
|
|
|
| + // Types that allow us to recognize simple this-property assignments.
|
| + // A simple this-property assignment is a statement on the form
|
| + // "this.propertyName = {primitive constant or function parameter name);"
|
| + // where propertyName isn't "__proto__".
|
| + // The result is only relevant if the function body contains only
|
| + // simple this-property assignments.
|
| +
|
| + enum StatementType {
|
| + kUnknownStatement
|
| + };
|
| +
|
| + enum ExpressionType {
|
| + kUnknownExpression,
|
| + kIdentifierExpression, // Used to detect labels.
|
| + kThisExpression,
|
| + kThisPropertyExpression
|
| + };
|
| +
|
| + enum IdentifierType {
|
| + kUnknownIdentifier
|
| + };
|
| +
|
| + enum SourceElementTypes {
|
| + kUnknownSourceElements
|
| + };
|
| +
|
| + typedef int SourceElements;
|
| + typedef int Expression;
|
| + typedef int Statement;
|
| + typedef int Identifier;
|
| + typedef int Arguments;
|
| +
|
| class Scope {
|
| public:
|
| Scope(Scope** variable, ScopeType type)
|
| @@ -134,12 +134,30 @@ class PreParser {
|
| int with_nesting_count_;
|
| };
|
|
|
| - // Types that allow us to recognize simple this-property assignments.
|
| - // A simple this-property assignment is a statement on the form
|
| - // "this.propertyName = {primitive constant or function parameter name);"
|
| - // where propertyName isn't "__proto__".
|
| - // The result is only relevant if the function body contains only
|
| - // simple this-property assignments.
|
| + // Private constructor only used in PreParseProgram.
|
| + PreParser(i::JavaScriptScanner* scanner,
|
| + i::ParserRecorder* log,
|
| + uintptr_t stack_limit,
|
| + bool allow_lazy)
|
| + : scanner_(scanner),
|
| + log_(log),
|
| + scope_(NULL),
|
| + stack_limit_(stack_limit),
|
| + stack_overflow_(false),
|
| + allow_lazy_(true) { }
|
| +
|
| + // Preparse the program. Only called in PreParseProgram after creating
|
| + // the instance.
|
| + PreParseResult PreParse() {
|
| + Scope top_scope(&scope_, kTopLevelScope);
|
| + bool ok = true;
|
| + ParseSourceElements(i::Token::EOS, &ok);
|
| + if (stack_overflow_) return kPreParseStackOverflow;
|
| + if (!ok) {
|
| + ReportUnexpectedToken(scanner_->current_token());
|
| + }
|
| + return kPreParseSuccess;
|
| + }
|
|
|
| // Report syntax error
|
| void ReportUnexpectedToken(i::Token::Value token);
|
| @@ -202,16 +220,26 @@ class PreParser {
|
| unsigned int HexDigitValue(char digit);
|
| Expression GetStringSymbol();
|
|
|
| + i::Token::Value peek() {
|
| + if (stack_overflow_) return i::Token::ILLEGAL;
|
| + return scanner_->peek();
|
| + }
|
|
|
| - i::Token::Value peek() { return scanner_->peek(); }
|
| i::Token::Value Next() {
|
| - i::Token::Value next = scanner_->Next();
|
| - return next;
|
| + if (stack_overflow_) return i::Token::ILLEGAL;
|
| + {
|
| + int marker;
|
| + if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
|
| + // Further calls to peek/Next will return illegal token.
|
| + // The current one will still be returned. It might already
|
| + // have been seen using peek.
|
| + stack_overflow_ = true;
|
| + }
|
| + }
|
| + return scanner_->Next();
|
| }
|
|
|
| - void Consume(i::Token::Value token) {
|
| - Next();
|
| - }
|
| + void Consume(i::Token::Value token) { Next(); }
|
|
|
| void Expect(i::Token::Value token, bool* ok) {
|
| if (Next() != token) {
|
| @@ -234,6 +262,8 @@ class PreParser {
|
| i::JavaScriptScanner* scanner_;
|
| i::ParserRecorder* log_;
|
| Scope* scope_;
|
| + uintptr_t stack_limit_;
|
| + bool stack_overflow_;
|
| bool allow_lazy_;
|
| };
|
| } } // v8::preparser
|
|
|