OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
6 | 6 |
7 #include "src/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/builtins/builtins-constructor.h" | 9 #include "src/builtins/builtins-constructor.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 491 |
492 // Used to build a list of global declaration initial value pairs. | 492 // Used to build a list of global declaration initial value pairs. |
493 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { | 493 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { |
494 public: | 494 public: |
495 explicit GlobalDeclarationsBuilder(Zone* zone) | 495 explicit GlobalDeclarationsBuilder(Zone* zone) |
496 : declarations_(0, zone), | 496 : declarations_(0, zone), |
497 constant_pool_entry_(0), | 497 constant_pool_entry_(0), |
498 has_constant_pool_entry_(false) {} | 498 has_constant_pool_entry_(false) {} |
499 | 499 |
500 void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot, | 500 void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot, |
| 501 FeedbackVectorSlot literal_slot, |
501 FunctionLiteral* func) { | 502 FunctionLiteral* func) { |
502 DCHECK(!slot.IsInvalid()); | 503 DCHECK(!slot.IsInvalid()); |
503 declarations_.push_back(Declaration(name, slot, func)); | 504 declarations_.push_back(Declaration(name, slot, literal_slot, func)); |
504 } | 505 } |
505 | 506 |
506 void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) { | 507 void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) { |
507 DCHECK(!slot.IsInvalid()); | 508 DCHECK(!slot.IsInvalid()); |
508 declarations_.push_back(Declaration(name, slot, nullptr)); | 509 declarations_.push_back(Declaration(name, slot, nullptr)); |
509 } | 510 } |
510 | 511 |
511 Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) { | 512 Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) { |
512 DCHECK(has_constant_pool_entry_); | 513 DCHECK(has_constant_pool_entry_); |
513 int array_index = 0; | 514 int array_index = 0; |
514 Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( | 515 Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( |
515 static_cast<int>(declarations_.size() * 3), TENURED); | 516 static_cast<int>(declarations_.size() * 4), TENURED); |
516 for (const Declaration& declaration : declarations_) { | 517 for (const Declaration& declaration : declarations_) { |
517 FunctionLiteral* func = declaration.func; | 518 FunctionLiteral* func = declaration.func; |
518 Handle<Object> initial_value; | 519 Handle<Object> initial_value; |
519 if (func == nullptr) { | 520 if (func == nullptr) { |
520 initial_value = info->isolate()->factory()->undefined_value(); | 521 initial_value = info->isolate()->factory()->undefined_value(); |
521 } else { | 522 } else { |
522 initial_value = | 523 initial_value = |
523 Compiler::GetSharedFunctionInfo(func, info->script(), info); | 524 Compiler::GetSharedFunctionInfo(func, info->script(), info); |
524 } | 525 } |
525 | 526 |
526 // Return a null handle if any initial values can't be created. Caller | 527 // Return a null handle if any initial values can't be created. Caller |
527 // will set stack overflow. | 528 // will set stack overflow. |
528 if (initial_value.is_null()) return Handle<FixedArray>(); | 529 if (initial_value.is_null()) return Handle<FixedArray>(); |
529 | 530 |
530 data->set(array_index++, *declaration.name); | 531 data->set(array_index++, *declaration.name); |
531 data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); | 532 data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); |
| 533 Object* undefined_or_literal_slot; |
| 534 if (declaration.literal_slot.IsInvalid()) { |
| 535 undefined_or_literal_slot = info->isolate()->heap()->undefined_value(); |
| 536 } else { |
| 537 undefined_or_literal_slot = |
| 538 Smi::FromInt(declaration.literal_slot.ToInt()); |
| 539 } |
| 540 data->set(array_index++, undefined_or_literal_slot); |
532 data->set(array_index++, *initial_value); | 541 data->set(array_index++, *initial_value); |
533 } | 542 } |
534 return data; | 543 return data; |
535 } | 544 } |
536 | 545 |
537 size_t constant_pool_entry() { | 546 size_t constant_pool_entry() { |
538 DCHECK(has_constant_pool_entry_); | 547 DCHECK(has_constant_pool_entry_); |
539 return constant_pool_entry_; | 548 return constant_pool_entry_; |
540 } | 549 } |
541 | 550 |
542 void set_constant_pool_entry(size_t constant_pool_entry) { | 551 void set_constant_pool_entry(size_t constant_pool_entry) { |
543 DCHECK(!empty()); | 552 DCHECK(!empty()); |
544 DCHECK(!has_constant_pool_entry_); | 553 DCHECK(!has_constant_pool_entry_); |
545 constant_pool_entry_ = constant_pool_entry; | 554 constant_pool_entry_ = constant_pool_entry; |
546 has_constant_pool_entry_ = true; | 555 has_constant_pool_entry_ = true; |
547 } | 556 } |
548 | 557 |
549 bool empty() { return declarations_.empty(); } | 558 bool empty() { return declarations_.empty(); } |
550 | 559 |
551 private: | 560 private: |
552 struct Declaration { | 561 struct Declaration { |
553 Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} | 562 Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} |
554 Declaration(Handle<String> name, FeedbackVectorSlot slot, | 563 Declaration(Handle<String> name, FeedbackVectorSlot slot, |
| 564 FeedbackVectorSlot literal_slot, FunctionLiteral* func) |
| 565 : name(name), slot(slot), literal_slot(literal_slot), func(func) {} |
| 566 Declaration(Handle<String> name, FeedbackVectorSlot slot, |
555 FunctionLiteral* func) | 567 FunctionLiteral* func) |
556 : name(name), slot(slot), func(func) {} | 568 : name(name), |
| 569 slot(slot), |
| 570 literal_slot(FeedbackVectorSlot::Invalid()), |
| 571 func(func) {} |
557 | 572 |
558 Handle<String> name; | 573 Handle<String> name; |
559 FeedbackVectorSlot slot; | 574 FeedbackVectorSlot slot; |
| 575 FeedbackVectorSlot literal_slot; |
560 FunctionLiteral* func; | 576 FunctionLiteral* func; |
561 }; | 577 }; |
562 ZoneVector<Declaration> declarations_; | 578 ZoneVector<Declaration> declarations_; |
563 size_t constant_pool_entry_; | 579 size_t constant_pool_entry_; |
564 bool has_constant_pool_entry_; | 580 bool has_constant_pool_entry_; |
565 }; | 581 }; |
566 | 582 |
567 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) | 583 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) |
568 : zone_(info->zone()), | 584 : zone_(info->zone()), |
569 builder_(new (zone()) BytecodeArrayBuilder( | 585 builder_(new (zone()) BytecodeArrayBuilder( |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 break; | 898 break; |
883 } | 899 } |
884 } | 900 } |
885 | 901 |
886 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 902 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
887 Variable* variable = decl->proxy()->var(); | 903 Variable* variable = decl->proxy()->var(); |
888 DCHECK(variable->mode() == LET || variable->mode() == VAR); | 904 DCHECK(variable->mode() == LET || variable->mode() == VAR); |
889 switch (variable->location()) { | 905 switch (variable->location()) { |
890 case VariableLocation::UNALLOCATED: { | 906 case VariableLocation::UNALLOCATED: { |
891 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 907 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
892 globals_builder()->AddFunctionDeclaration(variable->name(), slot, | 908 globals_builder()->AddFunctionDeclaration( |
893 decl->fun()); | 909 variable->name(), slot, decl->fun()->LiteralFeedbackSlot(), |
| 910 decl->fun()); |
894 break; | 911 break; |
895 } | 912 } |
896 case VariableLocation::PARAMETER: | 913 case VariableLocation::PARAMETER: |
897 case VariableLocation::LOCAL: { | 914 case VariableLocation::LOCAL: { |
898 VisitForAccumulatorValue(decl->fun()); | 915 VisitForAccumulatorValue(decl->fun()); |
899 BuildVariableAssignment(variable, Token::INIT, | 916 BuildVariableAssignment(variable, Token::INIT, |
900 FeedbackVectorSlot::Invalid(), | 917 FeedbackVectorSlot::Invalid(), |
901 HoleCheckMode::kElided); | 918 HoleCheckMode::kElided); |
902 break; | 919 break; |
903 } | 920 } |
(...skipping 2470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3374 } | 3391 } |
3375 | 3392 |
3376 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3393 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3377 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3394 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3378 : Runtime::kStoreKeyedToSuper_Sloppy; | 3395 : Runtime::kStoreKeyedToSuper_Sloppy; |
3379 } | 3396 } |
3380 | 3397 |
3381 } // namespace interpreter | 3398 } // namespace interpreter |
3382 } // namespace internal | 3399 } // namespace internal |
3383 } // namespace v8 | 3400 } // namespace v8 |
OLD | NEW |