Index: src/parsing/parser-base.h |
diff --git a/src/parsing/preparser.h b/src/parsing/parser-base.h |
similarity index 74% |
copy from src/parsing/preparser.h |
copy to src/parsing/parser-base.h |
index 7a699670bbdf3b87d01cb465a02ded7cbfdda698..c56b59e99c71cda3e1efa1ffc29241a160ca7ab2 100644 |
--- a/src/parsing/preparser.h |
+++ b/src/parsing/parser-base.h |
@@ -2,8 +2,8 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#ifndef V8_PARSING_PREPARSER_H |
-#define V8_PARSING_PREPARSER_H |
+#ifndef V8_PARSING_PARSER_BASE_H |
+#define V8_PARSING_PARSER_BASE_H |
#include "src/ast/scopes.h" |
#include "src/bailout-reason.h" |
@@ -926,1137 +926,6 @@ class ParserBase : public Traits { |
}; |
-class PreParserIdentifier { |
- public: |
- PreParserIdentifier() : type_(kUnknownIdentifier) {} |
- static PreParserIdentifier Default() { |
- return PreParserIdentifier(kUnknownIdentifier); |
- } |
- static PreParserIdentifier Eval() { |
- return PreParserIdentifier(kEvalIdentifier); |
- } |
- static PreParserIdentifier Arguments() { |
- return PreParserIdentifier(kArgumentsIdentifier); |
- } |
- static PreParserIdentifier Undefined() { |
- return PreParserIdentifier(kUndefinedIdentifier); |
- } |
- static PreParserIdentifier FutureReserved() { |
- return PreParserIdentifier(kFutureReservedIdentifier); |
- } |
- static PreParserIdentifier FutureStrictReserved() { |
- return PreParserIdentifier(kFutureStrictReservedIdentifier); |
- } |
- static PreParserIdentifier Let() { |
- return PreParserIdentifier(kLetIdentifier); |
- } |
- static PreParserIdentifier Static() { |
- return PreParserIdentifier(kStaticIdentifier); |
- } |
- static PreParserIdentifier Yield() { |
- return PreParserIdentifier(kYieldIdentifier); |
- } |
- static PreParserIdentifier Prototype() { |
- return PreParserIdentifier(kPrototypeIdentifier); |
- } |
- static PreParserIdentifier Constructor() { |
- return PreParserIdentifier(kConstructorIdentifier); |
- } |
- bool IsEval() const { return type_ == kEvalIdentifier; } |
- bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
- bool IsEvalOrArguments() const { return IsEval() || IsArguments(); } |
- bool IsUndefined() const { return type_ == kUndefinedIdentifier; } |
- bool IsLet() const { return type_ == kLetIdentifier; } |
- bool IsStatic() const { return type_ == kStaticIdentifier; } |
- bool IsYield() const { return type_ == kYieldIdentifier; } |
- bool IsPrototype() const { return type_ == kPrototypeIdentifier; } |
- bool IsConstructor() const { return type_ == kConstructorIdentifier; } |
- bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } |
- bool IsFutureStrictReserved() const { |
- return type_ == kFutureStrictReservedIdentifier || |
- type_ == kLetIdentifier || type_ == kStaticIdentifier || |
- type_ == kYieldIdentifier; |
- } |
- |
- // Allow identifier->name()[->length()] to work. The preparser |
- // does not need the actual positions/lengths of the identifiers. |
- const PreParserIdentifier* operator->() const { return this; } |
- const PreParserIdentifier raw_name() const { return *this; } |
- |
- int position() const { return 0; } |
- int length() const { return 0; } |
- |
- private: |
- enum Type { |
- kUnknownIdentifier, |
- kFutureReservedIdentifier, |
- kFutureStrictReservedIdentifier, |
- kLetIdentifier, |
- kStaticIdentifier, |
- kYieldIdentifier, |
- kEvalIdentifier, |
- kArgumentsIdentifier, |
- kUndefinedIdentifier, |
- kPrototypeIdentifier, |
- kConstructorIdentifier |
- }; |
- |
- explicit PreParserIdentifier(Type type) : type_(type) {} |
- Type type_; |
- |
- friend class PreParserExpression; |
-}; |
- |
- |
-class PreParserExpression { |
- public: |
- static PreParserExpression Default() { |
- return PreParserExpression(TypeField::encode(kExpression)); |
- } |
- |
- static PreParserExpression Spread(PreParserExpression expression) { |
- return PreParserExpression(TypeField::encode(kSpreadExpression)); |
- } |
- |
- static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
- return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
- IdentifierTypeField::encode(id.type_)); |
- } |
- |
- static PreParserExpression BinaryOperation(PreParserExpression left, |
- Token::Value op, |
- PreParserExpression right) { |
- return PreParserExpression( |
- TypeField::encode(kBinaryOperationExpression) | |
- HasRestField::encode(op == Token::COMMA && |
- right->IsSpreadExpression())); |
- } |
- |
- static PreParserExpression AssignmentPattern() { |
- return PreParserExpression(TypeField::encode(kExpression) | |
- ExpressionTypeField::encode(kAssignmentPattern)); |
- } |
- |
- static PreParserExpression ObjectLiteral() { |
- return PreParserExpression(TypeField::encode(kObjectLiteralExpression)); |
- } |
- |
- static PreParserExpression ArrayLiteral() { |
- return PreParserExpression(TypeField::encode(kArrayLiteralExpression)); |
- } |
- |
- static PreParserExpression StringLiteral() { |
- return PreParserExpression(TypeField::encode(kStringLiteralExpression)); |
- } |
- |
- static PreParserExpression UseStrictStringLiteral() { |
- return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
- IsUseStrictField::encode(true)); |
- } |
- |
- static PreParserExpression UseStrongStringLiteral() { |
- return PreParserExpression(TypeField::encode(kStringLiteralExpression) | |
- IsUseStrongField::encode(true)); |
- } |
- |
- static PreParserExpression This() { |
- return PreParserExpression(TypeField::encode(kExpression) | |
- ExpressionTypeField::encode(kThisExpression)); |
- } |
- |
- static PreParserExpression ThisProperty() { |
- return PreParserExpression( |
- TypeField::encode(kExpression) | |
- ExpressionTypeField::encode(kThisPropertyExpression)); |
- } |
- |
- static PreParserExpression Property() { |
- return PreParserExpression( |
- TypeField::encode(kExpression) | |
- ExpressionTypeField::encode(kPropertyExpression)); |
- } |
- |
- static PreParserExpression Call() { |
- return PreParserExpression(TypeField::encode(kExpression) | |
- ExpressionTypeField::encode(kCallExpression)); |
- } |
- |
- static PreParserExpression SuperCallReference() { |
- return PreParserExpression( |
- TypeField::encode(kExpression) | |
- ExpressionTypeField::encode(kSuperCallReference)); |
- } |
- |
- static PreParserExpression NoTemplateTag() { |
- return PreParserExpression( |
- TypeField::encode(kExpression) | |
- ExpressionTypeField::encode(kNoTemplateTagExpression)); |
- } |
- |
- bool IsIdentifier() const { |
- return TypeField::decode(code_) == kIdentifierExpression; |
- } |
- |
- PreParserIdentifier AsIdentifier() const { |
- DCHECK(IsIdentifier()); |
- return PreParserIdentifier(IdentifierTypeField::decode(code_)); |
- } |
- |
- bool IsAssignmentPattern() const { |
- return TypeField::decode(code_) == kExpression && |
- ExpressionTypeField::decode(code_) == kAssignmentPattern; |
- } |
- |
- bool IsObjectLiteral() const { |
- return TypeField::decode(code_) == kObjectLiteralExpression; |
- } |
- |
- bool IsArrayLiteral() const { |
- return TypeField::decode(code_) == kArrayLiteralExpression; |
- } |
- |
- bool IsStringLiteral() const { |
- return TypeField::decode(code_) == kStringLiteralExpression; |
- } |
- |
- bool IsUseStrictLiteral() const { |
- return TypeField::decode(code_) == kStringLiteralExpression && |
- IsUseStrictField::decode(code_); |
- } |
- |
- bool IsUseStrongLiteral() const { |
- return TypeField::decode(code_) == kStringLiteralExpression && |
- IsUseStrongField::decode(code_); |
- } |
- |
- bool IsThis() const { |
- return TypeField::decode(code_) == kExpression && |
- ExpressionTypeField::decode(code_) == kThisExpression; |
- } |
- |
- bool IsThisProperty() const { |
- return TypeField::decode(code_) == kExpression && |
- ExpressionTypeField::decode(code_) == kThisPropertyExpression; |
- } |
- |
- bool IsProperty() const { |
- return TypeField::decode(code_) == kExpression && |
- (ExpressionTypeField::decode(code_) == kPropertyExpression || |
- ExpressionTypeField::decode(code_) == kThisPropertyExpression); |
- } |
- |
- bool IsCall() const { |
- return TypeField::decode(code_) == kExpression && |
- ExpressionTypeField::decode(code_) == kCallExpression; |
- } |
- |
- bool IsSuperCallReference() const { |
- return TypeField::decode(code_) == kExpression && |
- ExpressionTypeField::decode(code_) == kSuperCallReference; |
- } |
- |
- bool IsValidReferenceExpression() const { |
- return IsIdentifier() || IsProperty(); |
- } |
- |
- // At the moment PreParser doesn't track these expression types. |
- bool IsFunctionLiteral() const { return false; } |
- bool IsCallNew() const { return false; } |
- |
- bool IsNoTemplateTag() const { |
- return TypeField::decode(code_) == kExpression && |
- ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
- } |
- |
- bool IsSpreadExpression() const { |
- return TypeField::decode(code_) == kSpreadExpression; |
- } |
- |
- bool IsArrowFunctionFormalParametersWithRestParameter() const { |
- // Iff the expression classifier has determined that this expression is a |
- // valid arrow fformal parameter list, return true if the formal parameter |
- // list ends with a rest parameter. |
- return IsSpreadExpression() || |
- (IsBinaryOperation() && HasRestField::decode(code_)); |
- } |
- |
- PreParserExpression AsFunctionLiteral() { return *this; } |
- |
- bool IsBinaryOperation() const { |
- return TypeField::decode(code_) == kBinaryOperationExpression; |
- } |
- |
- // Dummy implementation for making expression->somefunc() work in both Parser |
- // and PreParser. |
- PreParserExpression* operator->() { return this; } |
- |
- // More dummy implementations of things PreParser doesn't need to track: |
- void set_index(int index) {} // For YieldExpressions |
- void set_should_eager_compile() {} |
- |
- int position() const { return RelocInfo::kNoPosition; } |
- void set_function_token_position(int position) {} |
- |
- private: |
- enum Type { |
- kExpression, |
- kIdentifierExpression, |
- kStringLiteralExpression, |
- kBinaryOperationExpression, |
- kSpreadExpression, |
- kObjectLiteralExpression, |
- kArrayLiteralExpression |
- }; |
- |
- enum ExpressionType { |
- kThisExpression, |
- kThisPropertyExpression, |
- kPropertyExpression, |
- kCallExpression, |
- kSuperCallReference, |
- kNoTemplateTagExpression, |
- kAssignmentPattern |
- }; |
- |
- explicit PreParserExpression(uint32_t expression_code) |
- : code_(expression_code) {} |
- |
- // The first three bits are for the Type. |
- typedef BitField<Type, 0, 3> TypeField; |
- |
- // The rest of the bits are interpreted depending on the value |
- // of the Type field, so they can share the storage. |
- typedef BitField<ExpressionType, TypeField::kNext, 3> ExpressionTypeField; |
- typedef BitField<bool, TypeField::kNext, 1> IsUseStrictField; |
- typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
- typedef BitField<PreParserIdentifier::Type, TypeField::kNext, 10> |
- IdentifierTypeField; |
- typedef BitField<bool, TypeField::kNext, 1> HasRestField; |
- typedef BitField<bool, TypeField::kNext, 1> HasCoverInitializedNameField; |
- |
- uint32_t code_; |
-}; |
- |
- |
-// The pre-parser doesn't need to build lists of expressions, identifiers, or |
-// the like. |
-template <typename T> |
-class PreParserList { |
- public: |
- // These functions make list->Add(some_expression) work (and do nothing). |
- PreParserList() : length_(0) {} |
- PreParserList* operator->() { return this; } |
- void Add(T, void*) { ++length_; } |
- int length() const { return length_; } |
- private: |
- int length_; |
-}; |
- |
- |
-typedef PreParserList<PreParserExpression> PreParserExpressionList; |
- |
- |
-class PreParserStatement { |
- public: |
- static PreParserStatement Default() { |
- return PreParserStatement(kUnknownStatement); |
- } |
- |
- static PreParserStatement Jump() { |
- return PreParserStatement(kJumpStatement); |
- } |
- |
- static PreParserStatement FunctionDeclaration() { |
- return PreParserStatement(kFunctionDeclaration); |
- } |
- |
- // Creates expression statement from expression. |
- // Preserves being an unparenthesized string literal, possibly |
- // "use strict". |
- static PreParserStatement ExpressionStatement( |
- PreParserExpression expression) { |
- if (expression.IsUseStrictLiteral()) { |
- return PreParserStatement(kUseStrictExpressionStatement); |
- } |
- if (expression.IsUseStrongLiteral()) { |
- return PreParserStatement(kUseStrongExpressionStatement); |
- } |
- if (expression.IsStringLiteral()) { |
- return PreParserStatement(kStringLiteralExpressionStatement); |
- } |
- return Default(); |
- } |
- |
- bool IsStringLiteral() { |
- return code_ == kStringLiteralExpressionStatement; |
- } |
- |
- bool IsUseStrictLiteral() { |
- return code_ == kUseStrictExpressionStatement; |
- } |
- |
- bool IsUseStrongLiteral() { return code_ == kUseStrongExpressionStatement; } |
- |
- bool IsFunctionDeclaration() { |
- return code_ == kFunctionDeclaration; |
- } |
- |
- bool IsJumpStatement() { |
- return code_ == kJumpStatement; |
- } |
- |
- private: |
- enum Type { |
- kUnknownStatement, |
- kJumpStatement, |
- kStringLiteralExpressionStatement, |
- kUseStrictExpressionStatement, |
- kUseStrongExpressionStatement, |
- kFunctionDeclaration |
- }; |
- |
- explicit PreParserStatement(Type code) : code_(code) {} |
- Type code_; |
-}; |
- |
- |
-typedef PreParserList<PreParserStatement> PreParserStatementList; |
- |
- |
-class PreParserFactory { |
- public: |
- explicit PreParserFactory(void* unused_value_factory) {} |
- PreParserExpression NewStringLiteral(PreParserIdentifier identifier, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewNumberLiteral(double number, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, |
- int js_flags, int literal_index, |
- bool is_strong, int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
- int literal_index, |
- bool is_strong, |
- int pos) { |
- return PreParserExpression::ArrayLiteral(); |
- } |
- PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
- int first_spread_index, int literal_index, |
- bool is_strong, int pos) { |
- return PreParserExpression::ArrayLiteral(); |
- } |
- PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
- PreParserExpression value, |
- ObjectLiteralProperty::Kind kind, |
- bool is_static, |
- bool is_computed_name) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
- PreParserExpression value, |
- bool is_static, |
- bool is_computed_name) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
- int literal_index, |
- int boilerplate_properties, |
- bool has_function, |
- bool is_strong, |
- int pos) { |
- return PreParserExpression::ObjectLiteral(); |
- } |
- PreParserExpression NewVariableProxy(void* variable) { |
- return PreParserExpression::Default(); |
- } |
- 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::BinaryOperation(left, op, right); |
- } |
- PreParserExpression NewCompareOperation(Token::Value op, |
- PreParserExpression left, |
- PreParserExpression right, int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewRewritableAssignmentExpression( |
- PreParserExpression expression) { |
- return expression; |
- } |
- PreParserExpression NewAssignment(Token::Value op, |
- PreParserExpression left, |
- PreParserExpression right, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewAssignmentPattern(PreParserExpression pattern, |
- int pos) { |
- DCHECK(pattern->IsObjectLiteral() || pattern->IsArrayLiteral()); |
- return PreParserExpression::AssignmentPattern(); |
- } |
- 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::Call(); |
- } |
- PreParserExpression NewCallNew(PreParserExpression expression, |
- PreParserExpressionList arguments, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewCallRuntime(const AstRawString* name, |
- const Runtime::Function* function, |
- PreParserExpressionList arguments, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserStatement NewReturnStatement(PreParserExpression expression, |
- int pos) { |
- return PreParserStatement::Default(); |
- } |
- PreParserExpression NewFunctionLiteral( |
- PreParserIdentifier name, AstValueFactory* ast_value_factory, |
- Scope* scope, PreParserStatementList body, int materialized_literal_count, |
- int expected_property_count, int parameter_count, |
- FunctionLiteral::ParameterFlag has_duplicate_parameters, |
- FunctionLiteral::FunctionType function_type, |
- FunctionLiteral::IsFunctionFlag is_function, |
- FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind, |
- int position) { |
- return PreParserExpression::Default(); |
- } |
- |
- PreParserExpression NewSpread(PreParserExpression expression, int pos) { |
- return PreParserExpression::Spread(expression); |
- } |
- |
- PreParserExpression NewEmptyParentheses(int pos) { |
- return PreParserExpression::Default(); |
- } |
- |
- // Return the object itself as AstVisitor and implement the needed |
- // dummy method right in this class. |
- PreParserFactory* visitor() { return this; } |
- int* ast_properties() { |
- static int dummy = 42; |
- return &dummy; |
- } |
-}; |
- |
- |
-struct PreParserFormalParameters : FormalParametersBase { |
- explicit PreParserFormalParameters(Scope* scope) |
- : FormalParametersBase(scope) {} |
- int arity = 0; |
- |
- int Arity() const { return arity; } |
- PreParserIdentifier at(int i) { return PreParserIdentifier(); } // Dummy |
-}; |
- |
- |
-class PreParser; |
- |
-class PreParserTraits { |
- public: |
- struct Type { |
- // TODO(marja): To be removed. The Traits object should contain all the data |
- // it needs. |
- typedef PreParser* Parser; |
- |
- // PreParser doesn't need to store generator variables. |
- typedef void GeneratorVariable; |
- |
- typedef int AstProperties; |
- |
- // Return types for traversing functions. |
- typedef PreParserIdentifier Identifier; |
- typedef PreParserExpression Expression; |
- typedef PreParserExpression YieldExpression; |
- typedef PreParserExpression FunctionLiteral; |
- typedef PreParserExpression ClassLiteral; |
- typedef PreParserExpression ObjectLiteralProperty; |
- typedef PreParserExpression Literal; |
- typedef PreParserExpressionList ExpressionList; |
- typedef PreParserExpressionList PropertyList; |
- typedef PreParserIdentifier FormalParameter; |
- typedef PreParserFormalParameters FormalParameters; |
- typedef PreParserStatementList StatementList; |
- |
- // For constructing objects returned by the traversing functions. |
- typedef PreParserFactory Factory; |
- }; |
- |
- explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} |
- |
- // Helper functions for recursive descent. |
- static bool IsEval(PreParserIdentifier identifier) { |
- return identifier.IsEval(); |
- } |
- |
- static bool IsArguments(PreParserIdentifier identifier) { |
- return identifier.IsArguments(); |
- } |
- |
- static bool IsEvalOrArguments(PreParserIdentifier identifier) { |
- return identifier.IsEvalOrArguments(); |
- } |
- |
- static bool IsUndefined(PreParserIdentifier identifier) { |
- return identifier.IsUndefined(); |
- } |
- |
- static bool IsPrototype(PreParserIdentifier identifier) { |
- return identifier.IsPrototype(); |
- } |
- |
- static bool IsConstructor(PreParserIdentifier identifier) { |
- return identifier.IsConstructor(); |
- } |
- |
- // Returns true if the expression is of type "this.foo". |
- static bool IsThisProperty(PreParserExpression expression) { |
- return expression.IsThisProperty(); |
- } |
- |
- static bool IsIdentifier(PreParserExpression expression) { |
- return expression.IsIdentifier(); |
- } |
- |
- static PreParserIdentifier AsIdentifier(PreParserExpression expression) { |
- return expression.AsIdentifier(); |
- } |
- |
- static bool IsFutureStrictReserved(PreParserIdentifier identifier) { |
- return identifier.IsFutureStrictReserved(); |
- } |
- |
- static bool IsBoilerplateProperty(PreParserExpression property) { |
- // PreParser doesn't count boilerplate properties. |
- return false; |
- } |
- |
- static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
- return false; |
- } |
- |
- static PreParserExpression GetPropertyValue(PreParserExpression property) { |
- return PreParserExpression::Default(); |
- } |
- |
- // Functions for encapsulating the differences between parsing and preparsing; |
- // operations interleaved with the recursive descent. |
- static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
- // PreParser should not use FuncNameInferrer. |
- UNREACHABLE(); |
- } |
- |
- static void PushPropertyName(FuncNameInferrer* fni, |
- PreParserExpression expression) { |
- // PreParser should not use FuncNameInferrer. |
- UNREACHABLE(); |
- } |
- |
- static void InferFunctionName(FuncNameInferrer* fni, |
- PreParserExpression expression) { |
- // PreParser should not use FuncNameInferrer. |
- UNREACHABLE(); |
- } |
- |
- static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
- Scope* scope, PreParserExpression property, bool* has_function) {} |
- |
- static void CheckAssigningFunctionLiteralToProperty( |
- PreParserExpression left, PreParserExpression right) {} |
- |
- static void CheckPossibleEvalCall(PreParserExpression expression, |
- Scope* scope) { |
- if (IsIdentifier(expression) && IsEval(AsIdentifier(expression))) { |
- scope->DeclarationScope()->RecordEvalCall(); |
- scope->RecordEvalCall(); |
- } |
- } |
- |
- static PreParserExpression MarkExpressionAsAssigned( |
- PreParserExpression expression) { |
- // TODO(marja): To be able to produce the same errors, the preparser needs |
- // to start tracking which expressions are variables and which are assigned. |
- return expression; |
- } |
- |
- bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, |
- PreParserExpression y, |
- Token::Value op, |
- int pos, |
- PreParserFactory* factory) { |
- return false; |
- } |
- |
- PreParserExpression BuildUnaryExpression(PreParserExpression expression, |
- Token::Value op, int pos, |
- PreParserFactory* factory) { |
- return PreParserExpression::Default(); |
- } |
- |
- PreParserExpression NewThrowReferenceError(MessageTemplate::Template message, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewThrowSyntaxError(MessageTemplate::Template message, |
- Handle<Object> arg, int pos) { |
- return PreParserExpression::Default(); |
- } |
- PreParserExpression NewThrowTypeError(MessageTemplate::Template message, |
- Handle<Object> arg, int pos) { |
- return PreParserExpression::Default(); |
- } |
- |
- // Reporting errors. |
- void ReportMessageAt(Scanner::Location location, |
- MessageTemplate::Template message, |
- const char* arg = NULL, |
- ParseErrorType error_type = kSyntaxError); |
- void ReportMessageAt(int start_pos, int end_pos, |
- MessageTemplate::Template message, |
- const char* arg = NULL, |
- ParseErrorType error_type = kSyntaxError); |
- |
- // "null" return type creators. |
- static PreParserIdentifier EmptyIdentifier() { |
- return PreParserIdentifier::Default(); |
- } |
- static PreParserIdentifier EmptyIdentifierString() { |
- return PreParserIdentifier::Default(); |
- } |
- static PreParserExpression EmptyExpression() { |
- return PreParserExpression::Default(); |
- } |
- static PreParserExpression EmptyLiteral() { |
- return PreParserExpression::Default(); |
- } |
- static PreParserExpression EmptyObjectLiteralProperty() { |
- return PreParserExpression::Default(); |
- } |
- static PreParserExpression EmptyFunctionLiteral() { |
- return PreParserExpression::Default(); |
- } |
- static PreParserExpressionList NullExpressionList() { |
- return PreParserExpressionList(); |
- } |
- |
- // Odd-ball literal creators. |
- static PreParserExpression GetLiteralTheHole(int position, |
- PreParserFactory* factory) { |
- return PreParserExpression::Default(); |
- } |
- |
- // Producing data during the recursive descent. |
- PreParserIdentifier GetSymbol(Scanner* scanner); |
- PreParserIdentifier GetNumberAsSymbol(Scanner* scanner); |
- |
- static PreParserIdentifier GetNextSymbol(Scanner* scanner) { |
- return PreParserIdentifier::Default(); |
- } |
- |
- static PreParserExpression ThisExpression(Scope* scope, |
- PreParserFactory* factory, |
- int pos) { |
- return PreParserExpression::This(); |
- } |
- |
- static PreParserExpression SuperPropertyReference(Scope* scope, |
- PreParserFactory* factory, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- |
- static PreParserExpression SuperCallReference(Scope* scope, |
- PreParserFactory* factory, |
- int pos) { |
- return PreParserExpression::SuperCallReference(); |
- } |
- |
- static PreParserExpression NewTargetExpression(Scope* scope, |
- PreParserFactory* factory, |
- int pos) { |
- return PreParserExpression::Default(); |
- } |
- |
- static PreParserExpression DefaultConstructor(bool call_super, Scope* scope, |
- int pos, int end_pos) { |
- return PreParserExpression::Default(); |
- } |
- |
- static PreParserExpression ExpressionFromLiteral( |
- Token::Value token, int pos, Scanner* scanner, |
- PreParserFactory* factory) { |
- return PreParserExpression::Default(); |
- } |
- |
- static PreParserExpression ExpressionFromIdentifier( |
- PreParserIdentifier name, int start_position, int end_position, |
- Scope* scope, PreParserFactory* factory) { |
- return PreParserExpression::FromIdentifier(name); |
- } |
- |
- PreParserExpression ExpressionFromString(int pos, |
- Scanner* scanner, |
- PreParserFactory* factory = NULL); |
- |
- PreParserExpression GetIterator(PreParserExpression iterable, |
- PreParserFactory* factory, int pos) { |
- return PreParserExpression::Default(); |
- } |
- |
- static PreParserExpressionList NewExpressionList(int size, Zone* zone) { |
- return PreParserExpressionList(); |
- } |
- |
- static PreParserStatementList NewStatementList(int size, Zone* zone) { |
- return PreParserStatementList(); |
- } |
- |
- static PreParserExpressionList NewPropertyList(int size, Zone* zone) { |
- return PreParserExpressionList(); |
- } |
- |
- static void AddParameterInitializationBlock( |
- const PreParserFormalParameters& parameters, |
- PreParserStatementList list, bool* ok) {} |
- |
- V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, |
- int* expected_property_count, bool* ok) { |
- UNREACHABLE(); |
- } |
- |
- V8_INLINE PreParserStatementList ParseEagerFunctionBody( |
- PreParserIdentifier function_name, int pos, |
- const PreParserFormalParameters& parameters, FunctionKind kind, |
- FunctionLiteral::FunctionType function_type, bool* ok); |
- |
- V8_INLINE void ParseArrowFunctionFormalParameterList( |
- PreParserFormalParameters* parameters, |
- PreParserExpression expression, const Scanner::Location& params_loc, |
- Scanner::Location* duplicate_loc, bool* ok); |
- |
- void ReindexLiterals(const PreParserFormalParameters& paramaters) {} |
- |
- struct TemplateLiteralState {}; |
- |
- TemplateLiteralState OpenTemplateLiteral(int pos) { |
- return TemplateLiteralState(); |
- } |
- void AddTemplateSpan(TemplateLiteralState*, bool) {} |
- void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {} |
- PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int, |
- PreParserExpression tag) { |
- if (IsTaggedTemplate(tag)) { |
- // Emulate generation of array literals for tag callsite |
- // 1st is array of cooked strings, second is array of raw strings |
- MaterializeTemplateCallsiteLiterals(); |
- } |
- return EmptyExpression(); |
- } |
- inline void MaterializeTemplateCallsiteLiterals(); |
- PreParserExpression NoTemplateTag() { |
- return PreParserExpression::NoTemplateTag(); |
- } |
- static bool IsTaggedTemplate(const PreParserExpression tag) { |
- return !tag.IsNoTemplateTag(); |
- } |
- |
- void AddFormalParameter(PreParserFormalParameters* parameters, |
- PreParserExpression pattern, |
- PreParserExpression initializer, |
- int initializer_end_position, bool is_rest) { |
- ++parameters->arity; |
- } |
- void DeclareFormalParameter(Scope* scope, PreParserIdentifier parameter, |
- ExpressionClassifier* classifier) { |
- if (!classifier->is_simple_parameter_list()) { |
- scope->SetHasNonSimpleParameters(); |
- } |
- } |
- |
- void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {} |
- |
- // Temporary glue; these functions will move to ParserBase. |
- PreParserExpression ParseV8Intrinsic(bool* ok); |
- V8_INLINE PreParserExpression ParseDoExpression(bool* ok); |
- PreParserExpression ParseFunctionLiteral( |
- PreParserIdentifier name, Scanner::Location function_name_location, |
- FunctionNameValidity function_name_validity, FunctionKind kind, |
- int function_token_position, FunctionLiteral::FunctionType type, |
- FunctionLiteral::ArityRestriction arity_restriction, |
- LanguageMode language_mode, bool* ok); |
- |
- PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
- Scanner::Location class_name_location, |
- bool name_is_strict_reserved, int pos, |
- bool* ok); |
- |
- PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { |
- return list; |
- } |
- |
- inline void MaterializeUnspreadArgumentsLiterals(int count); |
- |
- inline PreParserExpression SpreadCall(PreParserExpression function, |
- PreParserExpressionList args, int pos); |
- |
- inline PreParserExpression SpreadCallNew(PreParserExpression function, |
- PreParserExpressionList args, |
- int pos); |
- |
- inline void RewriteDestructuringAssignments() {} |
- |
- inline void QueueDestructuringAssignmentForRewriting(PreParserExpression) {} |
- |
- private: |
- PreParser* pre_parser_; |
-}; |
- |
- |
-// Preparsing checks a JavaScript program and emits preparse-data that helps |
-// a later parsing to be faster. |
-// See preparse-data-format.h for the data format. |
- |
-// The PreParser checks that the syntax follows the grammar for JavaScript, |
-// and collects some information about the program along the way. |
-// The grammar check is only performed in order to understand the program |
-// sufficiently to deduce some information about it, that can be used |
-// to speed up later parsing. Finding errors is not the goal of pre-parsing, |
-// rather it is to speed up properly written and correct programs. |
-// That means that contextual checks (like a label being declared where |
-// it is used) are generally omitted. |
-class PreParser : public ParserBase<PreParserTraits> { |
- public: |
- typedef PreParserIdentifier Identifier; |
- typedef PreParserExpression Expression; |
- typedef PreParserStatement Statement; |
- |
- enum PreParseResult { |
- kPreParseStackOverflow, |
- kPreParseSuccess |
- }; |
- |
- PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory, |
- ParserRecorder* log, uintptr_t stack_limit) |
- : ParserBase<PreParserTraits>(zone, scanner, stack_limit, NULL, |
- ast_value_factory, log, this) {} |
- |
- // 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. |
- PreParseResult PreParseProgram(int* materialized_literals = 0) { |
- Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
- PreParserFactory factory(NULL); |
- FunctionState top_scope(&function_state_, &scope_, scope, kNormalFunction, |
- &factory); |
- bool ok = true; |
- int start_position = scanner()->peek_location().beg_pos; |
- ParseStatementList(Token::EOS, &ok); |
- if (stack_overflow()) return kPreParseStackOverflow; |
- if (!ok) { |
- ReportUnexpectedToken(scanner()->current_token()); |
- } else if (is_strict(scope_->language_mode())) { |
- CheckStrictOctalLiteral(start_position, scanner()->location().end_pos, |
- &ok); |
- } |
- if (materialized_literals) { |
- *materialized_literals = function_state_->materialized_literal_count(); |
- } |
- return kPreParseSuccess; |
- } |
- |
- // Parses a single function literal, from the opening parentheses before |
- // parameters to the closing brace after the body. |
- // Returns a FunctionEntry describing the body of the function in enough |
- // detail that it can be lazily compiled. |
- // The scanner is expected to have matched the "function" or "function*" |
- // keyword and parameters, and have consumed the initial '{'. |
- // At return, unless an error occurred, the scanner is positioned before the |
- // the final '}'. |
- PreParseResult PreParseLazyFunction( |
- LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters, |
- ParserRecorder* log, Scanner::BookmarkScope* bookmark = nullptr); |
- |
- private: |
- friend class PreParserTraits; |
- |
- static const int kLazyParseTrialLimit = 200; |
- |
- // These types form an algebra over syntactic categories that is just |
- // rich enough to let us recognize and propagate the constructs that |
- // are either being counted in the preparser data, or is important |
- // to throw the correct syntax error exceptions. |
- |
- // All ParseXXX functions take as the last argument an *ok parameter |
- // which is set to false if parsing failed; it is unchanged otherwise. |
- // By making the 'exception handling' explicit, we are forced to check |
- // for failure at the call sites. |
- Statement ParseStatementListItem(bool* ok); |
- void ParseStatementList(int end_token, bool* ok, |
- Scanner::BookmarkScope* bookmark = nullptr); |
- Statement ParseStatement(bool* ok); |
- Statement ParseSubStatement(bool* ok); |
- Statement ParseFunctionDeclaration(bool* ok); |
- Statement ParseClassDeclaration(bool* ok); |
- Statement ParseBlock(bool* ok); |
- Statement ParseVariableStatement(VariableDeclarationContext var_context, |
- bool* ok); |
- Statement ParseVariableDeclarations(VariableDeclarationContext var_context, |
- int* num_decl, bool* is_lexical, |
- bool* is_binding_pattern, |
- Scanner::Location* first_initializer_loc, |
- Scanner::Location* bindings_loc, |
- bool* ok); |
- Statement ParseExpressionOrLabelledStatement(bool* ok); |
- Statement ParseIfStatement(bool* ok); |
- Statement ParseContinueStatement(bool* ok); |
- Statement ParseBreakStatement(bool* ok); |
- Statement ParseReturnStatement(bool* ok); |
- Statement ParseWithStatement(bool* ok); |
- Statement ParseSwitchStatement(bool* ok); |
- Statement ParseDoWhileStatement(bool* ok); |
- Statement ParseWhileStatement(bool* ok); |
- Statement ParseForStatement(bool* ok); |
- Statement ParseThrowStatement(bool* ok); |
- Statement ParseTryStatement(bool* ok); |
- Statement ParseDebuggerStatement(bool* ok); |
- Expression ParseConditionalExpression(bool accept_IN, bool* ok); |
- Expression ParseObjectLiteral(bool* ok); |
- Expression ParseV8Intrinsic(bool* ok); |
- Expression ParseDoExpression(bool* ok); |
- |
- V8_INLINE void SkipLazyFunctionBody(int* materialized_literal_count, |
- int* expected_property_count, bool* ok); |
- V8_INLINE PreParserStatementList ParseEagerFunctionBody( |
- PreParserIdentifier function_name, int pos, |
- const PreParserFormalParameters& parameters, FunctionKind kind, |
- FunctionLiteral::FunctionType function_type, bool* ok); |
- |
- Expression ParseFunctionLiteral( |
- Identifier name, Scanner::Location function_name_location, |
- FunctionNameValidity function_name_validity, FunctionKind kind, |
- int function_token_pos, FunctionLiteral::FunctionType function_type, |
- FunctionLiteral::ArityRestriction arity_restriction, |
- LanguageMode language_mode, bool* ok); |
- void ParseLazyFunctionLiteralBody(bool* ok, |
- Scanner::BookmarkScope* bookmark = nullptr); |
- |
- PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
- Scanner::Location class_name_location, |
- bool name_is_strict_reserved, int pos, |
- bool* ok); |
-}; |
- |
- |
-void PreParserTraits::MaterializeTemplateCallsiteLiterals() { |
- pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
- pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
-} |
- |
- |
-void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { |
- for (int i = 0; i < count; ++i) { |
- pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
- } |
-} |
- |
- |
-PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, |
- PreParserExpressionList args, |
- int pos) { |
- return pre_parser_->factory()->NewCall(function, args, pos); |
-} |
- |
-PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
- PreParserExpressionList args, |
- int pos) { |
- return pre_parser_->factory()->NewCallNew(function, args, pos); |
-} |
- |
- |
-void PreParserTraits::ParseArrowFunctionFormalParameterList( |
- PreParserFormalParameters* parameters, |
- PreParserExpression params, const Scanner::Location& params_loc, |
- Scanner::Location* duplicate_loc, bool* ok) { |
- // TODO(wingo): Detect duplicated identifiers in paramlists. Detect parameter |
- // lists that are too long. |
- |
- // Accomodate array literal for rest parameter. |
- if (params.IsArrowFunctionFormalParametersWithRestParameter()) { |
- ++parameters->materialized_literals_count; |
- pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
- } |
-} |
- |
- |
-PreParserExpression PreParserTraits::ParseDoExpression(bool* ok) { |
- return pre_parser_->ParseDoExpression(ok); |
-} |
- |
- |
-PreParserStatementList PreParser::ParseEagerFunctionBody( |
- PreParserIdentifier function_name, int pos, |
- const PreParserFormalParameters& parameters, FunctionKind kind, |
- FunctionLiteral::FunctionType function_type, bool* ok) { |
- ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
- |
- ParseStatementList(Token::RBRACE, ok); |
- if (!*ok) return PreParserStatementList(); |
- |
- Expect(Token::RBRACE, ok); |
- return PreParserStatementList(); |
-} |
- |
- |
-PreParserStatementList PreParserTraits::ParseEagerFunctionBody( |
- PreParserIdentifier function_name, int pos, |
- const PreParserFormalParameters& parameters, FunctionKind kind, |
- FunctionLiteral::FunctionType function_type, bool* ok) { |
- return pre_parser_->ParseEagerFunctionBody(function_name, pos, parameters, |
- kind, function_type, ok); |
-} |
- |
- |
template <class Traits> |
ParserBase<Traits>::FunctionState::FunctionState( |
FunctionState** function_state_stack, Scope** scope_stack, Scope* scope, |
@@ -4489,4 +3358,4 @@ void ParserBase<Traits>::ClassLiteralChecker::CheckProperty( |
} // namespace internal |
} // namespace v8 |
-#endif // V8_PARSING_PREPARSER_H |
+#endif // V8_PARSING_PARSER_BASE_H |