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/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-info.h" | 10 #include "src/compilation-info.h" |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 }; | 489 }; |
490 | 490 |
491 // Used to build a list of global declaration initial value pairs. | 491 // Used to build a list of global declaration initial value pairs. |
492 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { | 492 class BytecodeGenerator::GlobalDeclarationsBuilder final : public ZoneObject { |
493 public: | 493 public: |
494 explicit GlobalDeclarationsBuilder(Zone* zone) | 494 explicit GlobalDeclarationsBuilder(Zone* zone) |
495 : declarations_(0, zone), | 495 : declarations_(0, zone), |
496 constant_pool_entry_(0), | 496 constant_pool_entry_(0), |
497 has_constant_pool_entry_(false) {} | 497 has_constant_pool_entry_(false) {} |
498 | 498 |
499 void AddFunctionDeclaration(FeedbackVectorSlot slot, FunctionLiteral* func) { | 499 void AddFunctionDeclaration(Handle<String> name, FeedbackVectorSlot slot, |
| 500 FunctionLiteral* func) { |
500 DCHECK(!slot.IsInvalid()); | 501 DCHECK(!slot.IsInvalid()); |
501 declarations_.push_back(std::make_pair(slot, func)); | 502 declarations_.push_back(Declaration(name, slot, func)); |
502 } | 503 } |
503 | 504 |
504 void AddUndefinedDeclaration(FeedbackVectorSlot slot) { | 505 void AddUndefinedDeclaration(Handle<String> name, FeedbackVectorSlot slot) { |
505 DCHECK(!slot.IsInvalid()); | 506 DCHECK(!slot.IsInvalid()); |
506 declarations_.push_back(std::make_pair(slot, nullptr)); | 507 declarations_.push_back(Declaration(name, slot, nullptr)); |
507 } | 508 } |
508 | 509 |
509 Handle<FixedArray> AllocateDeclarationPairs(CompilationInfo* info) { | 510 Handle<FixedArray> AllocateDeclarations(CompilationInfo* info) { |
510 DCHECK(has_constant_pool_entry_); | 511 DCHECK(has_constant_pool_entry_); |
511 int array_index = 0; | 512 int array_index = 0; |
512 Handle<FixedArray> pairs = info->isolate()->factory()->NewFixedArray( | 513 Handle<FixedArray> data = info->isolate()->factory()->NewFixedArray( |
513 static_cast<int>(declarations_.size() * 2), TENURED); | 514 static_cast<int>(declarations_.size() * 3), TENURED); |
514 for (std::pair<FeedbackVectorSlot, FunctionLiteral*> declaration : | 515 for (const Declaration& declaration : declarations_) { |
515 declarations_) { | 516 FunctionLiteral* func = declaration.func; |
516 FunctionLiteral* func = declaration.second; | |
517 Handle<Object> initial_value; | 517 Handle<Object> initial_value; |
518 if (func == nullptr) { | 518 if (func == nullptr) { |
519 initial_value = info->isolate()->factory()->undefined_value(); | 519 initial_value = info->isolate()->factory()->undefined_value(); |
520 } else { | 520 } else { |
521 initial_value = | 521 initial_value = |
522 Compiler::GetSharedFunctionInfo(func, info->script(), info); | 522 Compiler::GetSharedFunctionInfo(func, info->script(), info); |
523 } | 523 } |
524 | 524 |
525 // Return a null handle if any initial values can't be created. Caller | 525 // Return a null handle if any initial values can't be created. Caller |
526 // will set stack overflow. | 526 // will set stack overflow. |
527 if (initial_value.is_null()) return Handle<FixedArray>(); | 527 if (initial_value.is_null()) return Handle<FixedArray>(); |
528 | 528 |
529 pairs->set(array_index++, Smi::FromInt(declaration.first.ToInt())); | 529 data->set(array_index++, *declaration.name); |
530 pairs->set(array_index++, *initial_value); | 530 data->set(array_index++, Smi::FromInt(declaration.slot.ToInt())); |
| 531 data->set(array_index++, *initial_value); |
531 } | 532 } |
532 return pairs; | 533 return data; |
533 } | 534 } |
534 | 535 |
535 size_t constant_pool_entry() { | 536 size_t constant_pool_entry() { |
536 DCHECK(has_constant_pool_entry_); | 537 DCHECK(has_constant_pool_entry_); |
537 return constant_pool_entry_; | 538 return constant_pool_entry_; |
538 } | 539 } |
539 | 540 |
540 void set_constant_pool_entry(size_t constant_pool_entry) { | 541 void set_constant_pool_entry(size_t constant_pool_entry) { |
541 DCHECK(!empty()); | 542 DCHECK(!empty()); |
542 DCHECK(!has_constant_pool_entry_); | 543 DCHECK(!has_constant_pool_entry_); |
543 constant_pool_entry_ = constant_pool_entry; | 544 constant_pool_entry_ = constant_pool_entry; |
544 has_constant_pool_entry_ = true; | 545 has_constant_pool_entry_ = true; |
545 } | 546 } |
546 | 547 |
547 bool empty() { return declarations_.empty(); } | 548 bool empty() { return declarations_.empty(); } |
548 | 549 |
549 private: | 550 private: |
550 ZoneVector<std::pair<FeedbackVectorSlot, FunctionLiteral*>> declarations_; | 551 struct Declaration { |
| 552 Declaration() : slot(FeedbackVectorSlot::Invalid()), func(nullptr) {} |
| 553 Declaration(Handle<String> name, FeedbackVectorSlot slot, |
| 554 FunctionLiteral* func) |
| 555 : name(name), slot(slot), func(func) {} |
| 556 |
| 557 Handle<String> name; |
| 558 FeedbackVectorSlot slot; |
| 559 FunctionLiteral* func; |
| 560 }; |
| 561 ZoneVector<Declaration> declarations_; |
551 size_t constant_pool_entry_; | 562 size_t constant_pool_entry_; |
552 bool has_constant_pool_entry_; | 563 bool has_constant_pool_entry_; |
553 }; | 564 }; |
554 | 565 |
555 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) | 566 BytecodeGenerator::BytecodeGenerator(CompilationInfo* info) |
556 : zone_(info->zone()), | 567 : zone_(info->zone()), |
557 builder_(new (zone()) BytecodeArrayBuilder( | 568 builder_(new (zone()) BytecodeArrayBuilder( |
558 info->isolate(), info->zone(), info->num_parameters_including_this(), | 569 info->isolate(), info->zone(), info->num_parameters_including_this(), |
559 info->scope()->MaxNestedContextChainLength(), | 570 info->scope()->MaxNestedContextChainLength(), |
560 info->scope()->num_stack_slots(), info->literal(), | 571 info->scope()->num_stack_slots(), info->literal(), |
(...skipping 21 matching lines...) Expand all Loading... |
582 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { | 593 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
583 AllocateDeferredConstants(); | 594 AllocateDeferredConstants(); |
584 if (HasStackOverflow()) return Handle<BytecodeArray>(); | 595 if (HasStackOverflow()) return Handle<BytecodeArray>(); |
585 return builder()->ToBytecodeArray(isolate); | 596 return builder()->ToBytecodeArray(isolate); |
586 } | 597 } |
587 | 598 |
588 void BytecodeGenerator::AllocateDeferredConstants() { | 599 void BytecodeGenerator::AllocateDeferredConstants() { |
589 // Build global declaration pair arrays. | 600 // Build global declaration pair arrays. |
590 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { | 601 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { |
591 Handle<FixedArray> declarations = | 602 Handle<FixedArray> declarations = |
592 globals_builder->AllocateDeclarationPairs(info()); | 603 globals_builder->AllocateDeclarations(info()); |
593 if (declarations.is_null()) return SetStackOverflow(); | 604 if (declarations.is_null()) return SetStackOverflow(); |
594 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), | 605 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), |
595 declarations); | 606 declarations); |
596 } | 607 } |
597 | 608 |
598 // Find or build shared function infos. | 609 // Find or build shared function infos. |
599 for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) { | 610 for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) { |
600 FunctionLiteral* expr = literal.first; | 611 FunctionLiteral* expr = literal.first; |
601 Handle<SharedFunctionInfo> shared_info = | 612 Handle<SharedFunctionInfo> shared_info = |
602 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); | 613 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 VisitStatements(stmt->statements()); | 799 VisitStatements(stmt->statements()); |
789 if (stmt->labels() != nullptr) block_builder.EndBlock(); | 800 if (stmt->labels() != nullptr) block_builder.EndBlock(); |
790 } | 801 } |
791 | 802 |
792 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { | 803 void BytecodeGenerator::VisitVariableDeclaration(VariableDeclaration* decl) { |
793 Variable* variable = decl->proxy()->var(); | 804 Variable* variable = decl->proxy()->var(); |
794 switch (variable->location()) { | 805 switch (variable->location()) { |
795 case VariableLocation::UNALLOCATED: { | 806 case VariableLocation::UNALLOCATED: { |
796 DCHECK(!variable->binding_needs_init()); | 807 DCHECK(!variable->binding_needs_init()); |
797 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 808 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
798 globals_builder()->AddUndefinedDeclaration(slot); | 809 globals_builder()->AddUndefinedDeclaration(variable->name(), slot); |
799 break; | 810 break; |
800 } | 811 } |
801 case VariableLocation::LOCAL: | 812 case VariableLocation::LOCAL: |
802 if (variable->binding_needs_init()) { | 813 if (variable->binding_needs_init()) { |
803 Register destination(variable->index()); | 814 Register destination(variable->index()); |
804 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); | 815 builder()->LoadTheHole().StoreAccumulatorInRegister(destination); |
805 } | 816 } |
806 break; | 817 break; |
807 case VariableLocation::PARAMETER: | 818 case VariableLocation::PARAMETER: |
808 if (variable->binding_needs_init()) { | 819 if (variable->binding_needs_init()) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 break; | 853 break; |
843 } | 854 } |
844 } | 855 } |
845 | 856 |
846 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { | 857 void BytecodeGenerator::VisitFunctionDeclaration(FunctionDeclaration* decl) { |
847 Variable* variable = decl->proxy()->var(); | 858 Variable* variable = decl->proxy()->var(); |
848 DCHECK(variable->mode() == LET || variable->mode() == VAR); | 859 DCHECK(variable->mode() == LET || variable->mode() == VAR); |
849 switch (variable->location()) { | 860 switch (variable->location()) { |
850 case VariableLocation::UNALLOCATED: { | 861 case VariableLocation::UNALLOCATED: { |
851 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); | 862 FeedbackVectorSlot slot = decl->proxy()->VariableFeedbackSlot(); |
852 globals_builder()->AddFunctionDeclaration(slot, decl->fun()); | 863 globals_builder()->AddFunctionDeclaration(variable->name(), slot, |
| 864 decl->fun()); |
853 break; | 865 break; |
854 } | 866 } |
855 case VariableLocation::PARAMETER: | 867 case VariableLocation::PARAMETER: |
856 case VariableLocation::LOCAL: { | 868 case VariableLocation::LOCAL: { |
857 VisitForAccumulatorValue(decl->fun()); | 869 VisitForAccumulatorValue(decl->fun()); |
858 BuildVariableAssignment(variable, Token::INIT, | 870 BuildVariableAssignment(variable, Token::INIT, |
859 FeedbackVectorSlot::Invalid(), | 871 FeedbackVectorSlot::Invalid(), |
860 HoleCheckMode::kElided); | 872 HoleCheckMode::kElided); |
861 break; | 873 break; |
862 } | 874 } |
(...skipping 2323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3186 } | 3198 } |
3187 | 3199 |
3188 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3200 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3189 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3201 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3190 : Runtime::kStoreKeyedToSuper_Sloppy; | 3202 : Runtime::kStoreKeyedToSuper_Sloppy; |
3191 } | 3203 } |
3192 | 3204 |
3193 } // namespace interpreter | 3205 } // namespace interpreter |
3194 } // namespace internal | 3206 } // namespace internal |
3195 } // namespace v8 | 3207 } // namespace v8 |
OLD | NEW |