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