| 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 |