// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_PARSING_PARSER_H_ #define V8_PARSING_PARSER_H_ #include #include "src/ast/ast-source-ranges.h" #include "src/ast/ast.h" #include "src/ast/scopes.h" #include "src/base/compiler-specific.h" #include "src/base/threaded-list.h" #include "src/common/globals.h" #include "src/parsing/parser-base.h" #include "src/parsing/parsing.h" #include "src/parsing/preparser.h" #include "src/utils/pointer-with-payload.h" #include "src/zone/zone-chunk-list.h" namespace v8 { class ScriptCompiler; namespace internal { class ConsumedPreparseData; class ParseInfo; class ParserTarget; class ParserTargetScope; class PendingCompilationErrorHandler; class PreparseData; // ---------------------------------------------------------------------------- // JAVASCRIPT PARSING class Parser; struct ParserFormalParameters : FormalParametersBase { struct Parameter : public ZoneObject { Parameter(Expression* pattern, Expression* initializer, int position, int initializer_end_position, bool is_rest) : initializer_and_is_rest(initializer, is_rest), pattern(pattern), position(position), initializer_end_position(initializer_end_position) {} PointerWithPayload initializer_and_is_rest; Expression* pattern; Expression* initializer() const { return initializer_and_is_rest.GetPointer(); } int position; int initializer_end_position; inline bool is_rest() const { return initializer_and_is_rest.GetPayload(); } Parameter* next_parameter = nullptr; bool is_simple() const { return pattern->IsVariableProxy() && initializer() == nullptr && !is_rest(); } const AstRawString* name() const { DCHECK(is_simple()); return pattern->AsVariableProxy()->raw_name(); } Parameter** next() { return &next_parameter; } Parameter* const* next() const { return &next_parameter; } }; void set_strict_parameter_error(const Scanner::Location& loc, MessageTemplate message) { strict_error_loc = loc; strict_error_message = message; } bool has_duplicate() const { return duplicate_loc.IsValid(); } void ValidateDuplicate(Parser* parser) const; void ValidateStrictMode(Parser* parser) const; explicit ParserFormalParameters(DeclarationScope* scope) : FormalParametersBase(scope) {} base::ThreadedList params; Scanner::Location duplicate_loc = Scanner::Location::invalid(); Scanner::Location strict_error_loc = Scanner::Location::invalid(); MessageTemplate strict_error_message = MessageTemplate::kNone; }; template <> struct ParserTypes { using Base = ParserBase; using Impl = Parser; // Return types for traversing functions. using Block = v8::internal::Block*; using BreakableStatement = v8::internal::BreakableStatement*; using ClassLiteralProperty = ClassLiteral::Property*; using ClassPropertyList = ZonePtrList*; using Expression = v8::internal::Expression*; using ExpressionList = ScopedPtrList; using FormalParameters = ParserFormalParameters; using ForStatement = v8::internal::ForStatement*; using FunctionLiteral = v8::internal::FunctionLiteral*; using Identifier = const AstRawString*; using IterationStatement = v8::internal::IterationStatement*; using ObjectLiteralProperty = ObjectLiteral::Property*; using ObjectPropertyList = ScopedPtrList; using Statement = v8::internal::Statement*; using StatementList = ScopedPtrList; using Suspend = v8::internal::Suspend*; // For constructing objects returned by the traversing functions. using Factory = AstNodeFactory; // Other implementation-specific functions. using FuncNameInferrer = v8::internal::FuncNameInferrer; using SourceRange = v8::internal::SourceRange; using SourceRangeScope = v8::internal::SourceRangeScope; using Target = ParserTarget; using TargetScope = ParserTargetScope; }; class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase) { public: explicit Parser(ParseInfo* info); ~Parser() { delete reusable_preparser_; reusable_preparser_ = nullptr; } static bool IsPreParser() { return false; } void ParseOnBackground(ParseInfo* info); // Initializes an empty scope chain for top-level scripts, or scopes which // consist of only the native context. void InitializeEmptyScopeChain(ParseInfo* info); // Deserialize the scope chain prior to parsing in which the script is going // to be executed. If the script is a top-level script, or the scope chain // consists of only a native context, maybe_outer_scope_info should be an // empty handle. // // This only deserializes the scope chain, but doesn't connect the scopes to // their corresponding scope infos. Therefore, looking up variables in the // deserialized scopes is not possible. void DeserializeScopeChain(Isolate* isolate, ParseInfo* info, MaybeHandle maybe_outer_scope_info, Scope::DeserializationMode mode = Scope::DeserializationMode::kScopesOnly); // Move statistics to Isolate void UpdateStatistics(Isolate* isolate, Handle