• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_PARSING_PARSER_H_
6 #define V8_PARSING_PARSER_H_
7 
8 #include <cstddef>
9 
10 #include "src/ast/ast-source-ranges.h"
11 #include "src/ast/ast-value-factory.h"
12 #include "src/ast/ast.h"
13 #include "src/ast/scopes.h"
14 #include "src/base/compiler-specific.h"
15 #include "src/base/pointer-with-payload.h"
16 #include "src/base/small-vector.h"
17 #include "src/base/threaded-list.h"
18 #include "src/common/globals.h"
19 #include "src/parsing/import-assertions.h"
20 #include "src/parsing/parse-info.h"
21 #include "src/parsing/parser-base.h"
22 #include "src/parsing/parsing.h"
23 #include "src/parsing/preparser.h"
24 #include "src/zone/zone-chunk-list.h"
25 
26 namespace v8 {
27 
28 class ScriptCompiler;
29 
30 namespace internal {
31 
32 class ConsumedPreparseData;
33 class ParseInfo;
34 class ParserTarget;
35 class ParserTargetScope;
36 class PendingCompilationErrorHandler;
37 class PreparseData;
38 
39 // ----------------------------------------------------------------------------
40 // JAVASCRIPT PARSING
41 
42 class Parser;
43 
44 
45 struct ParserFormalParameters : FormalParametersBase {
46   struct Parameter : public ZoneObject {
ParameterParserFormalParameters::Parameter47     Parameter(Expression* pattern, Expression* initializer, int position,
48               int initializer_end_position, bool is_rest)
49         : initializer_and_is_rest(initializer, is_rest),
50           pattern(pattern),
51           position(position),
52           initializer_end_position(initializer_end_position) {}
53 
54     base::PointerWithPayload<Expression, bool, 1> initializer_and_is_rest;
55 
56     Expression* pattern;
initializerParserFormalParameters::Parameter57     Expression* initializer() const {
58       return initializer_and_is_rest.GetPointer();
59     }
60     int position;
61     int initializer_end_position;
is_restParserFormalParameters::Parameter62     inline bool is_rest() const { return initializer_and_is_rest.GetPayload(); }
63 
64     Parameter* next_parameter = nullptr;
is_simpleParserFormalParameters::Parameter65     bool is_simple() const {
66       return pattern->IsVariableProxy() && initializer() == nullptr &&
67              !is_rest();
68     }
69 
nameParserFormalParameters::Parameter70     const AstRawString* name() const {
71       DCHECK(is_simple());
72       return pattern->AsVariableProxy()->raw_name();
73     }
74 
nextParserFormalParameters::Parameter75     Parameter** next() { return &next_parameter; }
nextParserFormalParameters::Parameter76     Parameter* const* next() const { return &next_parameter; }
77   };
78 
set_strict_parameter_errorParserFormalParameters79   void set_strict_parameter_error(const Scanner::Location& loc,
80                                   MessageTemplate message) {
81     strict_error_loc = loc;
82     strict_error_message = message;
83   }
84 
has_duplicateParserFormalParameters85   bool has_duplicate() const { return duplicate_loc.IsValid(); }
86   void ValidateDuplicate(Parser* parser) const;
87   void ValidateStrictMode(Parser* parser) const;
88 
ParserFormalParametersParserFormalParameters89   explicit ParserFormalParameters(DeclarationScope* scope)
90       : FormalParametersBase(scope) {}
91 
92   base::ThreadedList<Parameter> params;
93   Scanner::Location duplicate_loc = Scanner::Location::invalid();
94   Scanner::Location strict_error_loc = Scanner::Location::invalid();
95   MessageTemplate strict_error_message = MessageTemplate::kNone;
96 };
97 
98 template <>
99 struct ParserTypes<Parser> {
100   using Base = ParserBase<Parser>;
101   using Impl = Parser;
102 
103   // Return types for traversing functions.
104   using Block = v8::internal::Block*;
105   using BreakableStatement = v8::internal::BreakableStatement*;
106   using ClassLiteralProperty = ClassLiteral::Property*;
107   using ClassLiteralStaticElement = ClassLiteral::StaticElement*;
108   using ClassPropertyList = ZonePtrList<ClassLiteral::Property>*;
109   using ClassStaticElementList = ZonePtrList<ClassLiteral::StaticElement>*;
110   using Expression = v8::internal::Expression*;
111   using ExpressionList = ScopedPtrList<v8::internal::Expression>;
112   using FormalParameters = ParserFormalParameters;
113   using ForStatement = v8::internal::ForStatement*;
114   using FunctionLiteral = v8::internal::FunctionLiteral*;
115   using Identifier = const AstRawString*;
116   using IterationStatement = v8::internal::IterationStatement*;
117   using ObjectLiteralProperty = ObjectLiteral::Property*;
118   using ObjectPropertyList = ScopedPtrList<v8::internal::ObjectLiteralProperty>;
119   using Statement = v8::internal::Statement*;
120   using StatementList = ScopedPtrList<v8::internal::Statement>;
121   using Suspend = v8::internal::Suspend*;
122 
123   // For constructing objects returned by the traversing functions.
124   using Factory = AstNodeFactory;
125 
126   // Other implementation-specific functions.
127   using FuncNameInferrer = v8::internal::FuncNameInferrer;
128   using SourceRange = v8::internal::SourceRange;
129   using SourceRangeScope = v8::internal::SourceRangeScope;
130 };
131 
132 class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
133  public:
134   Parser(LocalIsolate* local_isolate, ParseInfo* info, Handle<Script> script);
135   ~Parser() {
136     delete reusable_preparser_;
137     reusable_preparser_ = nullptr;
138   }
139 
140   static bool IsPreParser() { return false; }
141 
142   // Sets the literal on |info| if parsing succeeded.
143   void ParseOnBackground(LocalIsolate* isolate, ParseInfo* info,
144                          int start_position, int end_position,
145                          int function_literal_id);
146 
147   // Initializes an empty scope chain for top-level scripts, or scopes which
148   // consist of only the native context.
149   void InitializeEmptyScopeChain(ParseInfo* info);
150 
151   // Deserialize the scope chain prior to parsing in which the script is going
152   // to be executed. If the script is a top-level script, or the scope chain
153   // consists of only a native context, maybe_outer_scope_info should be an
154   // empty handle.
155   //
156   // This only deserializes the scope chain, but doesn't connect the scopes to
157   // their corresponding scope infos. Therefore, looking up variables in the
158   // deserialized scopes is not possible.
159   template <typename IsolateT>
160   void DeserializeScopeChain(IsolateT* isolate, ParseInfo* info,
161                              MaybeHandle<ScopeInfo> maybe_outer_scope_info,
162                              Scope::DeserializationMode mode =
163                                  Scope::DeserializationMode::kScopesOnly);
164 
165   // Move statistics to Isolate
166   void UpdateStatistics(Isolate* isolate, Handle<Script> script);
167   void UpdateStatistics(
168       Handle<Script> script,
169       base::SmallVector<v8::Isolate::UseCounterFeature, 8>* use_counters,
170       int* preparse_skipped);
171   template <typename IsolateT>
172   void HandleSourceURLComments(IsolateT* isolate, Handle<Script> script);
173 
174  private:
175   friend class ParserBase<Parser>;
176   friend struct ParserFormalParameters;
177   friend class i::ExpressionScope<ParserTypes<Parser>>;
178   friend class i::VariableDeclarationParsingScope<ParserTypes<Parser>>;
179   friend class i::ParameterDeclarationParsingScope<ParserTypes<Parser>>;
180   friend class i::ArrowHeadParsingScope<ParserTypes<Parser>>;
181   friend bool v8::internal::parsing::ParseProgram(
182       ParseInfo*, Handle<Script>, MaybeHandle<ScopeInfo> maybe_outer_scope_info,
183       Isolate*, parsing::ReportStatisticsMode stats_mode);
184   friend bool v8::internal::parsing::ParseFunction(
185       ParseInfo*, Handle<SharedFunctionInfo> shared_info, Isolate*,
186       parsing::ReportStatisticsMode stats_mode);
187 
188   bool AllowsLazyParsingWithoutUnresolvedVariables() const {
189     return !MaybeParsingArrowhead() &&
190            scope()->AllowsLazyParsingWithoutUnresolvedVariables(
191                original_scope_);
192   }
193 
194   bool parse_lazily() const { return mode_ == PARSE_LAZILY; }
195   enum Mode { PARSE_LAZILY, PARSE_EAGERLY };
196 
197   class V8_NODISCARD ParsingModeScope {
198    public:
199     ParsingModeScope(Parser* parser, Mode mode)
200         : parser_(parser), old_mode_(parser->mode_) {
201       parser_->mode_ = mode;
202     }
203     ~ParsingModeScope() { parser_->mode_ = old_mode_; }
204 
205    private:
206     Parser* parser_;
207     Mode old_mode_;
208   };
209 
210   // Runtime encoding of different completion modes.
211   enum CompletionKind {
212     kNormalCompletion,
213     kThrowCompletion,
214     kAbruptCompletion
215   };
216 
217   Variable* NewTemporary(const AstRawString* name) {
218     return scope()->NewTemporary(name);
219   }
220 
221   void PrepareGeneratorVariables();
222 
223   // Sets the literal on |info| if parsing succeeded.
224   void ParseProgram(Isolate* isolate, Handle<Script> script, ParseInfo* info,
225                     MaybeHandle<ScopeInfo> maybe_outer_scope_info);
226 
227   // Sets the literal on |info| if parsing succeeded.
228   void ParseFunction(Isolate* isolate, ParseInfo* info,
229                      Handle<SharedFunctionInfo> shared_info);
230 
231   template <typename IsolateT>
232   void PostProcessParseResult(IsolateT* isolate, ParseInfo* info,
233                               FunctionLiteral* literal);
234 
235   FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info,
236                                    int start_position, int end_position,
237                                    int function_literal_id,
238                                    const AstRawString* raw_name);
239 
240   FunctionLiteral* DoParseDeserializedFunction(
241       Isolate* isolate, MaybeHandle<ScopeInfo> maybe_outer_scope_info,
242       ParseInfo* info, int start_position, int end_position,
243       int function_literal_id, const AstRawString* raw_name);
244 
245   FunctionLiteral* ParseClassForInstanceMemberInitialization(
246       Isolate* isolate, MaybeHandle<ScopeInfo> maybe_class_scope_info,
247       int initializer_pos, int initializer_id, int initializer_end_pos);
248 
249   // Called by ParseProgram after setting up the scanner.
250   FunctionLiteral* DoParseProgram(Isolate* isolate, ParseInfo* info);
251 
252   // Parse with the script as if the source is implicitly wrapped in a function.
253   // We manually construct the AST and scopes for a top-level function and the
254   // function wrapper.
255   void ParseWrapped(Isolate* isolate, ParseInfo* info,
256                     ScopedPtrList<Statement>* body, DeclarationScope* scope,
257                     Zone* zone);
258 
259   void ParseREPLProgram(ParseInfo* info, ScopedPtrList<Statement>* body,
260                         DeclarationScope* scope);
261   Expression* WrapREPLResult(Expression* value);
262 
263   ZonePtrList<const AstRawString>* PrepareWrappedArguments(Isolate* isolate,
264                                                            ParseInfo* info,
265                                                            Zone* zone);
266 
267   PreParser* reusable_preparser() {
268     if (reusable_preparser_ == nullptr) {
269       reusable_preparser_ = new PreParser(
270           &preparser_zone_, &scanner_, stack_limit_, ast_value_factory(),
271           pending_error_handler(), runtime_call_stats_, logger_, flags(),
272           parsing_on_main_thread_);
273       reusable_preparser_->set_allow_eval_cache(allow_eval_cache());
274       preparse_data_buffer_.reserve(128);
275     }
276     return reusable_preparser_;
277   }
278 
279   void ParseModuleItemList(ScopedPtrList<Statement>* body);
280   Statement* ParseModuleItem();
281   const AstRawString* ParseModuleSpecifier();
282   void ParseImportDeclaration();
283   Statement* ParseExportDeclaration();
284   Statement* ParseExportDefault();
285   void ParseExportStar();
286   struct ExportClauseData {
287     const AstRawString* export_name;
288     const AstRawString* local_name;
289     Scanner::Location location;
290   };
291   ZoneChunkList<ExportClauseData>* ParseExportClause(
292       Scanner::Location* reserved_loc,
293       Scanner::Location* string_literal_local_name_loc);
294   struct NamedImport : public ZoneObject {
295     const AstRawString* import_name;
296     const AstRawString* local_name;
297     const Scanner::Location location;
298     NamedImport(const AstRawString* import_name, const AstRawString* local_name,
299                 Scanner::Location location)
300         : import_name(import_name),
301           local_name(local_name),
302           location(location) {}
303   };
304   const AstRawString* ParseExportSpecifierName();
305   ZonePtrList<const NamedImport>* ParseNamedImports(int pos);
306 
307   ImportAssertions* ParseImportAssertClause();
308   Statement* BuildInitializationBlock(DeclarationParsingResult* parsing_result);
309   Expression* RewriteReturn(Expression* return_value, int pos);
310   Statement* RewriteSwitchStatement(SwitchStatement* switch_statement,
311                                     Scope* scope);
312   Block* RewriteCatchPattern(CatchInfo* catch_info);
313   void ReportVarRedeclarationIn(const AstRawString* name, Scope* scope);
314   Statement* RewriteTryStatement(Block* try_block, Block* catch_block,
315                                  const SourceRange& catch_range,
316                                  Block* finally_block,
317                                  const SourceRange& finally_range,
318                                  const CatchInfo& catch_info, int pos);
319   void ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
320                                             ScopedPtrList<Statement>* body);
321   void ParseAndRewriteAsyncGeneratorFunctionBody(
322       int pos, FunctionKind kind, ScopedPtrList<Statement>* body);
323   void DeclareFunctionNameVar(const AstRawString* function_name,
324                               FunctionSyntaxKind function_syntax_kind,
325                               DeclarationScope* function_scope);
326 
327   Statement* DeclareFunction(const AstRawString* variable_name,
328                              FunctionLiteral* function, VariableMode mode,
329                              VariableKind kind, int beg_pos, int end_pos,
330                              ZonePtrList<const AstRawString>* names);
331   Variable* CreateSyntheticContextVariable(const AstRawString* synthetic_name);
332   Variable* CreatePrivateNameVariable(ClassScope* scope, VariableMode mode,
333                                       IsStaticFlag is_static_flag,
334                                       const AstRawString* name);
335   FunctionLiteral* CreateInitializerFunction(const char* name,
336                                              DeclarationScope* scope,
337                                              Statement* initializer_stmt);
338 
339   bool IdentifierEquals(const AstRawString* identifier,
340                         const AstRawString* other) {
341     return identifier == other;
342   }
343 
344   Statement* DeclareClass(const AstRawString* variable_name, Expression* value,
345                           ZonePtrList<const AstRawString>* names,
346                           int class_token_pos, int end_pos);
347   void DeclareClassVariable(ClassScope* scope, const AstRawString* name,
348                             ClassInfo* class_info, int class_token_pos);
349   void DeclareClassBrandVariable(ClassScope* scope, ClassInfo* class_info,
350                                  int class_token_pos);
351   void DeclarePrivateClassMember(ClassScope* scope,
352                                  const AstRawString* property_name,
353                                  ClassLiteralProperty* property,
354                                  ClassLiteralProperty::Kind kind,
355                                  bool is_static, ClassInfo* class_info);
356   void DeclarePublicClassMethod(const AstRawString* class_name,
357                                 ClassLiteralProperty* property,
358                                 bool is_constructor, ClassInfo* class_info);
359   void DeclarePublicClassField(ClassScope* scope,
360                                ClassLiteralProperty* property, bool is_static,
361                                bool is_computed_name, ClassInfo* class_info);
362   void DeclareClassProperty(ClassScope* scope, const AstRawString* class_name,
363                             ClassLiteralProperty* property, bool is_constructor,
364                             ClassInfo* class_info);
365   void DeclareClassField(ClassScope* scope, ClassLiteralProperty* property,
366                          const AstRawString* property_name, bool is_static,
367                          bool is_computed_name, bool is_private,
368                          ClassInfo* class_info);
369   void AddClassStaticBlock(Block* block, ClassInfo* class_info);
370   Expression* RewriteClassLiteral(ClassScope* block_scope,
371                                   const AstRawString* name,
372                                   ClassInfo* class_info, int pos, int end_pos);
373   Statement* DeclareNative(const AstRawString* name, int pos);
374 
375   Block* IgnoreCompletion(Statement* statement);
376 
377   Scope* NewHiddenCatchScope();
378 
379   bool HasCheckedSyntax() {
380     return scope()->GetDeclarationScope()->has_checked_syntax();
381   }
382 
383   void InitializeVariables(
384       ScopedPtrList<Statement>* statements, VariableKind kind,
385       const DeclarationParsingResult::Declaration* declaration);
386 
387   Block* RewriteForVarInLegacy(const ForInfo& for_info);
388   void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block,
389                                         Expression** each_variable);
390   Block* CreateForEachStatementTDZ(Block* init_block, const ForInfo& for_info);
391 
392   Statement* DesugarLexicalBindingsInForStatement(
393       ForStatement* loop, Statement* init, Expression* cond, Statement* next,
394       Statement* body, Scope* inner_scope, const ForInfo& for_info);
395 
396   FunctionLiteral* ParseFunctionLiteral(
397       const AstRawString* name, Scanner::Location function_name_location,
398       FunctionNameValidity function_name_validity, FunctionKind kind,
399       int function_token_position, FunctionSyntaxKind type,
400       LanguageMode language_mode,
401       ZonePtrList<const AstRawString>* arguments_for_wrapped_function);
402 
403   ObjectLiteral* InitializeObjectLiteral(ObjectLiteral* object_literal) {
404     object_literal->CalculateEmitStore(main_zone());
405     return object_literal;
406   }
407 
408   // Insert initializer statements for var-bindings shadowing parameter bindings
409   // from a non-simple parameter list.
410   void InsertShadowingVarBindingInitializers(Block* block);
411 
412   // Implement sloppy block-scoped functions, ES2015 Annex B 3.3
413   void InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope);
414 
415   void DeclareUnboundVariable(const AstRawString* name, VariableMode mode,
416                               InitializationFlag init, int pos);
417   V8_WARN_UNUSED_RESULT
418   VariableProxy* DeclareBoundVariable(const AstRawString* name,
419                                       VariableMode mode, int pos);
420   void DeclareAndBindVariable(VariableProxy* proxy, VariableKind kind,
421                               VariableMode mode, Scope* declaration_scope,
422                               bool* was_added, int initializer_position);
423   V8_WARN_UNUSED_RESULT
424   Variable* DeclareVariable(const AstRawString* name, VariableKind kind,
425                             VariableMode mode, InitializationFlag init,
426                             Scope* declaration_scope, bool* was_added,
427                             int begin, int end = kNoSourcePosition);
428   void Declare(Declaration* declaration, const AstRawString* name,
429                VariableKind kind, VariableMode mode, InitializationFlag init,
430                Scope* declaration_scope, bool* was_added, int var_begin_pos,
431                int var_end_pos = kNoSourcePosition);
432 
433   // Factory methods.
434   FunctionLiteral* DefaultConstructor(const AstRawString* name, bool call_super,
435                                       int pos, int end_pos);
436 
437   // Skip over a lazy function, either using cached data if we have it, or
438   // by parsing the function with PreParser. Consumes the ending }.
439   // In case the preparser detects an error it cannot identify, it resets the
440   // scanner- and preparser state to the initial one, before PreParsing the
441   // function.
442   // SkipFunction returns true if it correctly parsed the function, including
443   // cases where we detect an error. It returns false, if we needed to stop
444   // parsing or could not identify an error correctly, meaning the caller needs
445   // to fully reparse. In this case it resets the scanner and preparser state.
446   bool SkipFunction(const AstRawString* function_name, FunctionKind kind,
447                     FunctionSyntaxKind function_syntax_kind,
448                     DeclarationScope* function_scope, int* num_parameters,
449                     int* function_length,
450                     ProducedPreparseData** produced_preparsed_scope_data);
451 
452   Block* BuildParameterInitializationBlock(
453       const ParserFormalParameters& parameters);
454   Block* BuildRejectPromiseOnException(Block* block,
455                                        REPLMode repl_mode = REPLMode::kNo);
456 
457   void ParseFunction(
458       ScopedPtrList<Statement>* body, const AstRawString* function_name,
459       int pos, FunctionKind kind, FunctionSyntaxKind function_syntax_kind,
460       DeclarationScope* function_scope, int* num_parameters,
461       int* function_length, bool* has_duplicate_parameters,
462       int* expected_property_count, int* suspend_count,
463       ZonePtrList<const AstRawString>* arguments_for_wrapped_function);
464 
465   void ThrowPendingError(Isolate* isolate, Handle<Script> script);
466 
467   class TemplateLiteral : public ZoneObject {
468    public:
469     TemplateLiteral(Zone* zone, int pos)
470         : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
471 
472     const ZonePtrList<const AstRawString>* cooked() const { return &cooked_; }
473     const ZonePtrList<const AstRawString>* raw() const { return &raw_; }
474     const ZonePtrList<Expression>* expressions() const { return &expressions_; }
475     int position() const { return pos_; }
476 
477     void AddTemplateSpan(const AstRawString* cooked, const AstRawString* raw,
478                          int end, Zone* zone) {
479       DCHECK_NOT_NULL(raw);
480       cooked_.Add(cooked, zone);
481       raw_.Add(raw, zone);
482     }
483 
484     void AddExpression(Expression* expression, Zone* zone) {
485       expressions_.Add(expression, zone);
486     }
487 
488    private:
489     ZonePtrList<const AstRawString> cooked_;
490     ZonePtrList<const AstRawString> raw_;
491     ZonePtrList<Expression> expressions_;
492     int pos_;
493   };
494 
495   using TemplateLiteralState = TemplateLiteral*;
496 
497   TemplateLiteralState OpenTemplateLiteral(int pos);
498   // "should_cook" means that the span can be "cooked": in tagged template
499   // literals, both the raw and "cooked" representations are available to user
500   // code ("cooked" meaning that escape sequences are converted to their
501   // interpreted values). Invalid escape sequences cause the cooked span
502   // to be represented by undefined, instead of being a syntax error.
503   // "tail" indicates that this span is the last in the literal.
504   void AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
505                        bool tail);
506   void AddTemplateExpression(TemplateLiteralState* state,
507                              Expression* expression);
508   Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
509                                    Expression* tag);
510 
511   ArrayLiteral* ArrayLiteralFromListWithSpread(
512       const ScopedPtrList<Expression>& list);
513   Expression* RewriteSuperCall(Expression* call_expression);
514 
515   void SetLanguageMode(Scope* scope, LanguageMode mode);
516 #if V8_ENABLE_WEBASSEMBLY
517   void SetAsmModule();
518 #endif  // V8_ENABLE_WEBASSEMBLY
519 
520   Expression* RewriteSpreads(ArrayLiteral* lit);
521 
522   Expression* BuildInitialYield(int pos, FunctionKind kind);
523   Assignment* BuildCreateJSGeneratorObject(int pos, FunctionKind kind);
524 
525   // Generic AST generator for throwing errors from compiled code.
526   Expression* NewThrowError(Runtime::FunctionId function_id,
527                             MessageTemplate message, const AstRawString* arg,
528                             int pos);
529 
530   Statement* CheckCallable(Variable* var, Expression* error, int pos);
531 
532   void RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body, Block* block,
533                                 Expression* return_value,
534                                 REPLMode repl_mode = REPLMode::kNo);
535 
536   void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters,
537                                         Expression* params, int end_pos);
538   void SetFunctionName(Expression* value, const AstRawString* name,
539                        const AstRawString* prefix = nullptr);
540 
541   // Helper functions for recursive descent.
542   V8_INLINE bool IsEval(const AstRawString* identifier) const {
543     return identifier == ast_value_factory()->eval_string();
544   }
545 
546   V8_INLINE bool IsAsync(const AstRawString* identifier) const {
547     return identifier == ast_value_factory()->async_string();
548   }
549 
550   V8_INLINE bool IsArguments(const AstRawString* identifier) const {
551     return identifier == ast_value_factory()->arguments_string();
552   }
553 
554   V8_INLINE bool IsEvalOrArguments(const AstRawString* identifier) const {
555     return IsEval(identifier) || IsArguments(identifier);
556   }
557 
558   // Returns true if the expression is of type "this.foo".
559   V8_INLINE static bool IsThisProperty(Expression* expression) {
560     DCHECK_NOT_NULL(expression);
561     Property* property = expression->AsProperty();
562     return property != nullptr && property->obj()->IsThisExpression();
563   }
564 
565   // Returns true if the expression is of type "obj.#foo" or "obj?.#foo".
566   V8_INLINE static bool IsPrivateReference(Expression* expression) {
567     DCHECK_NOT_NULL(expression);
568     Property* property = expression->AsProperty();
569     if (expression->IsOptionalChain()) {
570       Expression* expr_inner = expression->AsOptionalChain()->expression();
571       property = expr_inner->AsProperty();
572     }
573     return property != nullptr && property->IsPrivateReference();
574   }
575 
576   // This returns true if the expression is an identifier (wrapped
577   // inside a variable proxy).  We exclude the case of 'this', which
578   // has been converted to a variable proxy.
579   V8_INLINE static bool IsIdentifier(Expression* expression) {
580     VariableProxy* operand = expression->AsVariableProxy();
581     return operand != nullptr && !operand->is_new_target();
582   }
583 
584   V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) {
585     DCHECK(IsIdentifier(expression));
586     return expression->AsVariableProxy()->raw_name();
587   }
588 
589   V8_INLINE VariableProxy* AsIdentifierExpression(Expression* expression) {
590     return expression->AsVariableProxy();
591   }
592 
593   V8_INLINE bool IsConstructor(const AstRawString* identifier) const {
594     return identifier == ast_value_factory()->constructor_string();
595   }
596 
597   V8_INLINE bool IsName(const AstRawString* identifier) const {
598     return identifier == ast_value_factory()->name_string();
599   }
600 
601   V8_INLINE static bool IsBoilerplateProperty(
602       ObjectLiteral::Property* property) {
603     return !property->IsPrototype();
604   }
605 
606   V8_INLINE v8::Extension* extension() const { return info_->extension(); }
607 
608   V8_INLINE bool ParsingExtension() const { return extension() != nullptr; }
609 
610   V8_INLINE bool IsNative(Expression* expr) const {
611     DCHECK_NOT_NULL(expr);
612     return expr->IsVariableProxy() &&
613            expr->AsVariableProxy()->raw_name() ==
614                ast_value_factory()->native_string();
615   }
616 
617   V8_INLINE static bool IsArrayIndex(const AstRawString* string,
618                                      uint32_t* index) {
619     return string->AsArrayIndex(index);
620   }
621 
622   // Returns true if the statement is an expression statement containing
623   // a single string literal.  If a second argument is given, the literal
624   // is also compared with it and the result is true only if they are equal.
625   V8_INLINE bool IsStringLiteral(Statement* statement,
626                                  const AstRawString* arg = nullptr) const {
627     ExpressionStatement* e_stat = statement->AsExpressionStatement();
628     if (e_stat == nullptr) return false;
629     Literal* literal = e_stat->expression()->AsLiteral();
630     if (literal == nullptr || !literal->IsString()) return false;
631     return arg == nullptr || literal->AsRawString() == arg;
632   }
633 
634   V8_INLINE void GetDefaultStrings(const AstRawString** default_string,
635                                    const AstRawString** dot_default_string) {
636     *default_string = ast_value_factory()->default_string();
637     *dot_default_string = ast_value_factory()->dot_default_string();
638   }
639 
640   // Functions for encapsulating the differences between parsing and preparsing;
641   // operations interleaved with the recursive descent.
642   V8_INLINE void PushLiteralName(const AstRawString* id) {
643     fni_.PushLiteralName(id);
644   }
645 
646   V8_INLINE void PushVariableName(const AstRawString* id) {
647     fni_.PushVariableName(id);
648   }
649 
650   V8_INLINE void PushPropertyName(Expression* expression) {
651     if (expression->IsPropertyName()) {
652       fni_.PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
653     } else {
654       fni_.PushLiteralName(ast_value_factory()->computed_string());
655     }
656   }
657 
658   V8_INLINE void PushEnclosingName(const AstRawString* name) {
659     fni_.PushEnclosingName(name);
660   }
661 
662   V8_INLINE void AddFunctionForNameInference(FunctionLiteral* func_to_infer) {
663     fni_.AddFunction(func_to_infer);
664   }
665 
666   V8_INLINE void InferFunctionName() { fni_.Infer(); }
667 
668   // If we assign a function literal to a property we pretenure the
669   // literal so it can be added as a constant function property.
670   V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
671       Expression* left, Expression* right) {
672     DCHECK_NOT_NULL(left);
673     if (left->IsProperty() && right->IsFunctionLiteral()) {
674       right->AsFunctionLiteral()->set_pretenure();
675     }
676   }
677 
678   // Returns true if we have a binary expression between two numeric
679   // literals. In that case, *x will be changed to an expression which is the
680   // computed value.
681   bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
682                                               Token::Value op, int pos);
683 
684   // Returns true if we have a binary operation between a binary/n-ary
685   // expression (with the same operation) and a value, which can be collapsed
686   // into a single n-ary expression. In that case, *x will be changed to an
687   // n-ary expression.
688   bool CollapseNaryExpression(Expression** x, Expression* y, Token::Value op,
689                               int pos, const SourceRange& range);
690 
691   // Returns a UnaryExpression or, in one of the following cases, a Literal.
692   // ! <literal> -> true / false
693   // + <Number literal> -> <Number literal>
694   // - <Number literal> -> <Number literal with value negated>
695   // ~ <literal> -> true / false
696   Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
697                                    int pos);
698 
699   // Generate AST node that throws a ReferenceError with the given type.
700   V8_INLINE Expression* NewThrowReferenceError(MessageTemplate message,
701                                                int pos) {
702     return NewThrowError(Runtime::kNewReferenceError, message,
703                          ast_value_factory()->empty_string(), pos);
704   }
705 
706   // Generate AST node that throws a SyntaxError with the given
707   // type. The first argument may be null (in the handle sense) in
708   // which case no arguments are passed to the constructor.
709   V8_INLINE Expression* NewThrowSyntaxError(MessageTemplate message,
710                                             const AstRawString* arg, int pos) {
711     return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
712   }
713 
714   // Generate AST node that throws a TypeError with the given
715   // type. Both arguments must be non-null (in the handle sense).
716   V8_INLINE Expression* NewThrowTypeError(MessageTemplate message,
717                                           const AstRawString* arg, int pos) {
718     return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
719   }
720 
721   // Dummy implementation. The parser should never have a unidentifiable
722   // error.
723   V8_INLINE void ReportUnidentifiableError() { UNREACHABLE(); }
724 
725   const AstRawString* GetRawNameFromIdentifier(const AstRawString* arg) {
726     return arg;
727   }
728 
729   const AstRawString* PreParserIdentifierToAstRawString(
730       const PreParserIdentifier& arg) {
731     // This method definition is only needed due to an MSVC oddity that
732     // instantiates the method despite it being unused. See crbug.com/v8/12266 .
733     UNREACHABLE();
734   }
735 
736   IterationStatement* AsIterationStatement(BreakableStatement* s) {
737     return s->AsIterationStatement();
738   }
739 
740   void ReportUnexpectedTokenAt(
741       Scanner::Location location, Token::Value token,
742       MessageTemplate message = MessageTemplate::kUnexpectedToken);
743 
744   // "null" return type creators.
745   V8_INLINE static std::nullptr_t NullIdentifier() { return nullptr; }
746   V8_INLINE static std::nullptr_t NullExpression() { return nullptr; }
747   V8_INLINE static std::nullptr_t NullLiteralProperty() { return nullptr; }
748   V8_INLINE static ZonePtrList<Expression>* NullExpressionList() {
749     return nullptr;
750   }
751   V8_INLINE static ZonePtrList<Statement>* NullStatementList() {
752     return nullptr;
753   }
754   V8_INLINE static std::nullptr_t NullStatement() { return nullptr; }
755   V8_INLINE static std::nullptr_t NullBlock() { return nullptr; }
756   Expression* FailureExpression() { return factory()->FailureExpression(); }
757 
758   template <typename T>
759   V8_INLINE static bool IsNull(T subject) {
760     return subject == nullptr;
761   }
762 
763   V8_INLINE static bool IsIterationStatement(Statement* subject) {
764     return subject->AsIterationStatement() != nullptr;
765   }
766 
767   // Non-null empty string.
768   V8_INLINE const AstRawString* EmptyIdentifierString() const {
769     return ast_value_factory()->empty_string();
770   }
771 
772   // Producing data during the recursive descent.
773   V8_INLINE const AstRawString* GetSymbol() const {
774     const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
775     DCHECK_NOT_NULL(result);
776     return result;
777   }
778 
779   V8_INLINE const AstRawString* GetIdentifier() const { return GetSymbol(); }
780 
781   V8_INLINE const AstRawString* GetNextSymbol() const {
782     return scanner()->NextSymbol(ast_value_factory());
783   }
784 
785   V8_INLINE const AstRawString* GetNumberAsSymbol() const {
786     double double_value = scanner()->DoubleValue();
787     char array[100];
788     const char* string =
789         DoubleToCString(double_value, base::ArrayVector(array));
790     return ast_value_factory()->GetOneByteString(string);
791   }
792 
793   const AstRawString* GetBigIntAsSymbol();
794 
795   class ThisExpression* ThisExpression() {
796     UseThis();
797     return factory()->ThisExpression();
798   }
799 
800   class ThisExpression* NewThisExpression(int pos) {
801     UseThis();
802     return factory()->NewThisExpression(pos);
803   }
804 
805   Expression* NewSuperPropertyReference(Scope* home_object_scope, int pos);
806   Expression* NewSuperCallReference(int pos);
807   Expression* NewTargetExpression(int pos);
808   Expression* ImportMetaExpression(int pos);
809 
810   Expression* ExpressionFromLiteral(Token::Value token, int pos);
811 
812   V8_INLINE VariableProxy* ExpressionFromPrivateName(
813       PrivateNameScopeIterator* private_name_scope, const AstRawString* name,
814       int start_position) {
815     VariableProxy* proxy = factory()->ast_node_factory()->NewVariableProxy(
816         name, NORMAL_VARIABLE, start_position);
817     private_name_scope->AddUnresolvedPrivateName(proxy);
818     return proxy;
819   }
820 
821   V8_INLINE VariableProxy* ExpressionFromIdentifier(
822       const AstRawString* name, int start_position,
823       InferName infer = InferName::kYes) {
824     if (infer == InferName::kYes) {
825       fni_.PushVariableName(name);
826     }
827     return expression_scope()->NewVariable(name, start_position);
828   }
829 
830   V8_INLINE void DeclareIdentifier(const AstRawString* name,
831                                    int start_position) {
832     expression_scope()->Declare(name, start_position);
833   }
834 
835   V8_INLINE Variable* DeclareCatchVariableName(Scope* scope,
836                                                const AstRawString* name) {
837     return scope->DeclareCatchVariableName(name);
838   }
839 
840   V8_INLINE ZonePtrList<Expression>* NewExpressionList(int size) const {
841     return zone()->New<ZonePtrList<Expression>>(size, zone());
842   }
843   V8_INLINE ZonePtrList<ObjectLiteral::Property>* NewObjectPropertyList(
844       int size) const {
845     return zone()->New<ZonePtrList<ObjectLiteral::Property>>(size, zone());
846   }
847   V8_INLINE ZonePtrList<ClassLiteral::Property>* NewClassPropertyList(
848       int size) const {
849     return zone()->New<ZonePtrList<ClassLiteral::Property>>(size, zone());
850   }
851   V8_INLINE ZonePtrList<ClassLiteral::StaticElement>* NewClassStaticElementList(
852       int size) const {
853     return zone()->New<ZonePtrList<ClassLiteral::StaticElement>>(size, zone());
854   }
855   V8_INLINE ZonePtrList<Statement>* NewStatementList(int size) const {
856     return zone()->New<ZonePtrList<Statement>>(size, zone());
857   }
858 
859   Expression* NewV8Intrinsic(const AstRawString* name,
860                              const ScopedPtrList<Expression>& args, int pos);
861 
862   Expression* NewV8RuntimeFunctionForFuzzing(
863       const Runtime::Function* function, const ScopedPtrList<Expression>& args,
864       int pos);
865 
866   V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) {
867     return factory()->NewExpressionStatement(
868         factory()->NewThrow(exception, pos), pos);
869   }
870 
871   V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
872                                     Expression* pattern,
873                                     Expression* initializer,
874                                     int initializer_end_position,
875                                     bool is_rest) {
876     parameters->UpdateArityAndFunctionLength(initializer != nullptr, is_rest);
877     auto parameter =
878         parameters->scope->zone()->New<ParserFormalParameters::Parameter>(
879             pattern, initializer, scanner()->location().beg_pos,
880             initializer_end_position, is_rest);
881 
882     parameters->params.Add(parameter);
883   }
884 
885   V8_INLINE void DeclareFormalParameters(ParserFormalParameters* parameters) {
886     bool is_simple = parameters->is_simple;
887     DeclarationScope* scope = parameters->scope;
888     if (!is_simple) scope->MakeParametersNonSimple();
889     for (auto parameter : parameters->params) {
890       bool is_optional = parameter->initializer() != nullptr;
891       // If the parameter list is simple, declare the parameters normally with
892       // their names. If the parameter list is not simple, declare a temporary
893       // for each parameter - the corresponding named variable is declared by
894       // BuildParamerterInitializationBlock.
895       scope->DeclareParameter(
896           is_simple ? parameter->name() : ast_value_factory()->empty_string(),
897           is_simple ? VariableMode::kVar : VariableMode::kTemporary,
898           is_optional, parameter->is_rest(), ast_value_factory(),
899           parameter->position);
900     }
901   }
902 
903   void DeclareArrowFunctionFormalParameters(
904       ParserFormalParameters* parameters, Expression* params,
905       const Scanner::Location& params_loc);
906 
907   Expression* ExpressionListToExpression(const ScopedPtrList<Expression>& args);
908 
909   void SetFunctionNameFromPropertyName(LiteralProperty* property,
910                                        const AstRawString* name,
911                                        const AstRawString* prefix = nullptr);
912   void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
913                                        const AstRawString* name,
914                                        const AstRawString* prefix = nullptr);
915 
916   void SetFunctionNameFromIdentifierRef(Expression* value,
917                                         Expression* identifier);
918 
919   V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
920     ++use_counts_[feature];
921   }
922 
923   // Returns true iff we're parsing the first function literal during
924   // CreateDynamicFunction().
925   V8_INLINE bool ParsingDynamicFunctionDeclaration() const {
926     return parameters_end_pos_ != kNoSourcePosition;
927   }
928 
929   V8_INLINE void ConvertBinaryToNaryOperationSourceRange(
930       BinaryOperation* binary_op, NaryOperation* nary_op) {
931     if (source_range_map_ == nullptr) return;
932     DCHECK_NULL(source_range_map_->Find(nary_op));
933 
934     BinaryOperationSourceRanges* ranges =
935         static_cast<BinaryOperationSourceRanges*>(
936             source_range_map_->Find(binary_op));
937     if (ranges == nullptr) return;
938 
939     SourceRange range = ranges->GetRange(SourceRangeKind::kRight);
940     source_range_map_->Insert(
941         nary_op, zone()->New<NaryOperationSourceRanges>(zone(), range));
942   }
943 
944   V8_INLINE void AppendNaryOperationSourceRange(NaryOperation* node,
945                                                 const SourceRange& range) {
946     if (source_range_map_ == nullptr) return;
947     NaryOperationSourceRanges* ranges =
948         static_cast<NaryOperationSourceRanges*>(source_range_map_->Find(node));
949     if (ranges == nullptr) return;
950 
951     ranges->AddRange(range);
952     DCHECK_EQ(node->subsequent_length(), ranges->RangeCount());
953   }
954 
955   V8_INLINE void RecordBlockSourceRange(Block* node,
956                                         int32_t continuation_position) {
957     if (source_range_map_ == nullptr) return;
958     source_range_map_->Insert(
959         node, zone()->New<BlockSourceRanges>(continuation_position));
960   }
961 
962   V8_INLINE void RecordCaseClauseSourceRange(CaseClause* node,
963                                              const SourceRange& body_range) {
964     if (source_range_map_ == nullptr) return;
965     source_range_map_->Insert(node,
966                               zone()->New<CaseClauseSourceRanges>(body_range));
967   }
968 
969   V8_INLINE void RecordConditionalSourceRange(Expression* node,
970                                               const SourceRange& then_range,
971                                               const SourceRange& else_range) {
972     if (source_range_map_ == nullptr) return;
973     source_range_map_->Insert(
974         node->AsConditional(),
975         zone()->New<ConditionalSourceRanges>(then_range, else_range));
976   }
977 
978   V8_INLINE void RecordFunctionLiteralSourceRange(FunctionLiteral* node) {
979     if (source_range_map_ == nullptr) return;
980     source_range_map_->Insert(node, zone()->New<FunctionLiteralSourceRanges>());
981   }
982 
983   V8_INLINE void RecordBinaryOperationSourceRange(
984       Expression* node, const SourceRange& right_range) {
985     if (source_range_map_ == nullptr) return;
986     source_range_map_->Insert(
987         node->AsBinaryOperation(),
988         zone()->New<BinaryOperationSourceRanges>(right_range));
989   }
990 
991   V8_INLINE void RecordJumpStatementSourceRange(Statement* node,
992                                                 int32_t continuation_position) {
993     if (source_range_map_ == nullptr) return;
994     source_range_map_->Insert(
995         static_cast<JumpStatement*>(node),
996         zone()->New<JumpStatementSourceRanges>(continuation_position));
997   }
998 
999   V8_INLINE void RecordIfStatementSourceRange(Statement* node,
1000                                               const SourceRange& then_range,
1001                                               const SourceRange& else_range) {
1002     if (source_range_map_ == nullptr) return;
1003     source_range_map_->Insert(
1004         node->AsIfStatement(),
1005         zone()->New<IfStatementSourceRanges>(then_range, else_range));
1006   }
1007 
1008   V8_INLINE void RecordIterationStatementSourceRange(
1009       IterationStatement* node, const SourceRange& body_range) {
1010     if (source_range_map_ == nullptr) return;
1011     source_range_map_->Insert(
1012         node, zone()->New<IterationStatementSourceRanges>(body_range));
1013   }
1014 
1015   // Used to record source ranges of expressions associated with optional chain:
1016   V8_INLINE void RecordExpressionSourceRange(Expression* node,
1017                                              const SourceRange& right_range) {
1018     if (source_range_map_ == nullptr) return;
1019     source_range_map_->Insert(node,
1020                               zone()->New<ExpressionSourceRanges>(right_range));
1021   }
1022 
1023   V8_INLINE void RecordSuspendSourceRange(Expression* node,
1024                                           int32_t continuation_position) {
1025     if (source_range_map_ == nullptr) return;
1026     source_range_map_->Insert(
1027         static_cast<Suspend*>(node),
1028         zone()->New<SuspendSourceRanges>(continuation_position));
1029   }
1030 
1031   V8_INLINE void RecordSwitchStatementSourceRange(
1032       Statement* node, int32_t continuation_position) {
1033     if (source_range_map_ == nullptr) return;
1034     source_range_map_->Insert(
1035         node->AsSwitchStatement(),
1036         zone()->New<SwitchStatementSourceRanges>(continuation_position));
1037   }
1038 
1039   V8_INLINE void RecordThrowSourceRange(Statement* node,
1040                                         int32_t continuation_position) {
1041     if (source_range_map_ == nullptr) return;
1042     ExpressionStatement* expr_stmt = static_cast<ExpressionStatement*>(node);
1043     Throw* throw_expr = expr_stmt->expression()->AsThrow();
1044     source_range_map_->Insert(
1045         throw_expr, zone()->New<ThrowSourceRanges>(continuation_position));
1046   }
1047 
1048   V8_INLINE void RecordTryCatchStatementSourceRange(
1049       TryCatchStatement* node, const SourceRange& body_range) {
1050     if (source_range_map_ == nullptr) return;
1051     source_range_map_->Insert(
1052         node, zone()->New<TryCatchStatementSourceRanges>(body_range));
1053   }
1054 
1055   V8_INLINE void RecordTryFinallyStatementSourceRange(
1056       TryFinallyStatement* node, const SourceRange& body_range) {
1057     if (source_range_map_ == nullptr) return;
1058     source_range_map_->Insert(
1059         node, zone()->New<TryFinallyStatementSourceRanges>(body_range));
1060   }
1061 
1062   // Generate the next internal variable name for binding an exported namespace
1063   // object (used to implement the "export * as" syntax).
1064   const AstRawString* NextInternalNamespaceExportName();
1065 
1066   ParseInfo* info() const { return info_; }
1067 
1068   std::vector<uint8_t>* preparse_data_buffer() {
1069     return &preparse_data_buffer_;
1070   }
1071 
1072   // Parser's private field members.
1073   friend class PreParserZoneScope;  // Uses reusable_preparser().
1074   friend class PreparseDataBuilder;  // Uses preparse_data_buffer()
1075 
1076   LocalIsolate* local_isolate_;
1077   ParseInfo* info_;
1078   Handle<Script> script_;
1079   Scanner scanner_;
1080   Zone preparser_zone_;
1081   PreParser* reusable_preparser_;
1082   Mode mode_;
1083   bool overall_parse_is_parked_ = false;
1084 
1085   MaybeHandle<FixedArray> maybe_wrapped_arguments_;
1086 
1087   SourceRangeMap* source_range_map_ = nullptr;
1088 
1089   friend class ParserTargetScope;
1090 
1091   ScriptCompiler::CompileOptions compile_options_;
1092 
1093   // For NextInternalNamespaceExportName().
1094   int number_of_named_namespace_exports_ = 0;
1095 
1096   // Other information which will be stored in Parser and moved to Isolate after
1097   // parsing.
1098   int use_counts_[v8::Isolate::kUseCounterFeatureCount];
1099   int total_preparse_skipped_;
1100   bool allow_lazy_;
1101   bool temp_zoned_;
1102   ConsumedPreparseData* consumed_preparse_data_;
1103   std::vector<uint8_t> preparse_data_buffer_;
1104 
1105   // If not kNoSourcePosition, indicates that the first function literal
1106   // encountered is a dynamic function, see CreateDynamicFunction(). This field
1107   // indicates the correct position of the ')' that closes the parameter list.
1108   // After that ')' is encountered, this field is reset to kNoSourcePosition.
1109   int parameters_end_pos_;
1110 };
1111 
1112 }  // namespace internal
1113 }  // namespace v8
1114 
1115 #endif  // V8_PARSING_PARSER_H_
1116