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