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