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