• 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 "src/ast/ast.h"
9 #include "src/ast/scopes.h"
10 #include "src/base/compiler-specific.h"
11 #include "src/globals.h"
12 #include "src/parsing/parser-base.h"
13 #include "src/parsing/preparse-data-format.h"
14 #include "src/parsing/preparse-data.h"
15 #include "src/parsing/preparser.h"
16 #include "src/pending-compilation-error-handler.h"
17 
18 namespace v8 {
19 
20 class ScriptCompiler;
21 
22 namespace internal {
23 
24 class ParseInfo;
25 class ScriptData;
26 class ParserTarget;
27 class ParserTargetScope;
28 
29 class FunctionEntry BASE_EMBEDDED {
30  public:
31   enum {
32     kStartPositionIndex,
33     kEndPositionIndex,
34     kNumParametersIndex,
35     kFunctionLengthIndex,
36     kLiteralCountIndex,
37     kPropertyCountIndex,
38     kFlagsIndex,
39     kSize
40   };
41 
FunctionEntry(Vector<unsigned> backing)42   explicit FunctionEntry(Vector<unsigned> backing)
43     : backing_(backing) { }
44 
FunctionEntry()45   FunctionEntry() : backing_() { }
46 
47   class LanguageModeField : public BitField<LanguageMode, 0, 1> {};
48   class UsesSuperPropertyField
49       : public BitField<bool, LanguageModeField::kNext, 1> {};
50   class CallsEvalField
51       : public BitField<bool, UsesSuperPropertyField::kNext, 1> {};
52   class HasDuplicateParametersField
53       : public BitField<bool, CallsEvalField::kNext, 1> {};
54 
EncodeFlags(LanguageMode language_mode,bool uses_super_property,bool calls_eval,bool has_duplicate_parameters)55   static uint32_t EncodeFlags(LanguageMode language_mode,
56                               bool uses_super_property, bool calls_eval,
57                               bool has_duplicate_parameters) {
58     return LanguageModeField::encode(language_mode) |
59            UsesSuperPropertyField::encode(uses_super_property) |
60            CallsEvalField::encode(calls_eval) |
61            HasDuplicateParametersField::encode(has_duplicate_parameters);
62   }
63 
start_pos()64   int start_pos() const { return backing_[kStartPositionIndex]; }
end_pos()65   int end_pos() const { return backing_[kEndPositionIndex]; }
num_parameters()66   int num_parameters() const { return backing_[kNumParametersIndex]; }
function_length()67   int function_length() const { return backing_[kFunctionLengthIndex]; }
literal_count()68   int literal_count() const { return backing_[kLiteralCountIndex]; }
property_count()69   int property_count() const { return backing_[kPropertyCountIndex]; }
language_mode()70   LanguageMode language_mode() const {
71     return LanguageModeField::decode(backing_[kFlagsIndex]);
72   }
uses_super_property()73   bool uses_super_property() const {
74     return UsesSuperPropertyField::decode(backing_[kFlagsIndex]);
75   }
calls_eval()76   bool calls_eval() const {
77     return CallsEvalField::decode(backing_[kFlagsIndex]);
78   }
has_duplicate_parameters()79   bool has_duplicate_parameters() const {
80     return HasDuplicateParametersField::decode(backing_[kFlagsIndex]);
81   }
82 
is_valid()83   bool is_valid() const { return !backing_.is_empty(); }
84 
85  private:
86   Vector<unsigned> backing_;
87 };
88 
89 
90 // Wrapper around ScriptData to provide parser-specific functionality.
91 class ParseData {
92  public:
FromCachedData(ScriptData * cached_data)93   static ParseData* FromCachedData(ScriptData* cached_data) {
94     ParseData* pd = new ParseData(cached_data);
95     if (pd->IsSane()) return pd;
96     cached_data->Reject();
97     delete pd;
98     return NULL;
99   }
100 
101   void Initialize();
102   FunctionEntry GetFunctionEntry(int start);
103   int FunctionCount();
104 
Data()105   unsigned* Data() {  // Writable data as unsigned int array.
106     return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
107   }
108 
Reject()109   void Reject() { script_data_->Reject(); }
110 
rejected()111   bool rejected() const { return script_data_->rejected(); }
112 
113  private:
ParseData(ScriptData * script_data)114   explicit ParseData(ScriptData* script_data) : script_data_(script_data) {}
115 
116   bool IsSane();
117   unsigned Magic();
118   unsigned Version();
119   int FunctionsSize();
Length()120   int Length() const {
121     // Script data length is already checked to be a multiple of unsigned size.
122     return script_data_->length() / sizeof(unsigned);
123   }
124 
125   ScriptData* script_data_;
126   int function_index_;
127 
128   DISALLOW_COPY_AND_ASSIGN(ParseData);
129 };
130 
131 // ----------------------------------------------------------------------------
132 // JAVASCRIPT PARSING
133 
134 class Parser;
135 
136 
137 struct ParserFormalParameters : FormalParametersBase {
138   struct Parameter {
ParameterParserFormalParameters::Parameter139     Parameter(const AstRawString* name, Expression* pattern,
140               Expression* initializer, int initializer_end_position,
141               bool is_rest)
142         : name(name),
143           pattern(pattern),
144           initializer(initializer),
145           initializer_end_position(initializer_end_position),
146           is_rest(is_rest) {}
147     const AstRawString* name;
148     Expression* pattern;
149     Expression* initializer;
150     int initializer_end_position;
151     bool is_rest;
is_simpleParserFormalParameters::Parameter152     bool is_simple() const {
153       return pattern->IsVariableProxy() && initializer == nullptr && !is_rest;
154     }
155   };
156 
ParserFormalParametersParserFormalParameters157   explicit ParserFormalParameters(DeclarationScope* scope)
158       : FormalParametersBase(scope), params(4, scope->zone()) {}
159   ZoneList<Parameter> params;
160 
atParserFormalParameters161   const Parameter& at(int i) const { return params[i]; }
162 };
163 
164 template <>
165 struct ParserTypes<Parser> {
166   typedef ParserBase<Parser> Base;
167   typedef Parser Impl;
168 
169   typedef v8::internal::Variable Variable;
170 
171   // Return types for traversing functions.
172   typedef const AstRawString* Identifier;
173   typedef v8::internal::Expression* Expression;
174   typedef v8::internal::FunctionLiteral* FunctionLiteral;
175   typedef ObjectLiteral::Property* ObjectLiteralProperty;
176   typedef ClassLiteral::Property* ClassLiteralProperty;
177   typedef ZoneList<v8::internal::Expression*>* ExpressionList;
178   typedef ZoneList<ObjectLiteral::Property*>* ObjectPropertyList;
179   typedef ZoneList<ClassLiteral::Property*>* ClassPropertyList;
180   typedef ParserFormalParameters FormalParameters;
181   typedef v8::internal::Statement* Statement;
182   typedef ZoneList<v8::internal::Statement*>* StatementList;
183   typedef v8::internal::Block* Block;
184   typedef v8::internal::BreakableStatement* BreakableStatement;
185   typedef v8::internal::IterationStatement* IterationStatement;
186 
187   // For constructing objects returned by the traversing functions.
188   typedef AstNodeFactory Factory;
189 
190   typedef ParserTarget Target;
191   typedef ParserTargetScope TargetScope;
192 };
193 
194 class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
195  public:
196   explicit Parser(ParseInfo* info);
197   ~Parser() {
198     delete reusable_preparser_;
199     reusable_preparser_ = NULL;
200     delete cached_parse_data_;
201     cached_parse_data_ = NULL;
202   }
203 
204   static bool const IsPreParser() { return false; }
205 
206   // Parses the source code represented by the compilation info and sets its
207   // function literal.  Returns false (and deallocates any allocated AST
208   // nodes) if parsing failed.
209   static bool ParseStatic(ParseInfo* info);
210   bool Parse(ParseInfo* info);
211   void ParseOnBackground(ParseInfo* info);
212 
213   // Deserialize the scope chain prior to parsing in which the script is going
214   // to be executed. If the script is a top-level script, or the scope chain
215   // consists of only a native context, maybe_outer_scope_info should be an
216   // empty handle.
217   //
218   // This only deserializes the scope chain, but doesn't connect the scopes to
219   // their corresponding scope infos. Therefore, looking up variables in the
220   // deserialized scopes is not possible.
221   void DeserializeScopeChain(ParseInfo* info,
222                              MaybeHandle<ScopeInfo> maybe_outer_scope_info);
223 
224   // Handle errors detected during parsing, move statistics to Isolate,
225   // internalize strings (move them to the heap).
226   void Internalize(Isolate* isolate, Handle<Script> script, bool error);
227   void HandleSourceURLComments(Isolate* isolate, Handle<Script> script);
228 
229  private:
230   friend class ParserBase<Parser>;
231   friend class v8::internal::ExpressionClassifier<ParserTypes<Parser>>;
232 
233   bool AllowsLazyParsingWithoutUnresolvedVariables() const {
234     return scope()->AllowsLazyParsingWithoutUnresolvedVariables(
235         original_scope_);
236   }
237 
238   bool parse_lazily() const { return mode_ == PARSE_LAZILY; }
239   enum Mode { PARSE_LAZILY, PARSE_EAGERLY };
240 
241   class ParsingModeScope BASE_EMBEDDED {
242    public:
243     ParsingModeScope(Parser* parser, Mode mode)
244         : parser_(parser), old_mode_(parser->mode_) {
245       parser_->mode_ = mode;
246     }
247     ~ParsingModeScope() { parser_->mode_ = old_mode_; }
248 
249    private:
250     Parser* parser_;
251     Mode old_mode_;
252   };
253 
254   // Runtime encoding of different completion modes.
255   enum CompletionKind {
256     kNormalCompletion,
257     kThrowCompletion,
258     kAbruptCompletion
259   };
260 
261   Variable* NewTemporary(const AstRawString* name) {
262     return scope()->NewTemporary(name);
263   }
264 
265   void PrepareGeneratorVariables(FunctionState* function_state);
266 
267   // Limit the allowed number of local variables in a function. The hard limit
268   // is that offsets computed by FullCodeGenerator::StackOperand and similar
269   // functions are ints, and they should not overflow. In addition, accessing
270   // local variables creates user-controlled constants in the generated code,
271   // and we don't want too much user-controlled memory inside the code (this was
272   // the reason why this limit was introduced in the first place; see
273   // https://codereview.chromium.org/7003030/ ).
274   static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
275 
276   // Returns NULL if parsing failed.
277   FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info);
278 
279   FunctionLiteral* ParseFunction(Isolate* isolate, ParseInfo* info);
280   FunctionLiteral* DoParseFunction(ParseInfo* info,
281                                    const AstRawString* raw_name,
282                                    Utf16CharacterStream* source);
283 
284   // Called by ParseProgram after setting up the scanner.
285   FunctionLiteral* DoParseProgram(ParseInfo* info);
286 
287   void SetCachedData(ParseInfo* info);
288 
289   ScriptCompiler::CompileOptions compile_options() const {
290     return compile_options_;
291   }
292   bool consume_cached_parse_data() const {
293     return allow_lazy() &&
294            compile_options_ == ScriptCompiler::kConsumeParserCache;
295   }
296   bool produce_cached_parse_data() const {
297     return allow_lazy() &&
298            compile_options_ == ScriptCompiler::kProduceParserCache;
299   }
300 
301   void ParseModuleItemList(ZoneList<Statement*>* body, bool* ok);
302   Statement* ParseModuleItem(bool* ok);
303   const AstRawString* ParseModuleSpecifier(bool* ok);
304   void ParseImportDeclaration(bool* ok);
305   Statement* ParseExportDeclaration(bool* ok);
306   Statement* ParseExportDefault(bool* ok);
307   void ParseExportClause(ZoneList<const AstRawString*>* export_names,
308                          ZoneList<Scanner::Location>* export_locations,
309                          ZoneList<const AstRawString*>* local_names,
310                          Scanner::Location* reserved_loc, bool* ok);
311   struct NamedImport : public ZoneObject {
312     const AstRawString* import_name;
313     const AstRawString* local_name;
314     const Scanner::Location location;
315     NamedImport(const AstRawString* import_name, const AstRawString* local_name,
316                 Scanner::Location location)
317         : import_name(import_name),
318           local_name(local_name),
319           location(location) {}
320   };
321   ZoneList<const NamedImport*>* ParseNamedImports(int pos, bool* ok);
322   Block* BuildInitializationBlock(DeclarationParsingResult* parsing_result,
323                                   ZoneList<const AstRawString*>* names,
324                                   bool* ok);
325   void DeclareAndInitializeVariables(
326       Block* block, const DeclarationDescriptor* declaration_descriptor,
327       const DeclarationParsingResult::Declaration* declaration,
328       ZoneList<const AstRawString*>* names, bool* ok);
329   ZoneList<const AstRawString*>* DeclareLabel(
330       ZoneList<const AstRawString*>* labels, VariableProxy* expr, bool* ok);
331   bool ContainsLabel(ZoneList<const AstRawString*>* labels,
332                      const AstRawString* label);
333   Expression* RewriteReturn(Expression* return_value, int pos);
334   Statement* RewriteSwitchStatement(Expression* tag,
335                                     SwitchStatement* switch_statement,
336                                     ZoneList<CaseClause*>* cases, Scope* scope);
337   void RewriteCatchPattern(CatchInfo* catch_info, bool* ok);
338   void ValidateCatchBlock(const CatchInfo& catch_info, bool* ok);
339   Statement* RewriteTryStatement(Block* try_block, Block* catch_block,
340                                  Block* finally_block,
341                                  const CatchInfo& catch_info, int pos);
342 
343   Statement* DeclareFunction(const AstRawString* variable_name,
344                              FunctionLiteral* function, int pos,
345                              bool is_generator, bool is_async,
346                              ZoneList<const AstRawString*>* names, bool* ok);
347   V8_INLINE Statement* DeclareClass(const AstRawString* variable_name,
348                                     Expression* value,
349                                     ZoneList<const AstRawString*>* names,
350                                     int class_token_pos, int end_pos, bool* ok);
351   V8_INLINE void DeclareClassVariable(const AstRawString* name,
352                                       Scope* block_scope, ClassInfo* class_info,
353                                       int class_token_pos, bool* ok);
354   V8_INLINE void DeclareClassProperty(const AstRawString* class_name,
355                                       ClassLiteralProperty* property,
356                                       ClassInfo* class_info, bool* ok);
357   V8_INLINE Expression* RewriteClassLiteral(const AstRawString* name,
358                                             ClassInfo* class_info, int pos,
359                                             bool* ok);
360   V8_INLINE Statement* DeclareNative(const AstRawString* name, int pos,
361                                      bool* ok);
362 
363   class PatternRewriter final : public AstVisitor<PatternRewriter> {
364    public:
365     static void DeclareAndInitializeVariables(
366         Parser* parser, Block* block,
367         const DeclarationDescriptor* declaration_descriptor,
368         const DeclarationParsingResult::Declaration* declaration,
369         ZoneList<const AstRawString*>* names, bool* ok);
370 
371     static void RewriteDestructuringAssignment(Parser* parser,
372                                                RewritableExpression* expr,
373                                                Scope* Scope);
374 
375     static Expression* RewriteDestructuringAssignment(Parser* parser,
376                                                       Assignment* assignment,
377                                                       Scope* scope);
378 
379    private:
380     PatternRewriter() {}
381 
382 #define DECLARE_VISIT(type) void Visit##type(v8::internal::type* node);
383     // Visiting functions for AST nodes make this an AstVisitor.
384     AST_NODE_LIST(DECLARE_VISIT)
385 #undef DECLARE_VISIT
386 
387     enum PatternContext {
388       BINDING,
389       INITIALIZER,
390       ASSIGNMENT,
391       ASSIGNMENT_INITIALIZER
392     };
393 
394     PatternContext context() const { return context_; }
395     void set_context(PatternContext context) { context_ = context; }
396 
397     void RecurseIntoSubpattern(AstNode* pattern, Expression* value) {
398       Expression* old_value = current_value_;
399       current_value_ = value;
400       recursion_level_++;
401       Visit(pattern);
402       recursion_level_--;
403       current_value_ = old_value;
404     }
405 
406     void VisitObjectLiteral(ObjectLiteral* node, Variable** temp_var);
407     void VisitArrayLiteral(ArrayLiteral* node, Variable** temp_var);
408 
409     bool IsBindingContext() const {
410       return context_ == BINDING || context_ == INITIALIZER;
411     }
412     bool IsInitializerContext() const { return context_ != ASSIGNMENT; }
413     bool IsAssignmentContext() const {
414       return context_ == ASSIGNMENT || context_ == ASSIGNMENT_INITIALIZER;
415     }
416     bool IsSubPattern() const { return recursion_level_ > 1; }
417     PatternContext SetAssignmentContextIfNeeded(Expression* node);
418     PatternContext SetInitializerContextIfNeeded(Expression* node);
419 
420     void RewriteParameterScopes(Expression* expr);
421 
422     Variable* CreateTempVar(Expression* value = nullptr);
423 
424     AstNodeFactory* factory() const { return parser_->factory(); }
425     AstValueFactory* ast_value_factory() const {
426       return parser_->ast_value_factory();
427     }
428     Zone* zone() const { return parser_->zone(); }
429     Scope* scope() const { return scope_; }
430 
431     Scope* scope_;
432     Parser* parser_;
433     PatternContext context_;
434     Expression* pattern_;
435     int initializer_position_;
436     Block* block_;
437     const DeclarationDescriptor* descriptor_;
438     ZoneList<const AstRawString*>* names_;
439     Expression* current_value_;
440     int recursion_level_;
441     bool* ok_;
442 
443     DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW()
444   };
445 
446   // !%_IsJSReceiver(result = iterator.next()) &&
447   //     %ThrowIteratorResultNotAnObject(result)
448   Expression* BuildIteratorNextResult(Expression* iterator, Variable* result,
449                                       int pos);
450 
451   Expression* GetIterator(Expression* iterable, int pos);
452 
453   // Initialize the components of a for-in / for-of statement.
454   Statement* InitializeForEachStatement(ForEachStatement* stmt,
455                                         Expression* each, Expression* subject,
456                                         Statement* body, int each_keyword_pos);
457   Statement* InitializeForOfStatement(ForOfStatement* stmt, Expression* each,
458                                       Expression* iterable, Statement* body,
459                                       bool finalize,
460                                       int next_result_pos = kNoSourcePosition);
461   Block* RewriteForVarInLegacy(const ForInfo& for_info);
462   void DesugarBindingInForEachStatement(ForInfo* for_info, Block** body_block,
463                                         Expression** each_variable, bool* ok);
464   Block* CreateForEachStatementTDZ(Block* init_block, const ForInfo& for_info,
465                                    bool* ok);
466 
467   Statement* DesugarLexicalBindingsInForStatement(
468       ForStatement* loop, Statement* init, Expression* cond, Statement* next,
469       Statement* body, Scope* inner_scope, const ForInfo& for_info, bool* ok);
470 
471   Expression* RewriteDoExpression(Block* body, int pos, bool* ok);
472 
473   FunctionLiteral* ParseFunctionLiteral(
474       const AstRawString* name, Scanner::Location function_name_location,
475       FunctionNameValidity function_name_validity, FunctionKind kind,
476       int function_token_position, FunctionLiteral::FunctionType type,
477       LanguageMode language_mode, bool* ok);
478 
479   Expression* InstallHomeObject(Expression* function_literal,
480                                 Expression* home_object);
481   FunctionLiteral* SynthesizeClassFieldInitializer(int count);
482   FunctionLiteral* InsertClassFieldInitializer(FunctionLiteral* constructor);
483 
484   // Get odd-ball literals.
485   Literal* GetLiteralUndefined(int position);
486 
487   // Check if the scope has conflicting var/let declarations from different
488   // scopes. This covers for example
489   //
490   // function f() { { { var x; } let x; } }
491   // function g() { { var x; let x; } }
492   //
493   // The var declarations are hoisted to the function scope, but originate from
494   // a scope where the name has also been let bound or the var declaration is
495   // hoisted over such a scope.
496   void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
497 
498   // Insert initializer statements for var-bindings shadowing parameter bindings
499   // from a non-simple parameter list.
500   void InsertShadowingVarBindingInitializers(Block* block);
501 
502   // Implement sloppy block-scoped functions, ES2015 Annex B 3.3
503   void InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope);
504 
505   VariableProxy* NewUnresolved(const AstRawString* name, int begin_pos,
506                                VariableKind kind = NORMAL_VARIABLE);
507   VariableProxy* NewUnresolved(const AstRawString* name);
508   Variable* Declare(Declaration* declaration,
509                     DeclarationDescriptor::Kind declaration_kind,
510                     VariableMode mode, InitializationFlag init, bool* ok,
511                     Scope* declaration_scope = nullptr,
512                     int var_end_pos = kNoSourcePosition);
513   Declaration* DeclareVariable(const AstRawString* name, VariableMode mode,
514                                int pos, bool* ok);
515   Declaration* DeclareVariable(const AstRawString* name, VariableMode mode,
516                                InitializationFlag init, int pos, bool* ok);
517 
518   bool TargetStackContainsLabel(const AstRawString* label);
519   BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
520   IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
521 
522   Statement* BuildAssertIsCoercible(Variable* var);
523 
524   // Factory methods.
525   FunctionLiteral* DefaultConstructor(const AstRawString* name, bool call_super,
526                                       bool requires_class_field_init, int pos,
527                                       int end_pos, LanguageMode language_mode);
528 
529   // Skip over a lazy function, either using cached data if we have it, or
530   // by parsing the function with PreParser. Consumes the ending }.
531   // If may_abort == true, the (pre-)parser may decide to abort skipping
532   // in order to force the function to be eagerly parsed, after all.
533   LazyParsingResult SkipFunction(
534       FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
535       int* function_length, bool* has_duplicate_parameters,
536       int* materialized_literal_count, int* expected_property_count,
537       bool is_inner_function, bool may_abort, bool* ok);
538 
539   Block* BuildParameterInitializationBlock(
540       const ParserFormalParameters& parameters, bool* ok);
541   Block* BuildRejectPromiseOnException(Block* block, bool* ok);
542 
543   // Consumes the ending }.
544   ZoneList<Statement*>* ParseEagerFunctionBody(
545       const AstRawString* function_name, int pos,
546       const ParserFormalParameters& parameters, FunctionKind kind,
547       FunctionLiteral::FunctionType function_type, bool* ok);
548 
549   ZoneList<Statement*>* ParseFunction(
550       const AstRawString* function_name, int pos, FunctionKind kind,
551       FunctionLiteral::FunctionType function_type,
552       DeclarationScope* function_scope, int* num_parameters,
553       int* function_length, bool* has_duplicate_parameters,
554       int* materialized_literal_count, int* expected_property_count, bool* ok);
555 
556   void ThrowPendingError(Isolate* isolate, Handle<Script> script);
557 
558   class TemplateLiteral : public ZoneObject {
559    public:
560     TemplateLiteral(Zone* zone, int pos)
561         : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
562 
563     const ZoneList<Expression*>* cooked() const { return &cooked_; }
564     const ZoneList<Expression*>* raw() const { return &raw_; }
565     const ZoneList<Expression*>* expressions() const { return &expressions_; }
566     int position() const { return pos_; }
567 
568     void AddTemplateSpan(Literal* cooked, Literal* raw, int end, Zone* zone) {
569       DCHECK_NOT_NULL(cooked);
570       DCHECK_NOT_NULL(raw);
571       cooked_.Add(cooked, zone);
572       raw_.Add(raw, zone);
573     }
574 
575     void AddExpression(Expression* expression, Zone* zone) {
576       DCHECK_NOT_NULL(expression);
577       expressions_.Add(expression, zone);
578     }
579 
580    private:
581     ZoneList<Expression*> cooked_;
582     ZoneList<Expression*> raw_;
583     ZoneList<Expression*> expressions_;
584     int pos_;
585   };
586 
587   typedef TemplateLiteral* TemplateLiteralState;
588 
589   TemplateLiteralState OpenTemplateLiteral(int pos);
590   void AddTemplateSpan(TemplateLiteralState* state, bool tail);
591   void AddTemplateExpression(TemplateLiteralState* state,
592                              Expression* expression);
593   Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
594                                    Expression* tag);
595   uint32_t ComputeTemplateLiteralHash(const TemplateLiteral* lit);
596 
597   ZoneList<Expression*>* PrepareSpreadArguments(ZoneList<Expression*>* list);
598   Expression* SpreadCall(Expression* function, ZoneList<Expression*>* args,
599                          int pos);
600   Expression* SpreadCallNew(Expression* function, ZoneList<Expression*>* args,
601                             int pos);
602   Expression* CallClassFieldInitializer(Scope* scope, Expression* this_expr);
603   Expression* RewriteSuperCall(Expression* call_expression);
604 
605   void SetLanguageMode(Scope* scope, LanguageMode mode);
606   void SetAsmModule();
607 
608   V8_INLINE void MarkCollectedTailCallExpressions();
609   V8_INLINE void MarkTailPosition(Expression* expression);
610 
611   // Rewrite all DestructuringAssignments in the current FunctionState.
612   V8_INLINE void RewriteDestructuringAssignments();
613 
614   V8_INLINE Expression* RewriteExponentiation(Expression* left,
615                                               Expression* right, int pos);
616   V8_INLINE Expression* RewriteAssignExponentiation(Expression* left,
617                                                     Expression* right, int pos);
618 
619   friend class NonPatternRewriter;
620   V8_INLINE Expression* RewriteSpreads(ArrayLiteral* lit);
621 
622   // Rewrite expressions that are not used as patterns
623   V8_INLINE void RewriteNonPattern(bool* ok);
624 
625   V8_INLINE void QueueDestructuringAssignmentForRewriting(
626       Expression* assignment);
627   V8_INLINE void QueueNonPatternForRewriting(Expression* expr, bool* ok);
628 
629   friend class InitializerRewriter;
630   void RewriteParameterInitializer(Expression* expr, Scope* scope);
631 
632   Expression* BuildInitialYield(int pos, FunctionKind kind);
633   Expression* BuildCreateJSGeneratorObject(int pos, FunctionKind kind);
634   Expression* BuildResolvePromise(Expression* value, int pos);
635   Expression* BuildRejectPromise(Expression* value, int pos);
636   Variable* PromiseVariable();
637 
638   // Generic AST generator for throwing errors from compiled code.
639   Expression* NewThrowError(Runtime::FunctionId function_id,
640                             MessageTemplate::Template message,
641                             const AstRawString* arg, int pos);
642 
643   void FinalizeIteratorUse(Scope* use_scope, Variable* completion,
644                            Expression* condition, Variable* iter,
645                            Block* iterator_use, Block* result);
646 
647   Statement* FinalizeForOfStatement(ForOfStatement* loop, Variable* completion,
648                                     int pos);
649   void BuildIteratorClose(ZoneList<Statement*>* statements, Variable* iterator,
650                           Variable* input, Variable* output);
651   void BuildIteratorCloseForCompletion(Scope* scope,
652                                        ZoneList<Statement*>* statements,
653                                        Variable* iterator,
654                                        Expression* completion);
655   Statement* CheckCallable(Variable* var, Expression* error, int pos);
656 
657   V8_INLINE Expression* RewriteAwaitExpression(Expression* value, int pos);
658   V8_INLINE void PrepareAsyncFunctionBody(ZoneList<Statement*>* body,
659                                           FunctionKind kind, int pos);
660   V8_INLINE void RewriteAsyncFunctionBody(ZoneList<Statement*>* body,
661                                           Block* block,
662                                           Expression* return_value, bool* ok);
663 
664   Expression* RewriteYieldStar(Expression* generator, Expression* expression,
665                                int pos);
666 
667   void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters,
668                                         Expression* params, int end_pos,
669                                         bool* ok);
670   void SetFunctionName(Expression* value, const AstRawString* name);
671 
672   // Helper functions for recursive descent.
673   V8_INLINE bool IsEval(const AstRawString* identifier) const {
674     return identifier == ast_value_factory()->eval_string();
675   }
676 
677   V8_INLINE bool IsArguments(const AstRawString* identifier) const {
678     return identifier == ast_value_factory()->arguments_string();
679   }
680 
681   V8_INLINE bool IsEvalOrArguments(const AstRawString* identifier) const {
682     return IsEval(identifier) || IsArguments(identifier);
683   }
684 
685   V8_INLINE bool IsUndefined(const AstRawString* identifier) const {
686     return identifier == ast_value_factory()->undefined_string();
687   }
688 
689   V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const {
690     return scanner()->IdentifierIsFutureStrictReserved(identifier);
691   }
692 
693   // Returns true if the expression is of type "this.foo".
694   V8_INLINE static bool IsThisProperty(Expression* expression) {
695     DCHECK(expression != NULL);
696     Property* property = expression->AsProperty();
697     return property != NULL && property->obj()->IsVariableProxy() &&
698            property->obj()->AsVariableProxy()->is_this();
699   }
700 
701   // This returns true if the expression is an indentifier (wrapped
702   // inside a variable proxy).  We exclude the case of 'this', which
703   // has been converted to a variable proxy.
704   V8_INLINE static bool IsIdentifier(Expression* expression) {
705     DCHECK_NOT_NULL(expression);
706     VariableProxy* operand = expression->AsVariableProxy();
707     return operand != nullptr && !operand->is_this();
708   }
709 
710   V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) {
711     DCHECK(IsIdentifier(expression));
712     return expression->AsVariableProxy()->raw_name();
713   }
714 
715   V8_INLINE VariableProxy* AsIdentifierExpression(Expression* expression) {
716     return expression->AsVariableProxy();
717   }
718 
719   V8_INLINE bool IsPrototype(const AstRawString* identifier) const {
720     return identifier == ast_value_factory()->prototype_string();
721   }
722 
723   V8_INLINE bool IsConstructor(const AstRawString* identifier) const {
724     return identifier == ast_value_factory()->constructor_string();
725   }
726 
727   V8_INLINE bool IsDirectEvalCall(Expression* expression) const {
728     if (!expression->IsCall()) return false;
729     expression = expression->AsCall()->expression();
730     return IsIdentifier(expression) && IsEval(AsIdentifier(expression));
731   }
732 
733   V8_INLINE static bool IsBoilerplateProperty(
734       ObjectLiteral::Property* property) {
735     return ObjectLiteral::IsBoilerplateProperty(property);
736   }
737 
738   V8_INLINE bool IsNative(Expression* expr) const {
739     DCHECK_NOT_NULL(expr);
740     return expr->IsVariableProxy() &&
741            expr->AsVariableProxy()->raw_name() ==
742                ast_value_factory()->native_string();
743   }
744 
745   V8_INLINE static bool IsArrayIndex(const AstRawString* string,
746                                      uint32_t* index) {
747     return string->AsArrayIndex(index);
748   }
749 
750   V8_INLINE bool IsUseStrictDirective(Statement* statement) const {
751     return IsStringLiteral(statement, ast_value_factory()->use_strict_string());
752   }
753 
754   V8_INLINE bool IsUseAsmDirective(Statement* statement) const {
755     return IsStringLiteral(statement, ast_value_factory()->use_asm_string());
756   }
757 
758   // Returns true if the statement is an expression statement containing
759   // a single string literal.  If a second argument is given, the literal
760   // is also compared with it and the result is true only if they are equal.
761   V8_INLINE bool IsStringLiteral(Statement* statement,
762                                  const AstRawString* arg = nullptr) const {
763     ExpressionStatement* e_stat = statement->AsExpressionStatement();
764     if (e_stat == nullptr) return false;
765     Literal* literal = e_stat->expression()->AsLiteral();
766     if (literal == nullptr || !literal->raw_value()->IsString()) return false;
767     return arg == nullptr || literal->raw_value()->AsString() == arg;
768   }
769 
770   V8_INLINE static Expression* GetPropertyValue(LiteralProperty* property) {
771     return property->value();
772   }
773 
774   V8_INLINE void GetDefaultStrings(
775       const AstRawString** default_string,
776       const AstRawString** star_default_star_string) {
777     *default_string = ast_value_factory()->default_string();
778     *star_default_star_string = ast_value_factory()->star_default_star_string();
779   }
780 
781   // Functions for encapsulating the differences between parsing and preparsing;
782   // operations interleaved with the recursive descent.
783   V8_INLINE void PushLiteralName(const AstRawString* id) {
784     DCHECK_NOT_NULL(fni_);
785     fni_->PushLiteralName(id);
786   }
787 
788   V8_INLINE void PushVariableName(const AstRawString* id) {
789     DCHECK_NOT_NULL(fni_);
790     fni_->PushVariableName(id);
791   }
792 
793   V8_INLINE void PushPropertyName(Expression* expression) {
794     DCHECK_NOT_NULL(fni_);
795     if (expression->IsPropertyName()) {
796       fni_->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
797     } else {
798       fni_->PushLiteralName(ast_value_factory()->anonymous_function_string());
799     }
800   }
801 
802   V8_INLINE void PushEnclosingName(const AstRawString* name) {
803     DCHECK_NOT_NULL(fni_);
804     fni_->PushEnclosingName(name);
805   }
806 
807   V8_INLINE void AddFunctionForNameInference(FunctionLiteral* func_to_infer) {
808     DCHECK_NOT_NULL(fni_);
809     fni_->AddFunction(func_to_infer);
810   }
811 
812   V8_INLINE void InferFunctionName() {
813     DCHECK_NOT_NULL(fni_);
814     fni_->Infer();
815   }
816 
817   // If we assign a function literal to a property we pretenure the
818   // literal so it can be added as a constant function property.
819   V8_INLINE static void CheckAssigningFunctionLiteralToProperty(
820       Expression* left, Expression* right) {
821     DCHECK(left != NULL);
822     if (left->IsProperty() && right->IsFunctionLiteral()) {
823       right->AsFunctionLiteral()->set_pretenure();
824     }
825   }
826 
827   // Determine if the expression is a variable proxy and mark it as being used
828   // in an assignment or with a increment/decrement operator.
829   V8_INLINE static Expression* MarkExpressionAsAssigned(
830       Expression* expression) {
831     VariableProxy* proxy =
832         expression != NULL ? expression->AsVariableProxy() : NULL;
833     if (proxy != NULL) proxy->set_is_assigned();
834     return expression;
835   }
836 
837   // Returns true if we have a binary expression between two numeric
838   // literals. In that case, *x will be changed to an expression which is the
839   // computed value.
840   bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
841                                               Token::Value op, int pos);
842 
843   // Rewrites the following types of unary expressions:
844   // not <literal> -> true / false
845   // + <numeric literal> -> <numeric literal>
846   // - <numeric literal> -> <numeric literal with value negated>
847   // ! <literal> -> true / false
848   // The following rewriting rules enable the collection of type feedback
849   // without any special stub and the multiplication is removed later in
850   // Crankshaft's canonicalization pass.
851   // + foo -> foo * 1
852   // - foo -> foo * (-1)
853   // ~ foo -> foo ^(~0)
854   Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
855                                    int pos);
856 
857   Expression* BuildIteratorResult(Expression* value, bool done);
858 
859   // Generate AST node that throws a ReferenceError with the given type.
860   V8_INLINE Expression* NewThrowReferenceError(
861       MessageTemplate::Template message, int pos) {
862     return NewThrowError(Runtime::kNewReferenceError, message,
863                          ast_value_factory()->empty_string(), pos);
864   }
865 
866   // Generate AST node that throws a SyntaxError with the given
867   // type. The first argument may be null (in the handle sense) in
868   // which case no arguments are passed to the constructor.
869   V8_INLINE Expression* NewThrowSyntaxError(MessageTemplate::Template message,
870                                             const AstRawString* arg, int pos) {
871     return NewThrowError(Runtime::kNewSyntaxError, message, arg, pos);
872   }
873 
874   // Generate AST node that throws a TypeError with the given
875   // type. Both arguments must be non-null (in the handle sense).
876   V8_INLINE Expression* NewThrowTypeError(MessageTemplate::Template message,
877                                           const AstRawString* arg, int pos) {
878     return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
879   }
880 
881   // Reporting errors.
882   V8_INLINE void ReportMessageAt(Scanner::Location source_location,
883                                  MessageTemplate::Template message,
884                                  const char* arg = NULL,
885                                  ParseErrorType error_type = kSyntaxError) {
886     if (stack_overflow()) {
887       // Suppress the error message (syntax error or such) in the presence of a
888       // stack overflow. The isolate allows only one pending exception at at
889       // time
890       // and we want to report the stack overflow later.
891       return;
892     }
893     pending_error_handler_.ReportMessageAt(source_location.beg_pos,
894                                            source_location.end_pos, message,
895                                            arg, error_type);
896   }
897 
898   V8_INLINE void ReportMessageAt(Scanner::Location source_location,
899                                  MessageTemplate::Template message,
900                                  const AstRawString* arg,
901                                  ParseErrorType error_type = kSyntaxError) {
902     if (stack_overflow()) {
903       // Suppress the error message (syntax error or such) in the presence of a
904       // stack overflow. The isolate allows only one pending exception at at
905       // time
906       // and we want to report the stack overflow later.
907       return;
908     }
909     pending_error_handler_.ReportMessageAt(source_location.beg_pos,
910                                            source_location.end_pos, message,
911                                            arg, error_type);
912   }
913 
914   // "null" return type creators.
915   V8_INLINE static const AstRawString* EmptyIdentifier() { return nullptr; }
916   V8_INLINE static bool IsEmptyIdentifier(const AstRawString* name) {
917     return name == nullptr;
918   }
919   V8_INLINE static Expression* EmptyExpression() { return nullptr; }
920   V8_INLINE static Literal* EmptyLiteral() { return nullptr; }
921   V8_INLINE static ObjectLiteralProperty* EmptyObjectLiteralProperty() {
922     return nullptr;
923   }
924   V8_INLINE static ClassLiteralProperty* EmptyClassLiteralProperty() {
925     return nullptr;
926   }
927   V8_INLINE static FunctionLiteral* EmptyFunctionLiteral() { return nullptr; }
928   V8_INLINE static Block* NullBlock() { return nullptr; }
929 
930   V8_INLINE static bool IsEmptyExpression(Expression* expr) {
931     return expr == nullptr;
932   }
933 
934   // Used in error return values.
935   V8_INLINE static ZoneList<Expression*>* NullExpressionList() {
936     return nullptr;
937   }
938   V8_INLINE static bool IsNullExpressionList(ZoneList<Expression*>* exprs) {
939     return exprs == nullptr;
940   }
941   V8_INLINE static ZoneList<Statement*>* NullStatementList() { return nullptr; }
942   V8_INLINE static bool IsNullStatementList(ZoneList<Statement*>* stmts) {
943     return stmts == nullptr;
944   }
945   V8_INLINE static Statement* NullStatement() { return nullptr; }
946   V8_INLINE bool IsNullStatement(Statement* stmt) { return stmt == nullptr; }
947   V8_INLINE bool IsEmptyStatement(Statement* stmt) {
948     DCHECK_NOT_NULL(stmt);
949     return stmt->IsEmpty();
950   }
951 
952   // Non-NULL empty string.
953   V8_INLINE const AstRawString* EmptyIdentifierString() const {
954     return ast_value_factory()->empty_string();
955   }
956 
957   // Odd-ball literal creators.
958   V8_INLINE Literal* GetLiteralTheHole(int position) {
959     return factory()->NewTheHoleLiteral(kNoSourcePosition);
960   }
961 
962   // Producing data during the recursive descent.
963   V8_INLINE const AstRawString* GetSymbol() const {
964     const AstRawString* result = scanner()->CurrentSymbol(ast_value_factory());
965     DCHECK(result != NULL);
966     return result;
967   }
968 
969   V8_INLINE const AstRawString* GetNextSymbol() const {
970     return scanner()->NextSymbol(ast_value_factory());
971   }
972 
973   V8_INLINE const AstRawString* GetNumberAsSymbol() const {
974     double double_value = scanner()->DoubleValue();
975     char array[100];
976     const char* string = DoubleToCString(double_value, ArrayVector(array));
977     return ast_value_factory()->GetOneByteString(string);
978   }
979 
980   V8_INLINE Expression* ThisExpression(int pos = kNoSourcePosition) {
981     return NewUnresolved(ast_value_factory()->this_string(), pos,
982                          THIS_VARIABLE);
983   }
984 
985   Expression* NewSuperPropertyReference(int pos);
986   Expression* NewSuperCallReference(int pos);
987   Expression* NewTargetExpression(int pos);
988   Expression* FunctionSentExpression(int pos);
989 
990   Literal* ExpressionFromLiteral(Token::Value token, int pos);
991 
992   V8_INLINE Expression* ExpressionFromIdentifier(
993       const AstRawString* name, int start_position,
994       InferName infer = InferName::kYes) {
995     if (infer == InferName::kYes) {
996       fni_->PushVariableName(name);
997     }
998     return NewUnresolved(name, start_position);
999   }
1000 
1001   V8_INLINE Expression* ExpressionFromString(int pos) {
1002     const AstRawString* symbol = GetSymbol();
1003     fni_->PushLiteralName(symbol);
1004     return factory()->NewStringLiteral(symbol, pos);
1005   }
1006 
1007   V8_INLINE ZoneList<Expression*>* NewExpressionList(int size) const {
1008     return new (zone()) ZoneList<Expression*>(size, zone());
1009   }
1010   V8_INLINE ZoneList<ObjectLiteral::Property*>* NewObjectPropertyList(
1011       int size) const {
1012     return new (zone()) ZoneList<ObjectLiteral::Property*>(size, zone());
1013   }
1014   V8_INLINE ZoneList<ClassLiteral::Property*>* NewClassPropertyList(
1015       int size) const {
1016     return new (zone()) ZoneList<ClassLiteral::Property*>(size, zone());
1017   }
1018   V8_INLINE ZoneList<Statement*>* NewStatementList(int size) const {
1019     return new (zone()) ZoneList<Statement*>(size, zone());
1020   }
1021   V8_INLINE ZoneList<CaseClause*>* NewCaseClauseList(int size) const {
1022     return new (zone()) ZoneList<CaseClause*>(size, zone());
1023   }
1024 
1025   V8_INLINE Expression* NewV8Intrinsic(const AstRawString* name,
1026                                        ZoneList<Expression*>* args, int pos,
1027                                        bool* ok);
1028 
1029   V8_INLINE Statement* NewThrowStatement(Expression* exception, int pos) {
1030     return factory()->NewExpressionStatement(
1031         factory()->NewThrow(exception, pos), pos);
1032   }
1033 
1034   V8_INLINE void AddParameterInitializationBlock(
1035       const ParserFormalParameters& parameters, ZoneList<Statement*>* body,
1036       bool is_async, bool* ok) {
1037     if (parameters.is_simple) return;
1038     auto* init_block = BuildParameterInitializationBlock(parameters, ok);
1039     if (!*ok) return;
1040     if (is_async) {
1041       init_block = BuildRejectPromiseOnException(init_block, ok);
1042       if (!*ok) return;
1043     }
1044     if (init_block != nullptr) body->Add(init_block, zone());
1045   }
1046 
1047   V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters,
1048                                     Expression* pattern,
1049                                     Expression* initializer,
1050                                     int initializer_end_position,
1051                                     bool is_rest) {
1052     parameters->UpdateArityAndFunctionLength(initializer != nullptr, is_rest);
1053     bool is_simple = pattern->IsVariableProxy() && initializer == nullptr;
1054     const AstRawString* name = is_simple
1055                                    ? pattern->AsVariableProxy()->raw_name()
1056                                    : ast_value_factory()->empty_string();
1057     parameters->params.Add(
1058         ParserFormalParameters::Parameter(name, pattern, initializer,
1059                                           initializer_end_position, is_rest),
1060         parameters->scope->zone());
1061   }
1062 
1063   V8_INLINE void DeclareFormalParameter(
1064       DeclarationScope* scope,
1065       const ParserFormalParameters::Parameter& parameter) {
1066     bool is_duplicate = false;
1067     bool is_simple = classifier()->is_simple_parameter_list();
1068     auto name = is_simple || parameter.is_rest
1069                     ? parameter.name
1070                     : ast_value_factory()->empty_string();
1071     auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY;
1072     if (!is_simple) scope->SetHasNonSimpleParameters();
1073     bool is_optional = parameter.initializer != nullptr;
1074     Variable* var =
1075         scope->DeclareParameter(name, mode, is_optional, parameter.is_rest,
1076                                 &is_duplicate, ast_value_factory());
1077     if (is_duplicate) {
1078       classifier()->RecordDuplicateFormalParameterError(scanner()->location());
1079     }
1080     if (is_sloppy(scope->language_mode())) {
1081       // TODO(sigurds) Mark every parameter as maybe assigned. This is a
1082       // conservative approximation necessary to account for parameters
1083       // that are assigned via the arguments array.
1084       var->set_maybe_assigned();
1085     }
1086   }
1087 
1088   void DeclareArrowFunctionFormalParameters(ParserFormalParameters* parameters,
1089                                             Expression* params,
1090                                             const Scanner::Location& params_loc,
1091                                             Scanner::Location* duplicate_loc,
1092                                             bool* ok);
1093 
1094   void ReindexLiterals(const ParserFormalParameters& parameters);
1095 
1096   V8_INLINE Expression* NoTemplateTag() { return NULL; }
1097   V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
1098     return tag != NULL;
1099   }
1100 
1101   V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {}
1102 
1103   Expression* ExpressionListToExpression(ZoneList<Expression*>* args);
1104 
1105   void AddAccessorPrefixToFunctionName(bool is_get, FunctionLiteral* function,
1106                                        const AstRawString* name);
1107 
1108   void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property,
1109                                        const AstRawString* name);
1110 
1111   void SetFunctionNameFromIdentifierRef(Expression* value,
1112                                         Expression* identifier);
1113 
1114   V8_INLINE ZoneList<typename ExpressionClassifier::Error>*
1115   GetReportedErrorList() const {
1116     return function_state_->GetReportedErrorList();
1117   }
1118 
1119   V8_INLINE ZoneList<Expression*>* GetNonPatternList() const {
1120     return function_state_->non_patterns_to_rewrite();
1121   }
1122 
1123   V8_INLINE void CountUsage(v8::Isolate::UseCounterFeature feature) {
1124     ++use_counts_[feature];
1125   }
1126 
1127   // Parser's private field members.
1128   friend class DiscardableZoneScope;  // Uses reusable_preparser_.
1129   // FIXME(marja): Make reusable_preparser_ always use its own temp Zone (call
1130   // DeleteAll after each function), so this won't be needed.
1131 
1132   Scanner scanner_;
1133   PreParser* reusable_preparser_;
1134   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
1135   Mode mode_;
1136 
1137   friend class ParserTarget;
1138   friend class ParserTargetScope;
1139   ParserTarget* target_stack_;  // for break, continue statements
1140 
1141   ScriptCompiler::CompileOptions compile_options_;
1142   ParseData* cached_parse_data_;
1143 
1144   PendingCompilationErrorHandler pending_error_handler_;
1145 
1146   // Other information which will be stored in Parser and moved to Isolate after
1147   // parsing.
1148   int use_counts_[v8::Isolate::kUseCounterFeatureCount];
1149   int total_preparse_skipped_;
1150   bool parsing_on_main_thread_;
1151   ParserLogger* log_;
1152 };
1153 
1154 // ----------------------------------------------------------------------------
1155 // Target is a support class to facilitate manipulation of the
1156 // Parser's target_stack_ (the stack of potential 'break' and
1157 // 'continue' statement targets). Upon construction, a new target is
1158 // added; it is removed upon destruction.
1159 
1160 class ParserTarget BASE_EMBEDDED {
1161  public:
1162   ParserTarget(ParserBase<Parser>* parser, BreakableStatement* statement)
1163       : variable_(&parser->impl()->target_stack_),
1164         statement_(statement),
1165         previous_(parser->impl()->target_stack_) {
1166     parser->impl()->target_stack_ = this;
1167   }
1168 
1169   ~ParserTarget() { *variable_ = previous_; }
1170 
1171   ParserTarget* previous() { return previous_; }
1172   BreakableStatement* statement() { return statement_; }
1173 
1174  private:
1175   ParserTarget** variable_;
1176   BreakableStatement* statement_;
1177   ParserTarget* previous_;
1178 };
1179 
1180 class ParserTargetScope BASE_EMBEDDED {
1181  public:
1182   explicit ParserTargetScope(ParserBase<Parser>* parser)
1183       : variable_(&parser->impl()->target_stack_),
1184         previous_(parser->impl()->target_stack_) {
1185     parser->impl()->target_stack_ = nullptr;
1186   }
1187 
1188   ~ParserTargetScope() { *variable_ = previous_; }
1189 
1190  private:
1191   ParserTarget** variable_;
1192   ParserTarget* previous_;
1193 };
1194 
1195 }  // namespace internal
1196 }  // namespace v8
1197 
1198 #endif  // V8_PARSING_PARSER_H_
1199