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