1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_PARSING_PARSER_H_ 6 #define V8_PARSING_PARSER_H_ 7 8 #include "src/allocation.h" 9 #include "src/ast/ast.h" 10 #include "src/ast/scopes.h" 11 #include "src/compiler.h" // TODO(titzer): remove this include dependency 12 #include "src/parsing/parser-base.h" 13 #include "src/parsing/preparse-data.h" 14 #include "src/parsing/preparse-data-format.h" 15 #include "src/parsing/preparser.h" 16 #include "src/pending-compilation-error-handler.h" 17 18 namespace v8 { 19 20 class ScriptCompiler; 21 22 namespace internal { 23 24 class Target; 25 26 // A container for the inputs, configuration options, and outputs of parsing. 27 class ParseInfo { 28 public: 29 explicit ParseInfo(Zone* zone); 30 ParseInfo(Zone* zone, Handle<JSFunction> function); 31 ParseInfo(Zone* zone, Handle<Script> script); 32 // TODO(all) Only used via Debug::FindSharedFunctionInfoInScript, remove? 33 ParseInfo(Zone* zone, Handle<SharedFunctionInfo> shared); 34 35 ~ParseInfo() { 36 if (ast_value_factory_owned()) { 37 delete ast_value_factory_; 38 set_ast_value_factory_owned(false); 39 } 40 ast_value_factory_ = nullptr; 41 } 42 43 Zone* zone() { return zone_; } 44 45 // Convenience accessor methods for flags. 46 #define FLAG_ACCESSOR(flag, getter, setter) \ 47 bool getter() const { return GetFlag(flag); } \ 48 void setter() { SetFlag(flag); } \ 49 void setter(bool val) { SetFlag(flag, val); } 50 51 FLAG_ACCESSOR(kToplevel, is_toplevel, set_toplevel) 52 FLAG_ACCESSOR(kLazy, is_lazy, set_lazy) 53 FLAG_ACCESSOR(kEval, is_eval, set_eval) 54 FLAG_ACCESSOR(kGlobal, is_global, set_global) 55 FLAG_ACCESSOR(kStrictMode, is_strict_mode, set_strict_mode) 56 FLAG_ACCESSOR(kStrongMode, is_strong_mode, set_strong_mode) 57 FLAG_ACCESSOR(kNative, is_native, set_native) 58 FLAG_ACCESSOR(kModule, is_module, set_module) 59 FLAG_ACCESSOR(kAllowLazyParsing, allow_lazy_parsing, set_allow_lazy_parsing) 60 FLAG_ACCESSOR(kAstValueFactoryOwned, ast_value_factory_owned, 61 set_ast_value_factory_owned) 62 63 #undef FLAG_ACCESSOR 64 65 void set_parse_restriction(ParseRestriction restriction) { 66 SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION); 67 } 68 69 ParseRestriction parse_restriction() const { 70 return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL 71 : NO_PARSE_RESTRICTION; 72 } 73 74 ScriptCompiler::ExternalSourceStream* source_stream() { 75 return source_stream_; 76 } 77 void set_source_stream(ScriptCompiler::ExternalSourceStream* source_stream) { 78 source_stream_ = source_stream; 79 } 80 81 ScriptCompiler::StreamedSource::Encoding source_stream_encoding() { 82 return source_stream_encoding_; 83 } 84 void set_source_stream_encoding( 85 ScriptCompiler::StreamedSource::Encoding source_stream_encoding) { 86 source_stream_encoding_ = source_stream_encoding; 87 } 88 89 v8::Extension* extension() { return extension_; } 90 void set_extension(v8::Extension* extension) { extension_ = extension; } 91 92 ScriptData** cached_data() { return cached_data_; } 93 void set_cached_data(ScriptData** cached_data) { cached_data_ = cached_data; } 94 95 ScriptCompiler::CompileOptions compile_options() { return compile_options_; } 96 void set_compile_options(ScriptCompiler::CompileOptions compile_options) { 97 compile_options_ = compile_options; 98 } 99 100 Scope* script_scope() { return script_scope_; } 101 void set_script_scope(Scope* script_scope) { script_scope_ = script_scope; } 102 103 AstValueFactory* ast_value_factory() { return ast_value_factory_; } 104 void set_ast_value_factory(AstValueFactory* ast_value_factory) { 105 ast_value_factory_ = ast_value_factory; 106 } 107 108 FunctionLiteral* literal() { return literal_; } 109 void set_literal(FunctionLiteral* literal) { literal_ = literal; } 110 111 Scope* scope() { return scope_; } 112 void set_scope(Scope* scope) { scope_ = scope; } 113 114 UnicodeCache* unicode_cache() { return unicode_cache_; } 115 void set_unicode_cache(UnicodeCache* unicode_cache) { 116 unicode_cache_ = unicode_cache; 117 } 118 119 uintptr_t stack_limit() { return stack_limit_; } 120 void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; } 121 122 uint32_t hash_seed() { return hash_seed_; } 123 void set_hash_seed(uint32_t hash_seed) { hash_seed_ = hash_seed; } 124 125 //-------------------------------------------------------------------------- 126 // TODO(titzer): these should not be part of ParseInfo. 127 //-------------------------------------------------------------------------- 128 Isolate* isolate() { return isolate_; } 129 Handle<JSFunction> closure() { return closure_; } 130 Handle<SharedFunctionInfo> shared_info() { return shared_; } 131 Handle<Script> script() { return script_; } 132 Handle<Context> context() { return context_; } 133 void clear_script() { script_ = Handle<Script>::null(); } 134 void set_isolate(Isolate* isolate) { isolate_ = isolate; } 135 void set_context(Handle<Context> context) { context_ = context; } 136 void set_script(Handle<Script> script) { script_ = script; } 137 //-------------------------------------------------------------------------- 138 139 LanguageMode language_mode() { 140 return construct_language_mode(is_strict_mode(), is_strong_mode()); 141 } 142 void set_language_mode(LanguageMode language_mode) { 143 STATIC_ASSERT(LANGUAGE_END == 3); 144 set_strict_mode(language_mode & STRICT_BIT); 145 set_strong_mode(language_mode & STRONG_BIT); 146 } 147 148 void ReopenHandlesInNewHandleScope() { 149 closure_ = Handle<JSFunction>(*closure_); 150 shared_ = Handle<SharedFunctionInfo>(*shared_); 151 script_ = Handle<Script>(*script_); 152 context_ = Handle<Context>(*context_); 153 } 154 155 #ifdef DEBUG 156 bool script_is_native() { return script_->type() == Script::TYPE_NATIVE; } 157 #endif // DEBUG 158 159 private: 160 // Various configuration flags for parsing. 161 enum Flag { 162 // ---------- Input flags --------------------------- 163 kToplevel = 1 << 0, 164 kLazy = 1 << 1, 165 kEval = 1 << 2, 166 kGlobal = 1 << 3, 167 kStrictMode = 1 << 4, 168 kStrongMode = 1 << 5, 169 kNative = 1 << 6, 170 kParseRestriction = 1 << 7, 171 kModule = 1 << 8, 172 kAllowLazyParsing = 1 << 9, 173 // ---------- Output flags -------------------------- 174 kAstValueFactoryOwned = 1 << 10 175 }; 176 177 //------------- Inputs to parsing and scope analysis ----------------------- 178 Zone* zone_; 179 unsigned flags_; 180 ScriptCompiler::ExternalSourceStream* source_stream_; 181 ScriptCompiler::StreamedSource::Encoding source_stream_encoding_; 182 v8::Extension* extension_; 183 ScriptCompiler::CompileOptions compile_options_; 184 Scope* script_scope_; 185 UnicodeCache* unicode_cache_; 186 uintptr_t stack_limit_; 187 uint32_t hash_seed_; 188 189 // TODO(titzer): Move handles and isolate out of ParseInfo. 190 Isolate* isolate_; 191 Handle<JSFunction> closure_; 192 Handle<SharedFunctionInfo> shared_; 193 Handle<Script> script_; 194 Handle<Context> context_; 195 196 //----------- Inputs+Outputs of parsing and scope analysis ----------------- 197 ScriptData** cached_data_; // used if available, populated if requested. 198 AstValueFactory* ast_value_factory_; // used if available, otherwise new. 199 200 //----------- Outputs of parsing and scope analysis ------------------------ 201 FunctionLiteral* literal_; // produced by full parser. 202 Scope* scope_; // produced by scope analysis. 203 204 void SetFlag(Flag f) { flags_ |= f; } 205 void SetFlag(Flag f, bool v) { flags_ = v ? flags_ | f : flags_ & ~f; } 206 bool GetFlag(Flag f) const { return (flags_ & f) != 0; } 207 208 void set_shared_info(Handle<SharedFunctionInfo> shared) { shared_ = shared; } 209 void set_closure(Handle<JSFunction> closure) { closure_ = closure; } 210 }; 211 212 class FunctionEntry BASE_EMBEDDED { 213 public: 214 enum { 215 kStartPositionIndex, 216 kEndPositionIndex, 217 kLiteralCountIndex, 218 kPropertyCountIndex, 219 kLanguageModeIndex, 220 kUsesSuperPropertyIndex, 221 kCallsEvalIndex, 222 kSize 223 }; 224 225 explicit FunctionEntry(Vector<unsigned> backing) 226 : backing_(backing) { } 227 228 FunctionEntry() : backing_() { } 229 230 int start_pos() { return backing_[kStartPositionIndex]; } 231 int end_pos() { return backing_[kEndPositionIndex]; } 232 int literal_count() { return backing_[kLiteralCountIndex]; } 233 int property_count() { return backing_[kPropertyCountIndex]; } 234 LanguageMode language_mode() { 235 DCHECK(is_valid_language_mode(backing_[kLanguageModeIndex])); 236 return static_cast<LanguageMode>(backing_[kLanguageModeIndex]); 237 } 238 bool uses_super_property() { return backing_[kUsesSuperPropertyIndex]; } 239 bool calls_eval() { return backing_[kCallsEvalIndex]; } 240 241 bool is_valid() { return !backing_.is_empty(); } 242 243 private: 244 Vector<unsigned> backing_; 245 }; 246 247 248 // Wrapper around ScriptData to provide parser-specific functionality. 249 class ParseData { 250 public: 251 static ParseData* FromCachedData(ScriptData* cached_data) { 252 ParseData* pd = new ParseData(cached_data); 253 if (pd->IsSane()) return pd; 254 cached_data->Reject(); 255 delete pd; 256 return NULL; 257 } 258 259 void Initialize(); 260 FunctionEntry GetFunctionEntry(int start); 261 int FunctionCount(); 262 263 bool HasError(); 264 265 unsigned* Data() { // Writable data as unsigned int array. 266 return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data())); 267 } 268 269 void Reject() { script_data_->Reject(); } 270 271 bool rejected() const { return script_data_->rejected(); } 272 273 private: 274 explicit ParseData(ScriptData* script_data) : script_data_(script_data) {} 275 276 bool IsSane(); 277 unsigned Magic(); 278 unsigned Version(); 279 int FunctionsSize(); 280 int Length() const { 281 // Script data length is already checked to be a multiple of unsigned size. 282 return script_data_->length() / sizeof(unsigned); 283 } 284 285 ScriptData* script_data_; 286 int function_index_; 287 288 DISALLOW_COPY_AND_ASSIGN(ParseData); 289 }; 290 291 // ---------------------------------------------------------------------------- 292 // JAVASCRIPT PARSING 293 294 class Parser; 295 class SingletonLogger; 296 297 298 struct ParserFormalParameters : FormalParametersBase { 299 struct Parameter { 300 Parameter(const AstRawString* name, Expression* pattern, 301 Expression* initializer, int initializer_end_position, 302 bool is_rest) 303 : name(name), 304 pattern(pattern), 305 initializer(initializer), 306 initializer_end_position(initializer_end_position), 307 is_rest(is_rest) {} 308 const AstRawString* name; 309 Expression* pattern; 310 Expression* initializer; 311 int initializer_end_position; 312 bool is_rest; 313 bool is_simple() const { 314 return pattern->IsVariableProxy() && initializer == nullptr && !is_rest; 315 } 316 }; 317 318 explicit ParserFormalParameters(Scope* scope) 319 : FormalParametersBase(scope), params(4, scope->zone()) {} 320 ZoneList<Parameter> params; 321 322 int Arity() const { return params.length(); } 323 const Parameter& at(int i) const { return params[i]; } 324 }; 325 326 327 class ParserTraits { 328 public: 329 struct Type { 330 // TODO(marja): To be removed. The Traits object should contain all the data 331 // it needs. 332 typedef v8::internal::Parser* Parser; 333 334 typedef Variable GeneratorVariable; 335 336 typedef v8::internal::AstProperties AstProperties; 337 338 // Return types for traversing functions. 339 typedef const AstRawString* Identifier; 340 typedef v8::internal::Expression* Expression; 341 typedef Yield* YieldExpression; 342 typedef v8::internal::FunctionLiteral* FunctionLiteral; 343 typedef v8::internal::ClassLiteral* ClassLiteral; 344 typedef v8::internal::Literal* Literal; 345 typedef ObjectLiteral::Property* ObjectLiteralProperty; 346 typedef ZoneList<v8::internal::Expression*>* ExpressionList; 347 typedef ZoneList<ObjectLiteral::Property*>* PropertyList; 348 typedef ParserFormalParameters::Parameter FormalParameter; 349 typedef ParserFormalParameters FormalParameters; 350 typedef ZoneList<v8::internal::Statement*>* StatementList; 351 352 // For constructing objects returned by the traversing functions. 353 typedef AstNodeFactory Factory; 354 }; 355 356 explicit ParserTraits(Parser* parser) : parser_(parser) {} 357 358 // Helper functions for recursive descent. 359 bool IsEval(const AstRawString* identifier) const; 360 bool IsArguments(const AstRawString* identifier) const; 361 bool IsEvalOrArguments(const AstRawString* identifier) const; 362 bool IsUndefined(const AstRawString* identifier) const; 363 V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const; 364 365 // Returns true if the expression is of type "this.foo". 366 static bool IsThisProperty(Expression* expression); 367 368 static bool IsIdentifier(Expression* expression); 369 370 bool IsPrototype(const AstRawString* identifier) const; 371 372 bool IsConstructor(const AstRawString* identifier) const; 373 374 static const AstRawString* AsIdentifier(Expression* expression) { 375 DCHECK(IsIdentifier(expression)); 376 return expression->AsVariableProxy()->raw_name(); 377 } 378 379 static bool IsBoilerplateProperty(ObjectLiteral::Property* property) { 380 return ObjectLiteral::IsBoilerplateProperty(property); 381 } 382 383 static bool IsArrayIndex(const AstRawString* string, uint32_t* index) { 384 return string->AsArrayIndex(index); 385 } 386 387 static Expression* GetPropertyValue(ObjectLiteral::Property* property) { 388 return property->value(); 389 } 390 391 // Functions for encapsulating the differences between parsing and preparsing; 392 // operations interleaved with the recursive descent. 393 static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) { 394 fni->PushLiteralName(id); 395 } 396 397 void PushPropertyName(FuncNameInferrer* fni, Expression* expression); 398 399 static void InferFunctionName(FuncNameInferrer* fni, 400 FunctionLiteral* func_to_infer) { 401 fni->AddFunction(func_to_infer); 402 } 403 404 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 405 Scope* scope, ObjectLiteralProperty* property, bool* has_function) { 406 Expression* value = property->value(); 407 if (scope->DeclarationScope()->is_script_scope() && 408 value->AsFunctionLiteral() != NULL) { 409 *has_function = true; 410 value->AsFunctionLiteral()->set_pretenure(); 411 } 412 } 413 414 // If we assign a function literal to a property we pretenure the 415 // literal so it can be added as a constant function property. 416 static void CheckAssigningFunctionLiteralToProperty(Expression* left, 417 Expression* right); 418 419 // Determine if the expression is a variable proxy and mark it as being used 420 // in an assignment or with a increment/decrement operator. 421 static Expression* MarkExpressionAsAssigned(Expression* expression); 422 423 // Returns true if we have a binary expression between two numeric 424 // literals. In that case, *x will be changed to an expression which is the 425 // computed value. 426 bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y, 427 Token::Value op, int pos, 428 AstNodeFactory* factory); 429 430 // Rewrites the following types of unary expressions: 431 // not <literal> -> true / false 432 // + <numeric literal> -> <numeric literal> 433 // - <numeric literal> -> <numeric literal with value negated> 434 // ! <literal> -> true / false 435 // The following rewriting rules enable the collection of type feedback 436 // without any special stub and the multiplication is removed later in 437 // Crankshaft's canonicalization pass. 438 // + foo -> foo * 1 439 // - foo -> foo * (-1) 440 // ~ foo -> foo ^(~0) 441 Expression* BuildUnaryExpression(Expression* expression, Token::Value op, 442 int pos, AstNodeFactory* factory); 443 444 // Generate AST node that throws a ReferenceError with the given type. 445 Expression* NewThrowReferenceError(MessageTemplate::Template message, 446 int pos); 447 448 // Generate AST node that throws a SyntaxError with the given 449 // type. The first argument may be null (in the handle sense) in 450 // which case no arguments are passed to the constructor. 451 Expression* NewThrowSyntaxError(MessageTemplate::Template message, 452 const AstRawString* arg, int pos); 453 454 // Generate AST node that throws a TypeError with the given 455 // type. Both arguments must be non-null (in the handle sense). 456 Expression* NewThrowTypeError(MessageTemplate::Template message, 457 const AstRawString* arg, int pos); 458 459 // Generic AST generator for throwing errors from compiled code. 460 Expression* NewThrowError(Runtime::FunctionId function_id, 461 MessageTemplate::Template message, 462 const AstRawString* arg, int pos); 463 464 // Reporting errors. 465 void ReportMessageAt(Scanner::Location source_location, 466 MessageTemplate::Template message, 467 const char* arg = NULL, 468 ParseErrorType error_type = kSyntaxError); 469 void ReportMessage(MessageTemplate::Template message, const char* arg = NULL, 470 ParseErrorType error_type = kSyntaxError); 471 void ReportMessage(MessageTemplate::Template message, const AstRawString* arg, 472 ParseErrorType error_type = kSyntaxError); 473 void ReportMessageAt(Scanner::Location source_location, 474 MessageTemplate::Template message, 475 const AstRawString* arg, 476 ParseErrorType error_type = kSyntaxError); 477 478 // "null" return type creators. 479 static const AstRawString* EmptyIdentifier() { 480 return NULL; 481 } 482 static Expression* EmptyExpression() { 483 return NULL; 484 } 485 static Literal* EmptyLiteral() { 486 return NULL; 487 } 488 static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; } 489 static FunctionLiteral* EmptyFunctionLiteral() { return NULL; } 490 491 // Used in error return values. 492 static ZoneList<Expression*>* NullExpressionList() { 493 return NULL; 494 } 495 static const AstRawString* EmptyFormalParameter() { return NULL; } 496 497 // Non-NULL empty string. 498 V8_INLINE const AstRawString* EmptyIdentifierString(); 499 500 // Odd-ball literal creators. 501 Literal* GetLiteralTheHole(int position, AstNodeFactory* factory); 502 503 // Producing data during the recursive descent. 504 const AstRawString* GetSymbol(Scanner* scanner); 505 const AstRawString* GetNextSymbol(Scanner* scanner); 506 const AstRawString* GetNumberAsSymbol(Scanner* scanner); 507 508 Expression* ThisExpression(Scope* scope, AstNodeFactory* factory, 509 int pos = RelocInfo::kNoPosition); 510 Expression* SuperPropertyReference(Scope* scope, AstNodeFactory* factory, 511 int pos); 512 Expression* SuperCallReference(Scope* scope, AstNodeFactory* factory, 513 int pos); 514 Expression* NewTargetExpression(Scope* scope, AstNodeFactory* factory, 515 int pos); 516 Expression* DefaultConstructor(bool call_super, Scope* scope, int pos, 517 int end_pos, LanguageMode language_mode); 518 Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner, 519 AstNodeFactory* factory); 520 Expression* ExpressionFromIdentifier(const AstRawString* name, 521 int start_position, int end_position, 522 Scope* scope, AstNodeFactory* factory); 523 Expression* ExpressionFromString(int pos, Scanner* scanner, 524 AstNodeFactory* factory); 525 Expression* GetIterator(Expression* iterable, AstNodeFactory* factory, 526 int pos); 527 ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) { 528 return new(zone) ZoneList<v8::internal::Expression*>(size, zone); 529 } 530 ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) { 531 return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone); 532 } 533 ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) { 534 return new(zone) ZoneList<v8::internal::Statement*>(size, zone); 535 } 536 537 V8_INLINE void AddParameterInitializationBlock( 538 const ParserFormalParameters& parameters, 539 ZoneList<v8::internal::Statement*>* body, bool* ok); 540 541 V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type, 542 FunctionKind kind = kNormalFunction); 543 544 V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters, 545 Expression* pattern, 546 Expression* initializer, 547 int initializer_end_position, bool is_rest); 548 V8_INLINE void DeclareFormalParameter( 549 Scope* scope, const ParserFormalParameters::Parameter& parameter, 550 ExpressionClassifier* classifier); 551 void ParseArrowFunctionFormalParameters(ParserFormalParameters* parameters, 552 Expression* params, 553 const Scanner::Location& params_loc, 554 bool* ok); 555 void ParseArrowFunctionFormalParameterList( 556 ParserFormalParameters* parameters, Expression* params, 557 const Scanner::Location& params_loc, 558 Scanner::Location* duplicate_loc, bool* ok); 559 560 V8_INLINE DoExpression* ParseDoExpression(bool* ok); 561 562 void ReindexLiterals(const ParserFormalParameters& parameters); 563 564 // Temporary glue; these functions will move to ParserBase. 565 Expression* ParseV8Intrinsic(bool* ok); 566 FunctionLiteral* ParseFunctionLiteral( 567 const AstRawString* name, Scanner::Location function_name_location, 568 FunctionNameValidity function_name_validity, FunctionKind kind, 569 int function_token_position, FunctionLiteral::FunctionType type, 570 FunctionLiteral::ArityRestriction arity_restriction, 571 LanguageMode language_mode, bool* ok); 572 V8_INLINE void SkipLazyFunctionBody( 573 int* materialized_literal_count, int* expected_property_count, bool* ok, 574 Scanner::BookmarkScope* bookmark = nullptr); 575 V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody( 576 const AstRawString* name, int pos, 577 const ParserFormalParameters& parameters, FunctionKind kind, 578 FunctionLiteral::FunctionType function_type, bool* ok); 579 580 ClassLiteral* ParseClassLiteral(const AstRawString* name, 581 Scanner::Location class_name_location, 582 bool name_is_strict_reserved, int pos, 583 bool* ok); 584 585 V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope, 586 bool* ok); 587 588 class TemplateLiteral : public ZoneObject { 589 public: 590 TemplateLiteral(Zone* zone, int pos) 591 : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {} 592 593 const ZoneList<Expression*>* cooked() const { return &cooked_; } 594 const ZoneList<Expression*>* raw() const { return &raw_; } 595 const ZoneList<Expression*>* expressions() const { return &expressions_; } 596 int position() const { return pos_; } 597 598 void AddTemplateSpan(Literal* cooked, Literal* raw, int end, Zone* zone) { 599 DCHECK_NOT_NULL(cooked); 600 DCHECK_NOT_NULL(raw); 601 cooked_.Add(cooked, zone); 602 raw_.Add(raw, zone); 603 } 604 605 void AddExpression(Expression* expression, Zone* zone) { 606 DCHECK_NOT_NULL(expression); 607 expressions_.Add(expression, zone); 608 } 609 610 private: 611 ZoneList<Expression*> cooked_; 612 ZoneList<Expression*> raw_; 613 ZoneList<Expression*> expressions_; 614 int pos_; 615 }; 616 617 typedef TemplateLiteral* TemplateLiteralState; 618 619 V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos); 620 V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail); 621 V8_INLINE void AddTemplateExpression(TemplateLiteralState* state, 622 Expression* expression); 623 V8_INLINE Expression* CloseTemplateLiteral(TemplateLiteralState* state, 624 int start, Expression* tag); 625 V8_INLINE Expression* NoTemplateTag() { return NULL; } 626 V8_INLINE static bool IsTaggedTemplate(const Expression* tag) { 627 return tag != NULL; 628 } 629 630 V8_INLINE ZoneList<v8::internal::Expression*>* PrepareSpreadArguments( 631 ZoneList<v8::internal::Expression*>* list); 632 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {} 633 V8_INLINE Expression* SpreadCall(Expression* function, 634 ZoneList<v8::internal::Expression*>* args, 635 int pos); 636 V8_INLINE Expression* SpreadCallNew(Expression* function, 637 ZoneList<v8::internal::Expression*>* args, 638 int pos); 639 640 // Rewrite all DestructuringAssignments in the current FunctionState. 641 V8_INLINE void RewriteDestructuringAssignments(); 642 643 V8_INLINE void QueueDestructuringAssignmentForRewriting( 644 Expression* assignment); 645 646 void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property, 647 const AstRawString* name); 648 649 void SetFunctionNameFromIdentifierRef(Expression* value, 650 Expression* identifier); 651 652 // Rewrite expressions that are not used as patterns 653 V8_INLINE Expression* RewriteNonPattern( 654 Expression* expr, const ExpressionClassifier* classifier, bool* ok); 655 V8_INLINE ZoneList<Expression*>* RewriteNonPatternArguments( 656 ZoneList<Expression*>* args, const ExpressionClassifier* classifier, 657 bool* ok); 658 V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty( 659 ObjectLiteralProperty* property, const ExpressionClassifier* classifier, 660 bool* ok); 661 662 private: 663 Parser* parser_; 664 }; 665 666 667 class Parser : public ParserBase<ParserTraits> { 668 public: 669 explicit Parser(ParseInfo* info); 670 ~Parser() { 671 delete reusable_preparser_; 672 reusable_preparser_ = NULL; 673 delete cached_parse_data_; 674 cached_parse_data_ = NULL; 675 } 676 677 // Parses the source code represented by the compilation info and sets its 678 // function literal. Returns false (and deallocates any allocated AST 679 // nodes) if parsing failed. 680 static bool ParseStatic(ParseInfo* info); 681 bool Parse(ParseInfo* info); 682 void ParseOnBackground(ParseInfo* info); 683 684 // Handle errors detected during parsing, move statistics to Isolate, 685 // internalize strings (move them to the heap). 686 void Internalize(Isolate* isolate, Handle<Script> script, bool error); 687 void HandleSourceURLComments(Isolate* isolate, Handle<Script> script); 688 689 private: 690 friend class ParserTraits; 691 692 // Limit the allowed number of local variables in a function. The hard limit 693 // is that offsets computed by FullCodeGenerator::StackOperand and similar 694 // functions are ints, and they should not overflow. In addition, accessing 695 // local variables creates user-controlled constants in the generated code, 696 // and we don't want too much user-controlled memory inside the code (this was 697 // the reason why this limit was introduced in the first place; see 698 // https://codereview.chromium.org/7003030/ ). 699 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1 700 701 // Returns NULL if parsing failed. 702 FunctionLiteral* ParseProgram(Isolate* isolate, ParseInfo* info); 703 704 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info); 705 FunctionLiteral* ParseLazy(Isolate* isolate, ParseInfo* info, 706 Utf16CharacterStream* source); 707 708 // Called by ParseProgram after setting up the scanner. 709 FunctionLiteral* DoParseProgram(ParseInfo* info); 710 711 void SetCachedData(ParseInfo* info); 712 713 ScriptCompiler::CompileOptions compile_options() const { 714 return compile_options_; 715 } 716 bool consume_cached_parse_data() const { 717 return compile_options_ == ScriptCompiler::kConsumeParserCache && 718 cached_parse_data_ != NULL; 719 } 720 bool produce_cached_parse_data() const { 721 return compile_options_ == ScriptCompiler::kProduceParserCache; 722 } 723 724 // All ParseXXX functions take as the last argument an *ok parameter 725 // which is set to false if parsing failed; it is unchanged otherwise. 726 // By making the 'exception handling' explicit, we are forced to check 727 // for failure at the call sites. 728 void* ParseStatementList(ZoneList<Statement*>* body, int end_token, bool* ok); 729 Statement* ParseStatementListItem(bool* ok); 730 void* ParseModuleItemList(ZoneList<Statement*>* body, bool* ok); 731 Statement* ParseModuleItem(bool* ok); 732 const AstRawString* ParseModuleSpecifier(bool* ok); 733 Statement* ParseImportDeclaration(bool* ok); 734 Statement* ParseExportDeclaration(bool* ok); 735 Statement* ParseExportDefault(bool* ok); 736 void* ParseExportClause(ZoneList<const AstRawString*>* export_names, 737 ZoneList<Scanner::Location>* export_locations, 738 ZoneList<const AstRawString*>* local_names, 739 Scanner::Location* reserved_loc, bool* ok); 740 ZoneList<ImportDeclaration*>* ParseNamedImports(int pos, bool* ok); 741 Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok); 742 Statement* ParseSubStatement(ZoneList<const AstRawString*>* labels, bool* ok); 743 Statement* ParseStatementAsUnlabelled(ZoneList<const AstRawString*>* labels, 744 bool* ok); 745 Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names, 746 bool* ok); 747 Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names, 748 bool* ok); 749 Statement* ParseNativeDeclaration(bool* ok); 750 Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok); 751 Block* ParseBlock(ZoneList<const AstRawString*>* labels, 752 bool finalize_block_scope, bool* ok); 753 Block* ParseVariableStatement(VariableDeclarationContext var_context, 754 ZoneList<const AstRawString*>* names, 755 bool* ok); 756 DoExpression* ParseDoExpression(bool* ok); 757 758 struct DeclarationDescriptor { 759 enum Kind { NORMAL, PARAMETER }; 760 Parser* parser; 761 Scope* scope; 762 Scope* hoist_scope; 763 VariableMode mode; 764 bool needs_init; 765 int declaration_pos; 766 int initialization_pos; 767 Kind declaration_kind; 768 }; 769 770 struct DeclarationParsingResult { 771 struct Declaration { 772 Declaration(Expression* pattern, int initializer_position, 773 Expression* initializer) 774 : pattern(pattern), 775 initializer_position(initializer_position), 776 initializer(initializer) {} 777 778 Expression* pattern; 779 int initializer_position; 780 Expression* initializer; 781 }; 782 783 DeclarationParsingResult() 784 : declarations(4), 785 first_initializer_loc(Scanner::Location::invalid()), 786 bindings_loc(Scanner::Location::invalid()) {} 787 788 Block* BuildInitializationBlock(ZoneList<const AstRawString*>* names, 789 bool* ok); 790 791 DeclarationDescriptor descriptor; 792 List<Declaration> declarations; 793 Scanner::Location first_initializer_loc; 794 Scanner::Location bindings_loc; 795 }; 796 797 class PatternRewriter : private AstVisitor { 798 public: 799 static void DeclareAndInitializeVariables( 800 Block* block, const DeclarationDescriptor* declaration_descriptor, 801 const DeclarationParsingResult::Declaration* declaration, 802 ZoneList<const AstRawString*>* names, bool* ok); 803 804 static void RewriteDestructuringAssignment( 805 Parser* parser, RewritableAssignmentExpression* expr, Scope* Scope); 806 807 static Expression* RewriteDestructuringAssignment(Parser* parser, 808 Assignment* assignment, 809 Scope* scope); 810 811 void set_initializer_position(int pos) { initializer_position_ = pos; } 812 813 private: 814 PatternRewriter() {} 815 816 #define DECLARE_VISIT(type) void Visit##type(v8::internal::type* node) override; 817 // Visiting functions for AST nodes make this an AstVisitor. 818 AST_NODE_LIST(DECLARE_VISIT) 819 #undef DECLARE_VISIT 820 void Visit(AstNode* node) override; 821 822 enum PatternContext { 823 BINDING, 824 INITIALIZER, 825 ASSIGNMENT, 826 ASSIGNMENT_INITIALIZER 827 }; 828 829 PatternContext context() const { return context_; } 830 void set_context(PatternContext context) { context_ = context; } 831 832 void RecurseIntoSubpattern(AstNode* pattern, Expression* value) { 833 Expression* old_value = current_value_; 834 current_value_ = value; 835 recursion_level_++; 836 pattern->Accept(this); 837 recursion_level_--; 838 current_value_ = old_value; 839 } 840 841 void VisitObjectLiteral(ObjectLiteral* node, Variable** temp_var); 842 void VisitArrayLiteral(ArrayLiteral* node, Variable** temp_var); 843 844 bool IsBindingContext() const { return IsBindingContext(context_); } 845 bool IsInitializerContext() const { return context_ != ASSIGNMENT; } 846 bool IsAssignmentContext() const { return IsAssignmentContext(context_); } 847 bool IsAssignmentContext(PatternContext c) const; 848 bool IsBindingContext(PatternContext c) const; 849 bool IsSubPattern() const { return recursion_level_ > 1; } 850 PatternContext SetAssignmentContextIfNeeded(Expression* node); 851 PatternContext SetInitializerContextIfNeeded(Expression* node); 852 853 Variable* CreateTempVar(Expression* value = nullptr); 854 855 AstNodeFactory* factory() const { return parser_->factory(); } 856 AstValueFactory* ast_value_factory() const { 857 return parser_->ast_value_factory(); 858 } 859 Zone* zone() const { return parser_->zone(); } 860 Scope* scope() const { return scope_; } 861 862 Scope* scope_; 863 Parser* parser_; 864 PatternContext context_; 865 Expression* pattern_; 866 int initializer_position_; 867 Block* block_; 868 const DeclarationDescriptor* descriptor_; 869 ZoneList<const AstRawString*>* names_; 870 Expression* current_value_; 871 int recursion_level_; 872 bool* ok_; 873 }; 874 875 876 void ParseVariableDeclarations(VariableDeclarationContext var_context, 877 DeclarationParsingResult* parsing_result, 878 bool* ok); 879 Statement* ParseExpressionOrLabelledStatement( 880 ZoneList<const AstRawString*>* labels, bool* ok); 881 IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels, 882 bool* ok); 883 Statement* ParseContinueStatement(bool* ok); 884 Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels, 885 bool* ok); 886 Statement* ParseReturnStatement(bool* ok); 887 Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels, 888 bool* ok); 889 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok); 890 Statement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels, 891 bool* ok); 892 DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels, 893 bool* ok); 894 WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels, 895 bool* ok); 896 Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok); 897 Statement* ParseThrowStatement(bool* ok); 898 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value); 899 TryStatement* ParseTryStatement(bool* ok); 900 DebuggerStatement* ParseDebuggerStatement(bool* ok); 901 902 // !%_IsJSReceiver(result = iterator.next()) && 903 // %ThrowIteratorResultNotAnObject(result) 904 Expression* BuildIteratorNextResult(Expression* iterator, Variable* result, 905 int pos); 906 907 908 // Initialize the components of a for-in / for-of statement. 909 void InitializeForEachStatement(ForEachStatement* stmt, Expression* each, 910 Expression* subject, Statement* body, 911 bool is_destructuring); 912 Statement* DesugarLexicalBindingsInForStatement( 913 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 914 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 915 Statement* body, bool* ok); 916 917 void RewriteDoExpression(Expression* expr, bool* ok); 918 919 FunctionLiteral* ParseFunctionLiteral( 920 const AstRawString* name, Scanner::Location function_name_location, 921 FunctionNameValidity function_name_validity, FunctionKind kind, 922 int function_token_position, FunctionLiteral::FunctionType type, 923 FunctionLiteral::ArityRestriction arity_restriction, 924 LanguageMode language_mode, bool* ok); 925 926 927 ClassLiteral* ParseClassLiteral(const AstRawString* name, 928 Scanner::Location class_name_location, 929 bool name_is_strict_reserved, int pos, 930 bool* ok); 931 932 // Magical syntax support. 933 Expression* ParseV8Intrinsic(bool* ok); 934 935 // Get odd-ball literals. 936 Literal* GetLiteralUndefined(int position); 937 938 // Check if the scope has conflicting var/let declarations from different 939 // scopes. This covers for example 940 // 941 // function f() { { { var x; } let x; } } 942 // function g() { { var x; let x; } } 943 // 944 // The var declarations are hoisted to the function scope, but originate from 945 // a scope where the name has also been let bound or the var declaration is 946 // hoisted over such a scope. 947 void CheckConflictingVarDeclarations(Scope* scope, bool* ok); 948 949 // Insert initializer statements for var-bindings shadowing parameter bindings 950 // from a non-simple parameter list. 951 void InsertShadowingVarBindingInitializers(Block* block); 952 953 // Implement sloppy block-scoped functions, ES2015 Annex B 3.3 954 void InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok); 955 956 // Parser support 957 VariableProxy* NewUnresolved(const AstRawString* name, VariableMode mode); 958 Variable* Declare(Declaration* declaration, 959 DeclarationDescriptor::Kind declaration_kind, bool resolve, 960 bool* ok, Scope* declaration_scope = nullptr); 961 962 bool TargetStackContainsLabel(const AstRawString* label); 963 BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok); 964 IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok); 965 966 Statement* BuildAssertIsCoercible(Variable* var); 967 968 // Factory methods. 969 FunctionLiteral* DefaultConstructor(bool call_super, Scope* scope, int pos, 970 int end_pos, LanguageMode language_mode); 971 972 // Skip over a lazy function, either using cached data if we have it, or 973 // by parsing the function with PreParser. Consumes the ending }. 974 // 975 // If bookmark is set, the (pre-)parser may decide to abort skipping 976 // in order to force the function to be eagerly parsed, after all. 977 // In this case, it'll reset the scanner using the bookmark. 978 void SkipLazyFunctionBody(int* materialized_literal_count, 979 int* expected_property_count, bool* ok, 980 Scanner::BookmarkScope* bookmark = nullptr); 981 982 PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser( 983 SingletonLogger* logger, Scanner::BookmarkScope* bookmark = nullptr); 984 985 Block* BuildParameterInitializationBlock( 986 const ParserFormalParameters& parameters, bool* ok); 987 988 // Consumes the ending }. 989 ZoneList<Statement*>* ParseEagerFunctionBody( 990 const AstRawString* function_name, int pos, 991 const ParserFormalParameters& parameters, FunctionKind kind, 992 FunctionLiteral::FunctionType function_type, bool* ok); 993 994 void ThrowPendingError(Isolate* isolate, Handle<Script> script); 995 996 TemplateLiteralState OpenTemplateLiteral(int pos); 997 void AddTemplateSpan(TemplateLiteralState* state, bool tail); 998 void AddTemplateExpression(TemplateLiteralState* state, 999 Expression* expression); 1000 Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start, 1001 Expression* tag); 1002 uint32_t ComputeTemplateLiteralHash(const TemplateLiteral* lit); 1003 1004 ZoneList<v8::internal::Expression*>* PrepareSpreadArguments( 1005 ZoneList<v8::internal::Expression*>* list); 1006 Expression* SpreadCall(Expression* function, 1007 ZoneList<v8::internal::Expression*>* args, int pos); 1008 Expression* SpreadCallNew(Expression* function, 1009 ZoneList<v8::internal::Expression*>* args, int pos); 1010 1011 void SetLanguageMode(Scope* scope, LanguageMode mode); 1012 void RaiseLanguageMode(LanguageMode mode); 1013 1014 V8_INLINE void RewriteDestructuringAssignments(); 1015 1016 V8_INLINE Expression* RewriteNonPattern( 1017 Expression* expr, const ExpressionClassifier* classifier, bool* ok); 1018 V8_INLINE ZoneList<Expression*>* RewriteNonPatternArguments( 1019 ZoneList<Expression*>* args, const ExpressionClassifier* classifier, 1020 bool* ok); 1021 V8_INLINE ObjectLiteralProperty* RewriteNonPatternObjectLiteralProperty( 1022 ObjectLiteralProperty* property, const ExpressionClassifier* classifier, 1023 bool* ok); 1024 1025 friend class InitializerRewriter; 1026 void RewriteParameterInitializer(Expression* expr, Scope* scope); 1027 1028 Scanner scanner_; 1029 PreParser* reusable_preparser_; 1030 Scope* original_scope_; // for ES5 function declarations in sloppy eval 1031 Target* target_stack_; // for break, continue statements 1032 ScriptCompiler::CompileOptions compile_options_; 1033 ParseData* cached_parse_data_; 1034 1035 PendingCompilationErrorHandler pending_error_handler_; 1036 1037 // Other information which will be stored in Parser and moved to Isolate after 1038 // parsing. 1039 int use_counts_[v8::Isolate::kUseCounterFeatureCount]; 1040 int total_preparse_skipped_; 1041 HistogramTimer* pre_parse_timer_; 1042 1043 bool parsing_on_main_thread_; 1044 }; 1045 1046 1047 bool ParserTraits::IsFutureStrictReserved( 1048 const AstRawString* identifier) const { 1049 return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier); 1050 } 1051 1052 1053 Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type, 1054 FunctionKind kind) { 1055 return parser_->NewScope(parent_scope, scope_type, kind); 1056 } 1057 1058 1059 const AstRawString* ParserTraits::EmptyIdentifierString() { 1060 return parser_->ast_value_factory()->empty_string(); 1061 } 1062 1063 1064 void ParserTraits::SkipLazyFunctionBody(int* materialized_literal_count, 1065 int* expected_property_count, bool* ok, 1066 Scanner::BookmarkScope* bookmark) { 1067 return parser_->SkipLazyFunctionBody(materialized_literal_count, 1068 expected_property_count, ok, bookmark); 1069 } 1070 1071 1072 ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody( 1073 const AstRawString* name, int pos, const ParserFormalParameters& parameters, 1074 FunctionKind kind, FunctionLiteral::FunctionType function_type, bool* ok) { 1075 return parser_->ParseEagerFunctionBody(name, pos, parameters, kind, 1076 function_type, ok); 1077 } 1078 1079 1080 void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope, 1081 bool* ok) { 1082 parser_->CheckConflictingVarDeclarations(scope, ok); 1083 } 1084 1085 1086 // Support for handling complex values (array and object literals) that 1087 // can be fully handled at compile time. 1088 class CompileTimeValue: public AllStatic { 1089 public: 1090 enum LiteralType { 1091 OBJECT_LITERAL_FAST_ELEMENTS, 1092 OBJECT_LITERAL_SLOW_ELEMENTS, 1093 ARRAY_LITERAL 1094 }; 1095 1096 static bool IsCompileTimeValue(Expression* expression); 1097 1098 // Get the value as a compile time value. 1099 static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression); 1100 1101 // Get the type of a compile time value returned by GetValue(). 1102 static LiteralType GetLiteralType(Handle<FixedArray> value); 1103 1104 // Get the elements array of a compile time value returned by GetValue(). 1105 static Handle<FixedArray> GetElements(Handle<FixedArray> value); 1106 1107 private: 1108 static const int kLiteralTypeSlot = 0; 1109 static const int kElementsSlot = 1; 1110 1111 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); 1112 }; 1113 1114 1115 ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) { 1116 return parser_->OpenTemplateLiteral(pos); 1117 } 1118 1119 1120 void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) { 1121 parser_->AddTemplateSpan(state, tail); 1122 } 1123 1124 1125 void ParserTraits::AddTemplateExpression(TemplateLiteralState* state, 1126 Expression* expression) { 1127 parser_->AddTemplateExpression(state, expression); 1128 } 1129 1130 1131 Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state, 1132 int start, Expression* tag) { 1133 return parser_->CloseTemplateLiteral(state, start, tag); 1134 } 1135 1136 1137 ZoneList<v8::internal::Expression*>* ParserTraits::PrepareSpreadArguments( 1138 ZoneList<v8::internal::Expression*>* list) { 1139 return parser_->PrepareSpreadArguments(list); 1140 } 1141 1142 1143 Expression* ParserTraits::SpreadCall(Expression* function, 1144 ZoneList<v8::internal::Expression*>* args, 1145 int pos) { 1146 return parser_->SpreadCall(function, args, pos); 1147 } 1148 1149 1150 Expression* ParserTraits::SpreadCallNew( 1151 Expression* function, ZoneList<v8::internal::Expression*>* args, int pos) { 1152 return parser_->SpreadCallNew(function, args, pos); 1153 } 1154 1155 1156 void ParserTraits::AddFormalParameter(ParserFormalParameters* parameters, 1157 Expression* pattern, 1158 Expression* initializer, 1159 int initializer_end_position, 1160 bool is_rest) { 1161 bool is_simple = pattern->IsVariableProxy() && initializer == nullptr; 1162 const AstRawString* name = is_simple 1163 ? pattern->AsVariableProxy()->raw_name() 1164 : parser_->ast_value_factory()->empty_string(); 1165 parameters->params.Add( 1166 ParserFormalParameters::Parameter(name, pattern, initializer, 1167 initializer_end_position, is_rest), 1168 parameters->scope->zone()); 1169 } 1170 1171 1172 void ParserTraits::DeclareFormalParameter( 1173 Scope* scope, const ParserFormalParameters::Parameter& parameter, 1174 ExpressionClassifier* classifier) { 1175 bool is_duplicate = false; 1176 bool is_simple = classifier->is_simple_parameter_list(); 1177 auto name = is_simple || parameter.is_rest 1178 ? parameter.name 1179 : parser_->ast_value_factory()->empty_string(); 1180 auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY; 1181 if (!is_simple) scope->SetHasNonSimpleParameters(); 1182 bool is_optional = parameter.initializer != nullptr; 1183 Variable* var = scope->DeclareParameter( 1184 name, mode, is_optional, parameter.is_rest, &is_duplicate); 1185 if (is_duplicate) { 1186 classifier->RecordDuplicateFormalParameterError( 1187 parser_->scanner()->location()); 1188 } 1189 if (is_sloppy(scope->language_mode())) { 1190 // TODO(sigurds) Mark every parameter as maybe assigned. This is a 1191 // conservative approximation necessary to account for parameters 1192 // that are assigned via the arguments array. 1193 var->set_maybe_assigned(); 1194 } 1195 } 1196 1197 1198 void ParserTraits::AddParameterInitializationBlock( 1199 const ParserFormalParameters& parameters, 1200 ZoneList<v8::internal::Statement*>* body, bool* ok) { 1201 if (!parameters.is_simple) { 1202 auto* init_block = 1203 parser_->BuildParameterInitializationBlock(parameters, ok); 1204 if (!*ok) return; 1205 if (init_block != nullptr) { 1206 body->Add(init_block, parser_->zone()); 1207 } 1208 } 1209 } 1210 1211 1212 DoExpression* ParserTraits::ParseDoExpression(bool* ok) { 1213 return parser_->ParseDoExpression(ok); 1214 } 1215 1216 1217 } // namespace internal 1218 } // namespace v8 1219 1220 #endif // V8_PARSING_PARSER_H_ 1221