• 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.h"
12 #include "src/ast/scopes.h"
13 #include "src/base/compiler-specific.h"
14 #include "src/globals.h"
15 #include "src/parsing/parser-base.h"
16 #include "src/parsing/parsing.h"
17 #include "src/parsing/preparser.h"
18 #include "src/utils.h"
19 #include "src/zone/zone-chunk-list.h"
20 
21 namespace v8 {
22 
23 class ScriptCompiler;
24 
25 namespace internal {
26 
27 class ConsumedPreParsedScopeData;
28 class ParseInfo;
29 class ParserTarget;
30 class ParserTargetScope;
31 class PendingCompilationErrorHandler;
32 class PreParsedScopeData;
33 
34 class FunctionEntry BASE_EMBEDDED {
35  public:
36   enum {
37     kStartPositionIndex,
38     kEndPositionIndex,
39     kNumParametersIndex,
40     kFlagsIndex,
41     kNumInnerFunctionsIndex,
42     kSize
43   };
44 
FunctionEntry(Vector<unsigned> backing)45   explicit FunctionEntry(Vector<unsigned> backing)
46     : backing_(backing) { }
47 
FunctionEntry()48   FunctionEntry() : backing_() { }
49 
50   class LanguageModeField : public BitField<LanguageMode, 0, 1> {};
51   class UsesSuperPropertyField
52       : public BitField<bool, LanguageModeField::kNext, 1> {};
53 
EncodeFlags(LanguageMode language_mode,bool uses_super_property)54   static uint32_t EncodeFlags(LanguageMode language_mode,
55                               bool uses_super_property) {
56     return LanguageModeField::encode(language_mode) |
57            UsesSuperPropertyField::encode(uses_super_property);
58   }
59 
start_pos()60   int start_pos() const { return backing_[kStartPositionIndex]; }
end_pos()61   int end_pos() const { return backing_[kEndPositionIndex]; }
num_parameters()62   int num_parameters() const { return backing_[kNumParametersIndex]; }
language_mode()63   LanguageMode language_mode() const {
64     return LanguageModeField::decode(backing_[kFlagsIndex]);
65   }
uses_super_property()66   bool uses_super_property() const {
67     return UsesSuperPropertyField::decode(backing_[kFlagsIndex]);
68   }
num_inner_functions()69   int num_inner_functions() const { return backing_[kNumInnerFunctionsIndex]; }
70 
is_valid()71   bool is_valid() const { return !backing_.is_empty(); }
72 
73  private:
74   Vector<unsigned> backing_;
75 };
76 
77 
78 // ----------------------------------------------------------------------------
79 // JAVASCRIPT PARSING
80 
81 class Parser;
82 
83 
84 struct ParserFormalParameters : FormalParametersBase {
85   struct Parameter : public ZoneObject {
ParameterParserFormalParameters::Parameter86     Parameter(const AstRawString* name, Expression* pattern,
87               Expression* initializer, int position,
88               int initializer_end_position, bool is_rest)
89         : name(name),
90           pattern(pattern),
91           initializer(initializer),
92           position(position),
93           initializer_end_position(initializer_end_position),
94           is_rest(is_rest) {}
95     const AstRawString* name;
96     Expression* pattern;
97     Expression* initializer;
98     int position;
99     int initializer_end_position;
100     bool is_rest;
101     Parameter* next_parameter = nullptr;
is_simpleParserFormalParameters::Parameter102     bool is_simple() const {
103       return pattern->IsVariableProxy() && initializer == nullptr && !is_rest;
104     }
105 
nextParserFormalParameters::Parameter106     Parameter** next() { return &next_parameter; }
nextParserFormalParameters::Parameter107     Parameter* const* next() const { return &next_parameter; }
108   };
109 
ParserFormalParametersParserFormalParameters110   explicit ParserFormalParameters(DeclarationScope* scope)
111       : FormalParametersBase(scope) {}
112   ThreadedList<Parameter> params;
113 };
114 
115 template <>
116 struct ParserTypes<Parser> {
117   typedef ParserBase<Parser> Base;
118   typedef Parser Impl;
119 
120   // Return types for traversing functions.
121   typedef const AstRawString* Identifier;
122   typedef v8::internal::Expression* Expression;
123   typedef v8::internal::FunctionLiteral* FunctionLiteral;
124   typedef ObjectLiteral::Property* ObjectLiteralProperty;
125   typedef ClassLiteral::Property* ClassLiteralProperty;
126   typedef v8::internal::Suspend* Suspend;
127   typedef v8::internal::RewritableExpression* RewritableExpression;
128   typedef ZonePtrList<v8::internal::Expression>* ExpressionList;
129   typedef ZonePtrList<ObjectLiteral::Property>* ObjectPropertyList;
130   typedef ZonePtrList<ClassLiteral::Property>* ClassPropertyList;
131   typedef ParserFormalParameters FormalParameters;
132   typedef v8::internal::Statement* Statement;
133   typedef ZonePtrList<v8::internal::Statement>* StatementList;
134   typedef v8::internal::Block* Block;
135   typedef v8::internal::BreakableStatement* BreakableStatement;
136   typedef v8::internal::ForStatement* ForStatement;
137   typedef v8::internal::IterationStatement* IterationStatement;
138 
139   // For constructing objects returned by the traversing functions.
140   typedef AstNodeFactory Factory;
141 
142   typedef ParserTarget Target;
143   typedef ParserTargetScope TargetScope;
144 };
145 
146 class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
147  public:
148   explicit Parser(ParseInfo* info);
149   ~Parser() {
150     delete reusable_preparser_;
151     reusable_preparser_ = nullptr;
152   }
153 
154   static bool IsPreParser() { return false; }
155 
156   void ParseOnBackground(ParseInfo* info);
157 
158   // Deserialize the scope chain prior to parsing in which the script is going
159   // to be executed. If the script is a top-level script, or the scope chain
160   // consists of only a native context, maybe_outer_scope_info should be an
161   // empty handle.
162   //
163   // This only deserializes the scope chain, but doesn't connect the scopes to
164   // their corresponding scope infos. Therefore, looking up variables in the
165   // deserialized scopes is not possible.
166   void DeserializeScopeChain(Isolate* isolate, ParseInfo* info,
167                              MaybeHandle<ScopeInfo> maybe_outer_scope_info);
168 
169   // Move statistics to Isolate
170   void UpdateStatistics(Isolate* isolate, Handle<Script> script);
171   void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
172 
173  private:
174   friend class ParserBase<Parser>;
175   friend class v8::internal::ExpressionClassifier<ParserTypes<Parser>>;
176   friend bool v8::internal::parsing::ParseProgram(ParseInfo*, Isolate*);
177   friend bool v8::internal::parsing::ParseFunction(
178       ParseInfo*, Handle<SharedFunctionInfo> shared_info, Isolate*);
179 
180   bool AllowsLazyParsingWithoutUnresolvedVariables() const {
181     return scope()->AllowsLazyParsingWithoutUnresolvedVariables(
182         original_scope_);
183   }
184 
185   bool parse_lazily() const { return mode_ == PARSE_LAZILY; }
186   enum Mode { PARSE_LAZILY, PARSE_EAGERLY };
187 
188   class ParsingModeScope BASE_EMBEDDED {
189    public:
190     ParsingModeScope(Parser* parser, Mode mode)
191         : parser_(parser), old_mode_(parser->mode_) {
192       parser_->mode_ = mode;
193     }
194     ~ParsingModeScope() { parser_->mode_ = old_mode_; }
195 
196    private:
197     Parser* parser_;
198     Mode old_mode_;
199   };
200 
201   // Runtime encoding of different completion modes.
202   enum CompletionKind {
203     kNormalCompletion,
204     kThrowCompletion,
205     kAbruptCompletion
206   };
207 
208   Variable* NewTemporary(const AstRawString* name) {
209     return scope()->NewTemporary(name);
210   }
211 
212   void PrepareGeneratorVariables();
213 
214   // Returns nullptr if parsing failed.
215   FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info);
216 
217   FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info,
218                                  Handle<SharedFunctionInfo> shared_info);
219   FunctionLiteral* DoParseFunction(Isolate* isolate, ParseInfo* info,
220                                    const AstRawString* raw_name);
221 
222   // Called by ParseProgram after setting up the scanner.
223   FunctionLiteral* DoParseProgram(Isolate* isolate, ParseInfo* info);
224 
225   // Parse with the script as if the source is implicitly wrapped in a function.
226   // We manually construct the AST and scopes for a top-level function and the
227   // function wrapper.
228   void ParseWrapped(Isolate* isolate, ParseInfo* info,
229                     ZonePtrList<Statement>* body, DeclarationScope* scope,
230                     Zone* zone, bool* ok);
231 
232   ZonePtrList<const AstRawString>* PrepareWrappedArguments(Isolate* isolate,
233                                                            ParseInfo* info,
234                                                            Zone* zone);
235 
236   void StitchAst(ParseInfo* top_level_parse_info, Isolate* isolate);
237 
238   PreParser* reusable_preparser() {
239     if (reusable_preparser_ == nullptr) {
240       reusable_preparser_ =
241           new PreParser(zone(), &scanner_, stack_limit_, ast_value_factory(),
242                         pending_error_handler(), runtime_call_stats_, logger_,
243                         -1, parsing_module_, parsing_on_main_thread_);
244 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
245       SET_ALLOW(natives);
246       SET_ALLOW(harmony_do_expressions);
247       SET_ALLOW(harmony_public_fields);
248       SET_ALLOW(harmony_static_fields);
249       SET_ALLOW(harmony_dynamic_import);
250       SET_ALLOW(harmony_import_meta);
251       SET_ALLOW(harmony_bigint);
252       SET_ALLOW(harmony_private_fields);
253       SET_ALLOW(eval_cache);
254 #undef SET_ALLOW
255     }
256     return reusable_preparser_;
257   }
258 
259   void ParseModuleItemList(ZonePtrList<Statement>* body, bool* ok);
260   Statement* ParseModuleItem(bool* ok);
261   const AstRawString* ParseModuleSpecifier(bool* ok);
262   void ParseImportDeclaration(bool* ok);
263   Statement* ParseExportDeclaration(bool* ok);
264   Statement* ParseExportDefault(bool* ok);
265   struct ExportClauseData {
266     const AstRawString* export_name;
267     const AstRawString* local_name;
268     Scanner::Location location;
269   };
270   ZoneChunkList<ExportClauseData>* ParseExportClause(
271       Scanner::Location* reserved_loc, bool* ok);
272   struct NamedImport : public ZoneObject {
273     const AstRawString* import_name;
274     const AstRawString* local_name;
275     const Scanner::Location location;
276     NamedImport(const AstRawString* import_name, const AstRawString* local_name,
277                 Scanner::Location location)
278         : import_name(import_name),
279           local_name(local_name),
280           location(location) {}
281   };
282   ZonePtrList<const NamedImport>* ParseNamedImports(int pos, bool* ok);
283   Block* BuildInitializationBlock(DeclarationParsingResult* parsing_result,
284                                   ZonePtrList<const AstRawString>* names,
285                                   bool* ok);
286   void DeclareLabel(ZonePtrList<const AstRawString>** labels,
287                     ZonePtrList<const AstRawString>** own_labels,
288                     VariableProxy* expr, bool* ok);
289   bool ContainsLabel(ZonePtrList<const AstRawString>* labels,
290                      const AstRawString* label);
291   Expression* RewriteReturn(Expression* return_value, int pos);
292   Statement* RewriteSwitchStatement(SwitchStatement* switch_statement,
293                                     Scope* scope);
294   void RewriteCatchPattern(CatchInfo* catch_info, bool* ok);
295   void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok);
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                                             ZonePtrList<Statement>* body,
303                                             bool* ok);
304   void ParseAndRewriteAsyncGeneratorFunctionBody(int pos, FunctionKind kind,
305                                                  ZonePtrList<Statement>* body,
306                                                  bool* ok);
307   void DeclareFunctionNameVar(const AstRawString* function_name,
308                               FunctionLiteral::FunctionType function_type,
309                               DeclarationScope* function_scope);
310 
311   Statement* DeclareFunction(const AstRawString* variable_name,
312                              FunctionLiteral* function, VariableMode mode,
313                              int pos, bool is_sloppy_block_function,
314                              ZonePtrList<const AstRawString>* names, bool* ok);
315   Variable* CreateSyntheticContextVariable(const AstRawString* synthetic_name,
316                                            bool* ok);
317   FunctionLiteral* CreateInitializerFunction(
318       DeclarationScope* scope, ZonePtrList<ClassLiteral::Property>* fields);
319   V8_INLINE Statement* DeclareClass(const AstRawString* variable_name,
320                                     Expression* value,
321                                     ZonePtrList<const AstRawString>* names,
322                                     int class_token_pos, int end_pos, bool* ok);
323   V8_INLINE void DeclareClassVariable(const AstRawString* name,
324                                       ClassInfo* class_info,
325                                       int class_token_pos, bool* ok);
326   V8_INLINE void DeclareClassProperty(const AstRawString* class_name,
327                                       ClassLiteralProperty* property,
328                                       const AstRawString* property_name,
329                                       ClassLiteralProperty::Kind kind,
330                                       bool is_static, bool is_constructor,
331                                       bool is_computed_name,
332                                       ClassInfo* class_info, bool* ok);
333   V8_INLINE Expression* RewriteClassLiteral(Scope* block_scope,
334                                             const AstRawString* name,
335                                             ClassInfo* class_info, int pos,
336                                             int end_pos, bool* ok);
337   V8_INLINE Statement* DeclareNative(const AstRawString* name, int pos,
338                                      bool* ok);
339 
340   V8_INLINE Block* IgnoreCompletion(Statement* statement);
341 
342   V8_INLINE Scope* NewHiddenCatchScope();
343 
344   // PatternRewriter and associated methods defined in pattern-rewriter.cc.
345   friend class PatternRewriter;
346   void DeclareAndInitializeVariables(
347       Block* block, const DeclarationDescriptor* declaration_descriptor,
348       const DeclarationParsingResult::Declaration* declaration,
349       ZonePtrList<const AstRawString>* names, bool* ok);
350   void RewriteDestructuringAssignment(RewritableExpression* expr);
351   Expression* RewriteDestructuringAssignment(Assignment* assignment);
352 
353   // [if (IteratorType == kAsync)]
354   //     !%_IsJSReceiver(result = Await(next.[[Call]](iterator, « »)) &&
355   //         %ThrowIteratorResultNotAnObject(result)
356   // [else]
357   //     !%_IsJSReceiver(result = next.[[Call]](iterator, « »)) &&
358   //         %ThrowIteratorResultNotAnObject(result)
359   // [endif]
360   Expression* BuildIteratorNextResult(VariableProxy* iterator,
361                                       VariableProxy* next, Variable* result,
362                                       IteratorType type, int pos);
363 
364   // Initialize the components of a for-in / for-of statement.
365   Statement* InitializeForEachStatement(ForEachStatement* stmt,
366                                         Expression* each, Expression* subject,
367                                         Statement* body);
368   Statement* InitializeForOfStatement(ForOfStatement* stmt, Expression* each,
369                                       Expression* iterable, Statement* body,
370                                       bool finalize, IteratorType type,
371                                       int next_result_pos = kNoSourcePosition);
372 
373   Block* RewriteForVarInLegacy(const ForInfo& for_info);
374   void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block,
375                                         Expression** each_variable, bool* ok);
376   Block* CreateForEachStatementTDZ(Block* init_block, const ForInfo& for_info,
377                                    bool* ok);
378 
379   Statement* DesugarLexicalBindingsInForStatement(
380       ForStatement* loop, Statement* init, Expression* cond, Statement* next,
381       Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok);
382 
383   Expression* RewriteDoExpression(Block* body, int pos, bool* ok);
384 
385   FunctionLiteral* ParseFunctionLiteral(
386       const AstRawString* name, Scanner::Location function_name_location,
387       FunctionNameValidity function_name_validity, FunctionKind kind,
388       int function_token_position, FunctionLiteral::FunctionType type,
389       LanguageMode language_mode,
390       ZonePtrList<const AstRawString>* arguments_for_wrapped_function,
391       bool* ok);
392 
393   ObjectLiteral* InitializeObjectLiteral(ObjectLiteral* object_literal) {
394     object_literal->CalculateEmitStore(main_zone());
395     return object_literal;
396   }
397 
398   // Check if the scope has conflicting var/let declarations from different
399   // scopes. This covers for example
400   //
401   // function f() { { { var x; } let x; } }
402   // function g() { { var x; let x; } }
403   //
404   // The var declarations are hoisted to the function scope, but originate from
405   // a scope where the name has also been let bound or the var declaration is
406   // hoisted over such a scope.
407   void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
408 
409   bool IsPropertyWithPrivateFieldKey(Expression* property);
410 
411   // Insert initializer statements for var-bindings shadowing parameter bindings
412   // from a non-simple parameter list.
413   void InsertShadowingVarBindingInitializers(Block* block);
414 
415   // Implement sloppy block-scoped functions, ES2015 Annex B 3.3
416   void InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope);
417 
418   VariableProxy* NewUnresolved(const AstRawString* name, int begin_pos,
419                                VariableKind kind = NORMAL_VARIABLE);
420   VariableProxy* NewUnresolved(const AstRawString* name);
421   Variable* Declare(Declaration* declaration,
422                     DeclarationDescriptor::Kind declaration_kind,
423                     VariableMode mode, InitializationFlag init, bool* ok,
424                     Scope* declaration_scope = nullptr,
425                     int var_end_pos = kNoSourcePosition);
426   Declaration* DeclareVariable(const AstRawString* name, VariableMode mode,
427                                int pos, bool* ok);
428   Declaration* DeclareVariable(const AstRawString* name, VariableMode mode,
429                                InitializationFlag init, int pos, bool* ok);
430 
431   bool TargetStackContainsLabel(const AstRawString* label);
432   BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
433   IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
434 
435   Statement* BuildAssertIsCoercible(Variable* var, ObjectLiteral* pattern);
436 
437   // Factory methods.
438   FunctionLiteral* DefaultConstructor(const AstRawString* name, bool call_super,
439                                       int pos, int end_pos);
440 
441   // Skip over a lazy function, either using cached data if we have it, or
442   // by parsing the function with PreParser. Consumes the ending }.
443   // If may_abort == true, the (pre-)parser may decide to abort skipping
444   // in order to force the function to be eagerly parsed, after all.
445   LazyParsingResult SkipFunction(
446       const AstRawString* function_name, FunctionKind kind,
447       FunctionLiteral::FunctionType function_type,
448       DeclarationScope* function_scope, int* num_parameters,
449       ProducedPreParsedScopeData** produced_preparsed_scope_data,
450       bool is_inner_function, bool may_abort, bool* ok);
451 
452   Block* BuildParameterInitializationBlock(
453       const ParserFormalParameters& parameters, bool* ok);
454   Block* BuildRejectPromiseOnException(Block* block);
455 
456   ZonePtrList<Statement>* ParseFunction(
457       const AstRawString* function_name, int pos, FunctionKind kind,
458       FunctionLiteral::FunctionType function_type,
459       DeclarationScope* function_scope, int* num_parameters,
460       int* function_length, bool* has_duplicate_parameters,
461       int* expected_property_count, int* suspend_count,
462       ZonePtrList<const AstRawString>* arguments_for_wrapped_function,
463       bool* ok);
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       DCHECK_NOT_NULL(expression);
486       expressions_.Add(expression, zone);
487     }
488 
489    private:
490     ZonePtrList<const AstRawString> cooked_;
491     ZonePtrList<const AstRawString> raw_;
492     ZonePtrList<Expression> expressions_;
493     int pos_;
494   };
495 
496   typedef TemplateLiteral* TemplateLiteralState;
497 
498   TemplateLiteralState OpenTemplateLiteral(int pos);
499   // "should_cook" means that the span can be "cooked": in tagged template
500   // literals, both the raw and "cooked" representations are available to user
501   // code ("cooked" meaning that escape sequences are converted to their
502   // interpreted values). Invalid escape sequences cause the cooked span
503   // to be represented by undefined, instead of being a syntax error.
504   // "tail" indicates that this span is the last in the literal.
505   void AddTemplateSpan(TemplateLiteralState* state, bool should_cook,
506                        bool tail);
507   void AddTemplateExpression(TemplateLiteralState* state,
508                              Expression* expression);
509   Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
510                                    Expression* tag);
511 
512   ArrayLiteral* ArrayLiteralFromListWithSpread(ZonePtrList<Expression>* list);
513   Expression* SpreadCall(Expression* function, ZonePtrList<Expression>* args,
514                          int pos, Call::PossiblyEval is_possibly_eval);
515   Expression* SpreadCallNew(Expression* function, ZonePtrList<Expression>* args,
516                             int pos);
517   Expression* RewriteSuperCall(Expression* call_expression);
518 
519   void SetLanguageMode(Scope* scope, LanguageMode mode);
520   void SetAsmModule();
521 
522   // Rewrite all DestructuringAssignments in the current FunctionState.
523   V8_INLINE void RewriteDestructuringAssignments();
524 
525   Expression* RewriteSpreads(ArrayLiteral* lit);
526 
527   V8_INLINE void QueueDestructuringAssignmentForRewriting(
528       RewritableExpression* assignment);
529 
530   friend class InitializerRewriter;
531   void RewriteParameterInitializer(Expression* expr);
532 
533   Expression* BuildInitialYield(int pos, FunctionKind kind);
534   Assignment* BuildCreateJSGeneratorObject(int pos, FunctionKind kind);
535   Expression* BuildResolvePromise(Expression* value, int pos);
536   Expression* BuildRejectPromise(Expression* value, int pos);
537   Variable* PromiseVariable();
538   Variable* AsyncGeneratorAwaitVariable();
539 
540   // Generic AST generator for throwing errors from compiled code.
541   Expression* NewThrowError(Runtime::FunctionId function_id,
542                             MessageTemplate::Template message,
543                             const AstRawString* arg, int pos);
544 
545   void FinalizeIteratorUse(Variable* completion, Expression* condition,
546                            Variable* iter, Block* iterator_use, Block* result,
547                            IteratorType type);
548 
549   Statement* FinalizeForOfStatement(ForOfStatement* loop, Variable* completion,
550                                     IteratorType type, int pos);
551   void BuildIteratorClose(ZonePtrList<Statement>* statements,
552                           Variable* iterator, Variable* input, Variable* output,
553                           IteratorType type);
554   void BuildIteratorCloseForCompletion(ZonePtrList<Statement>* statements,
555                                        Variable* iterator,
556                                        Expression* completion,
557                                        IteratorType type);
558   Statement* CheckCallable(Variable* var, Expression* error, int pos);
559 
560   V8_INLINE void RewriteAsyncFunctionBody(ZonePtrList<Statement>* body,
561                                           Block* block,
562                                           Expression* return_value, bool* ok);
563 
564   void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters,
565                                         Expression* params, int end_pos,
566                                         bool* ok);
567   void SetFunctionName(Expression* value, const AstRawString* name,
568                        const AstRawString* prefix = nullptr);
569 
570   // Helper functions for recursive descent.
571   V8_INLINE bool IsEval(const AstRawString* identifier) const {
572     return identifier == ast_value_factory()->eval_string();
573   }
574 
575   V8_INLINE bool IsArguments(const AstRawString* identifier) const {
576     return identifier == ast_value_factory()->arguments_string();
577   }
578 
579   V8_INLINE bool IsEvalOrArguments(const AstRawString* identifier) const {
580     return IsEval(identifier) || IsArguments(identifier);
581   }
582 
583   // Returns true if the expression is of type "this.foo".
584   V8_INLINE static bool IsThisProperty(Expression* expression) {
585     DCHECK_NOT_NULL(expression);
586     Property* property = expression->AsProperty();
587     return property != nullptr && property->obj()->IsVariableProxy() &&
588            property->obj()->AsVariableProxy()->is_this();
589   }
590 
591   // This returns true if the expression is an indentifier (wrapped
592   // inside a variable proxy).  We exclude the case of 'this', which
593   // has been converted to a variable proxy.
594   V8_INLINE static bool IsIdentifier(Expression* expression) {
595     DCHECK_NOT_NULL(expression);
596     VariableProxy* operand = expression->AsVariableProxy();
597     return operand != nullptr && !operand->is_this() &&
598            !operand->is_new_target();
599   }
600 
601   V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) {
602     DCHECK(IsIdentifier(expression));
603     return expression->AsVariableProxy()->raw_name();
604   }
605 
606   V8_INLINE VariableProxy* AsIdentifierExpression(Expression* expression) {
607     return expression->AsVariableProxy();
608   }
609 
610   V8_INLINE bool IsConstructor(const AstRawString* identifier) const {
611     return identifier == ast_value_factory()->constructor_string();
612   }
613 
614   V8_INLINE bool IsName(const AstRawString* identifier) const {
615     return identifier == ast_value_factory()->name_string();
616   }
617 
618   V8_INLINE static bool IsBoilerplateProperty(
619       ObjectLiteral::Property* property) {
620     return !property->IsPrototype();
621   }
622 
623   V8_INLINE bool IsNative(Expression* expr) const {
624     DCHECK_NOT_NULL(expr);
625     return expr->IsVariableProxy() &&
626            expr->AsVariableProxy()->raw_name() ==
627                ast_value_factory()->native_string();
628   }
629 
630   V8_INLINE static bool IsArrayIndex(const AstRawString* string,
631                                      uint32_t* index) {
632     return string->AsArrayIndex(index);
633   }
634 
635   V8_INLINE bool IsUseStrictDirective(Statement* statement) const {
636     return IsStringLiteral(statement, ast_value_factory()->use_strict_string());
637   }
638 
639   V8_INLINE bool IsUseAsmDirective(Statement* statement) const {
640     return IsStringLiteral(statement, ast_value_factory()->use_asm_string());
641   }
642 
643   // Returns true if the statement is an expression statement containing
644   // a single string literal.  If a second argument is given, the literal
645   // is also compared with it and the result is true only if they are equal.
646   V8_INLINE bool IsStringLiteral(Statement* statement,
647                                  const AstRawString* arg = nullptr) const {
648     ExpressionStatement* e_stat = statement->AsExpressionStatement();
649     if (e_stat == nullptr) return false;
650     Literal* literal = e_stat->expression()->AsLiteral();
651     if (literal == nullptr || !literal->IsString()) return false;
652     return arg == nullptr || literal->AsRawString() == arg;
653   }
654 
655   V8_INLINE void GetDefaultStrings(
656       const AstRawString** default_string,
657       const AstRawString** star_default_star_string) {
658     *default_string = ast_value_factory()->default_string();
659     *star_default_star_string = ast_value_factory()->star_default_star_string();
660   }
661 
662   // Functions for encapsulating the differences between parsing and preparsing;
663   // operations interleaved with the recursive descent.
664   V8_INLINE void PushLiteralName(const AstRawString* id) {
665     DCHECK_NOT_NULL(fni_);
666     fni_->PushLiteralName(id);
667   }
668 
669   V8_INLINE void PushVariableName(const AstRawString* id) {
670     DCHECK_NOT_NULL(fni_);
671     fni_->PushVariableName(id);
672   }
673 
674   V8_INLINE void PushPropertyName(Expression* expression) {
675     DCHECK_NOT_NULL(fni_);
676     if (expression->IsPropertyName()) {
677       fni_->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
678     } else {
679       fni_->PushLiteralName(ast_value_factory()->anonymous_function_string());
680     }
681   }
682 
683   V8_INLINE void PushEnclosingName(const AstRawString* name) {
684     DCHECK_NOT_NULL(fni_);
685     fni_->PushEnclosingName(name);
686   }
687 
688   V8_INLINE void AddFunctionForNameInference(FunctionLiteral* func_to_infer) {
689     DCHECK_NOT_NULL(fni_);
690     fni_->AddFunction(func_to_infer);
691   }
692 
693   V8_INLINE void InferFunctionName() {
694     DCHECK_NOT_NULL(fni_);
695     fni_->Infer();
696   }
697 
698   // If we assign a function literal to a property we pretenure the
699   // literal so it can be added as a constant function property.
700   V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
701       Expression* left, Expression* right) {
702     DCHECK_NOT_NULL(left);
703     if (left->IsProperty() && right->IsFunctionLiteral()) {
704       right->AsFunctionLiteral()->set_pretenure();
705     }
706   }
707 
708   // Determine if the expression is a variable proxy and mark it as being used
709   // in an assignment or with a increment/decrement operator.
710   V8_INLINE static void MarkExpressionAsAssigned(Expression* expression) {
711     DCHECK_NOT_NULL(expression);
712     if (expression->IsVariableProxy()) {
713       expression->AsVariableProxy()->set_is_assigned();
714     }
715   }
716 
717   // A shortcut for performing a ToString operation
718   V8_INLINE Expression* ToString(Expression* expr) {
719     if (expr->IsStringLiteral()) return expr;
720     ZonePtrList<Expression>* args =
721         new (zone()) ZonePtrList<Expression>(1, zone());
722     args->Add(expr, zone());
723     return factory()->NewCallRuntime(Runtime::kInlineToString, args,
724                                      expr->position());
725   }
726 
727   // Returns true if we have a binary expression between two numeric
728   // literals. In that case, *x will be changed to an expression which is the
729   // computed value.
730   bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
731                                               Token::Value op, int pos);
732 
733   // Returns true if we have a binary operation between a binary/n-ary
734   // expression (with the same operation) and a value, which can be collapsed
735   // into a single n-ary expression. In that case, *x will be changed to an
736   // n-ary expression.
737   bool CollapseNaryExpression(Expression** x, Expression* y, Token::Value op,
738                               int pos, const SourceRange& range);
739 
740   // Returns a UnaryExpression or, in one of the following cases, a Literal.
741   // ! <literal> -> true / false
742   // + <Number literal> -> <Number literal>
743   // - <Number literal> -> <Number literal with value negated>
744   // ~ <literal> -> true / false
745   Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
746                                    int pos);
747 
748   // Generate AST node that throws a ReferenceError with the given type.
749   V8_INLINE Expression* NewThrowReferenceError(
750       MessageTemplate::Template message, int pos) {
751     return NewThrowError(Runtime::kNewReferenceError, message,
752                          ast_value_factory()->empty_string(), pos);
753   }
754 
755   // Generate AST node that throws a SyntaxError with the given
756   // type. The first argument may be null (in the handle sense) in
757   // which case no arguments are passed to the constructor.
758   V8_INLINE Expression* NewThrowSyntaxError(MessageTemplate::Template message,
759                                             const AstRawString* arg, int pos) {
760     return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
761   }
762 
763   // Generate AST node that throws a TypeError with the given
764   // type. Both arguments must be non-null (in the handle sense).
765   V8_INLINE Expression* NewThrowTypeError(MessageTemplate::Template message,
766                                           const AstRawString* arg, int pos) {
767     return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
768   }
769 
770   // Reporting errors.
771   void ReportMessageAt(Scanner::Location source_location,
772                        MessageTemplate::Template message,
773                        const char* arg = nullptr,
774                        ParseErrorType error_type = kSyntaxError) {
775     if (stack_overflow()) {
776       // Suppress the error message (syntax error or such) in the presence of a
777       // stack overflow. The isolate allows only one pending exception at at
778       // time
779       // and we want to report the stack overflow later.
780       return;
781     }
782     pending_error_handler()->ReportMessageAt(source_location.beg_pos,
783                                              source_location.end_pos, message,
784                                              arg, error_type);
785   }
786 
787   void ReportMessageAt(Scanner::Location source_location,
788                        MessageTemplate::Template message,
789                        const AstRawString* arg,
790                        ParseErrorType error_type = kSyntaxError) {
791     if (stack_overflow()) {
792       // Suppress the error message (syntax error or such) in the presence of a
793       // stack overflow. The isolate allows only one pending exception at at
794       // time
795       // and we want to report the stack overflow later.
796       return;
797     }
798     pending_error_handler()->ReportMessageAt(source_location.beg_pos,
799                                              source_location.end_pos, message,
800                                              arg, error_type);
801   }
802 
803   // "null" return type creators.
804   V8_INLINE static std::nullptr_t NullIdentifier() { return nullptr; }
805   V8_INLINE static std::nullptr_t NullExpression() { return nullptr; }
806   V8_INLINE static std::nullptr_t NullLiteralProperty() { return nullptr; }
807   V8_INLINE static ZonePtrList<Expression>* NullExpressionList() {
808     return nullptr;
809   }
810   V8_INLINE static ZonePtrList<Statement>* NullStatementList() {
811     return nullptr;
812   }
813   V8_INLINE static std::nullptr_t NullStatement() { return nullptr; }
814 
815   template <typename T>
816   V8_INLINE static bool IsNull(T subject) {
817     return subject == nullptr;
818   }
819 
820   // Non-null empty string.
821   V8_INLINE const AstRawString* EmptyIdentifierString() const {
822     return ast_value_factory()->empty_string();
823   }
824 
825   // Producing data during the recursive descent.
826   V8_INLINE const AstRawString* GetSymbol() const {
827     const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
828     DCHECK_NOT_NULL(result);
829     return result;
830   }
831 
832   V8_INLINE const AstRawString* GetNextSymbol() const {
833     return scanner()->NextSymbol(ast_value_factory());
834   }
835 
836   V8_INLINE const AstRawString* GetNumberAsSymbol() const {
837     double double_value = scanner()->DoubleValue();
838     char array[100];
839     const char* string = DoubleToCString(double_value, ArrayVector(array));
840     return ast_value_factory()->GetOneByteString(string);
841   }
842 
843   V8_INLINE Expression* ThisExpression(int pos = kNoSourcePosition) {
844     return NewUnresolved(ast_value_factory()->this_string(), pos,
845                          THIS_VARIABLE);
846   }
847 
848   Expression* NewSuperPropertyReference(int pos);
849   Expression* NewSuperCallReference(int pos);
850   Expression* NewTargetExpression(int pos);
851   Expression* ImportMetaExpression(int pos);
852 
853   Literal* ExpressionFromLiteral(Token::Value token, int pos);
854 
855   V8_INLINE VariableProxy* ExpressionFromIdentifier(
856       const AstRawString* name, int start_position,
857       InferName infer = InferName::kYes) {
858     if (infer == InferName::kYes) {
859       fni_->PushVariableName(name);
860     }
861     return NewUnresolved(name, start_position);
862   }
863 
864   V8_INLINE Expression* ExpressionFromString(int pos) {
865     const AstRawString* symbol = GetSymbol();
866     fni_->PushLiteralName(symbol);
867     return factory()->NewStringLiteral(symbol, pos);
868   }
869 
870   V8_INLINE ZonePtrList<Expression>* NewExpressionList(int size) const {
871     return new (zone()) ZonePtrList<Expression>(size, zone());
872   }
873   V8_INLINE ZonePtrList<ObjectLiteral::Property>* NewObjectPropertyList(
874       int size) const {
875     return new (zone()) ZonePtrList<ObjectLiteral::Property>(size, zone());
876   }
877   V8_INLINE ZonePtrList<ClassLiteral::Property>* NewClassPropertyList(
878       int size) const {
879     return new (zone()) ZonePtrList<ClassLiteral::Property>(size, zone());
880   }
881   V8_INLINE ZonePtrList<Statement>* NewStatementList(int size) const {
882     return new (zone()) ZonePtrList<Statement>(size, zone());
883   }
884 
885   V8_INLINE Expression* NewV8Intrinsic(const AstRawString* name,
886                                        ZonePtrList<Expression>* args, int pos,
887                                        bool* ok);
888 
889   V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) {
890     return factory()->NewExpressionStatement(
891         factory()->NewThrow(exception, pos), pos);
892   }
893 
894   V8_INLINE void AddParameterInitializationBlock(
895       const ParserFormalParameters& parameters, ZonePtrList<Statement>* body,
896       bool is_async, bool* ok) {
897     if (parameters.is_simple) return;
898     auto* init_block = BuildParameterInitializationBlock(parameters, ok);
899     if (!*ok) return;
900     if (is_async) {
901       init_block = BuildRejectPromiseOnException(init_block);
902     }
903     body->Add(init_block, zone());
904   }
905 
906   V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
907                                     Expression* pattern,
908                                     Expression* initializer,
909                                     int initializer_end_position,
910                                     bool is_rest) {
911     parameters->UpdateArityAndFunctionLength(initializer != nullptr, is_rest);
912     bool has_simple_name = pattern->IsVariableProxy() && initializer == nullptr;
913     const AstRawString* name = has_simple_name
914                                    ? pattern->AsVariableProxy()->raw_name()
915                                    : ast_value_factory()->empty_string();
916     auto parameter = new (parameters->scope->zone())
917         ParserFormalParameters::Parameter(name, pattern, initializer,
918                                           scanner()->location().beg_pos,
919                                           initializer_end_position, is_rest);
920 
921     parameters->params.Add(parameter);
922   }
923 
924   V8_INLINE void DeclareFormalParameters(
925       DeclarationScope* scope,
926       const ThreadedList<ParserFormalParameters::Parameter>& parameters,
927       bool is_simple, bool* has_duplicate = nullptr) {
928     if (!is_simple) scope->SetHasNonSimpleParameters();
929     for (auto parameter : parameters) {
930       bool is_optional = parameter->initializer != nullptr;
931       // If the parameter list is simple, declare the parameters normally with
932       // their names. If the parameter list is not simple, declare a temporary
933       // for each parameter - the corresponding named variable is declared by
934       // BuildParamerterInitializationBlock.
935       scope->DeclareParameter(
936           is_simple ? parameter->name : ast_value_factory()->empty_string(),
937           is_simple ? VariableMode::kVar : VariableMode::kTemporary,
938           is_optional, parameter->is_rest, has_duplicate, ast_value_factory(),
939           parameter->position);
940     }
941   }
942 
943   void DeclareArrowFunctionFormalParameters(ParserFormalParameters* parameters,
944                                             Expression* params,
945                                             const Scanner::Location& params_loc,
946                                             Scanner::Location* duplicate_loc,
947                                             bool* ok);
948 
949   Expression* ExpressionListToExpression(ZonePtrList<Expression>* args);
950 
951   void SetFunctionNameFromPropertyName(LiteralProperty* property,
952                                        const AstRawString* name,
953                                        const AstRawString* prefix = nullptr);
954   void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
955                                        const AstRawString* name,
956                                        const AstRawString* prefix = nullptr);
957 
958   void SetFunctionNameFromIdentifierRef(Expression* value,
959                                         Expression* identifier);
960 
961   V8_INLINE ZoneVector<typename ExpressionClassifier::Error>*
962   GetReportedErrorList() const {
963     return function_state_->GetReportedErrorList();
964   }
965 
966   V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
967     ++use_counts_[feature];
968   }
969 
970   // Returns true iff we're parsing the first function literal during
971   // CreateDynamicFunction().
972   V8_INLINE bool ParsingDynamicFunctionDeclaration() const {
973     return parameters_end_pos_ != kNoSourcePosition;
974   }
975 
976   V8_INLINE void ConvertBinaryToNaryOperationSourceRange(
977       BinaryOperation* binary_op, NaryOperation* nary_op) {
978     if (source_range_map_ == nullptr) return;
979     DCHECK_NULL(source_range_map_->Find(nary_op));
980 
981     BinaryOperationSourceRanges* ranges =
982         static_cast<BinaryOperationSourceRanges*>(
983             source_range_map_->Find(binary_op));
984     if (ranges == nullptr) return;
985 
986     SourceRange range = ranges->GetRange(SourceRangeKind::kRight);
987     source_range_map_->Insert(
988         nary_op, new (zone()) NaryOperationSourceRanges(zone(), range));
989   }
990 
991   V8_INLINE void AppendNaryOperationSourceRange(NaryOperation* node,
992                                                 const SourceRange& range) {
993     if (source_range_map_ == nullptr) return;
994     NaryOperationSourceRanges* ranges =
995         static_cast<NaryOperationSourceRanges*>(source_range_map_->Find(node));
996     if (ranges == nullptr) return;
997 
998     ranges->AddRange(range);
999     DCHECK_EQ(node->subsequent_length(), ranges->RangeCount());
1000   }
1001 
1002   V8_INLINE void RecordBlockSourceRange(Block* node,
1003                                         int32_t continuation_position) {
1004     if (source_range_map_ == nullptr) return;
1005     source_range_map_->Insert(
1006         node, new (zone()) BlockSourceRanges(continuation_position));
1007   }
1008 
1009   V8_INLINE void RecordCaseClauseSourceRange(CaseClause* node,
1010                                              const SourceRange& body_range) {
1011     if (source_range_map_ == nullptr) return;
1012     source_range_map_->Insert(node,
1013                               new (zone()) CaseClauseSourceRanges(body_range));
1014   }
1015 
1016   V8_INLINE void RecordConditionalSourceRange(Expression* node,
1017                                               const SourceRange& then_range,
1018                                               const SourceRange& else_range) {
1019     if (source_range_map_ == nullptr) return;
1020     source_range_map_->Insert(
1021         node->AsConditional(),
1022         new (zone()) ConditionalSourceRanges(then_range, else_range));
1023   }
1024 
1025   V8_INLINE void RecordBinaryOperationSourceRange(
1026       Expression* node, const SourceRange& right_range) {
1027     if (source_range_map_ == nullptr) return;
1028     source_range_map_->Insert(node->AsBinaryOperation(),
1029                               new (zone())
1030                                   BinaryOperationSourceRanges(right_range));
1031   }
1032 
1033   V8_INLINE void RecordJumpStatementSourceRange(Statement* node,
1034                                                 int32_t continuation_position) {
1035     if (source_range_map_ == nullptr) return;
1036     source_range_map_->Insert(
1037         static_cast<JumpStatement*>(node),
1038         new (zone()) JumpStatementSourceRanges(continuation_position));
1039   }
1040 
1041   V8_INLINE void RecordIfStatementSourceRange(Statement* node,
1042                                               const SourceRange& then_range,
1043                                               const SourceRange& else_range) {
1044     if (source_range_map_ == nullptr) return;
1045     source_range_map_->Insert(
1046         node->AsIfStatement(),
1047         new (zone()) IfStatementSourceRanges(then_range, else_range));
1048   }
1049 
1050   V8_INLINE void RecordIterationStatementSourceRange(
1051       IterationStatement* node, const SourceRange& body_range) {
1052     if (source_range_map_ == nullptr) return;
1053     source_range_map_->Insert(
1054         node, new (zone()) IterationStatementSourceRanges(body_range));
1055   }
1056 
1057   V8_INLINE void RecordSuspendSourceRange(Expression* node,
1058                                           int32_t continuation_position) {
1059     if (source_range_map_ == nullptr) return;
1060     source_range_map_->Insert(static_cast<Suspend*>(node),
1061                               new (zone())
1062                                   SuspendSourceRanges(continuation_position));
1063   }
1064 
1065   V8_INLINE void RecordSwitchStatementSourceRange(
1066       Statement* node, int32_t continuation_position) {
1067     if (source_range_map_ == nullptr) return;
1068     source_range_map_->Insert(
1069         node->AsSwitchStatement(),
1070         new (zone()) SwitchStatementSourceRanges(continuation_position));
1071   }
1072 
1073   V8_INLINE void RecordThrowSourceRange(Statement* node,
1074                                         int32_t continuation_position) {
1075     if (source_range_map_ == nullptr) return;
1076     ExpressionStatement* expr_stmt = static_cast<ExpressionStatement*>(node);
1077     Throw* throw_expr = expr_stmt->expression()->AsThrow();
1078     source_range_map_->Insert(
1079         throw_expr, new (zone()) ThrowSourceRanges(continuation_position));
1080   }
1081 
1082   V8_INLINE void RecordTryCatchStatementSourceRange(
1083       TryCatchStatement* node, const SourceRange& body_range) {
1084     if (source_range_map_ == nullptr) return;
1085     source_range_map_->Insert(
1086         node, new (zone()) TryCatchStatementSourceRanges(body_range));
1087   }
1088 
1089   V8_INLINE void RecordTryFinallyStatementSourceRange(
1090       TryFinallyStatement* node, const SourceRange& body_range) {
1091     if (source_range_map_ == nullptr) return;
1092     source_range_map_->Insert(
1093         node, new (zone()) TryFinallyStatementSourceRanges(body_range));
1094   }
1095 
1096   // Parser's private field members.
1097   friend class DiscardableZoneScope;  // Uses reusable_preparser_.
1098   // FIXME(marja): Make reusable_preparser_ always use its own temp Zone (call
1099   // DeleteAll after each function), so this won't be needed.
1100 
1101   Scanner scanner_;
1102   PreParser* reusable_preparser_;
1103   Mode mode_;
1104 
1105   SourceRangeMap* source_range_map_ = nullptr;
1106 
1107   friend class ParserTarget;
1108   friend class ParserTargetScope;
1109   ParserTarget* target_stack_;  // for break, continue statements
1110 
1111   ScriptCompiler::CompileOptions compile_options_;
1112 
1113   // Other information which will be stored in Parser and moved to Isolate after
1114   // parsing.
1115   int use_counts_[v8::Isolate::kUseCounterFeatureCount];
1116   int total_preparse_skipped_;
1117   bool allow_lazy_;
1118   bool temp_zoned_;
1119   ConsumedPreParsedScopeData* consumed_preparsed_scope_data_;
1120 
1121   // If not kNoSourcePosition, indicates that the first function literal
1122   // encountered is a dynamic function, see CreateDynamicFunction(). This field
1123   // indicates the correct position of the ')' that closes the parameter list.
1124   // After that ')' is encountered, this field is reset to kNoSourcePosition.
1125   int parameters_end_pos_;
1126 };
1127 
1128 // ----------------------------------------------------------------------------
1129 // Target is a support class to facilitate manipulation of the
1130 // Parser's target_stack_ (the stack of potential 'break' and
1131 // 'continue' statement targets). Upon construction, a new target is
1132 // added; it is removed upon destruction.
1133 
1134 class ParserTarget BASE_EMBEDDED {
1135  public:
1136   ParserTarget(ParserBase<Parser>* parser, BreakableStatement* statement)
1137       : variable_(&parser->impl()->target_stack_),
1138         statement_(statement),
1139         previous_(parser->impl()->target_stack_) {
1140     parser->impl()->target_stack_ = this;
1141   }
1142 
1143   ~ParserTarget() { *variable_ = previous_; }
1144 
1145   ParserTarget* previous() { return previous_; }
1146   BreakableStatement* statement() { return statement_; }
1147 
1148  private:
1149   ParserTarget** variable_;
1150   BreakableStatement* statement_;
1151   ParserTarget* previous_;
1152 };
1153 
1154 class ParserTargetScope BASE_EMBEDDED {
1155  public:
1156   explicit ParserTargetScope(ParserBase<Parser>* parser)
1157       : variable_(&parser->impl()->target_stack_),
1158         previous_(parser->impl()->target_stack_) {
1159     parser->impl()->target_stack_ = nullptr;
1160   }
1161 
1162   ~ParserTargetScope() { *variable_ = previous_; }
1163 
1164  private:
1165   ParserTarget** variable_;
1166   ParserTarget* previous_;
1167 };
1168 
1169 }  // namespace internal
1170 }  // namespace v8
1171 
1172 #endif  // V8_PARSING_PARSER_H_
1173