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 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 info->isolate(), info->zone(), info->num_parameters_including_this(), | 570 info->isolate(), info->zone(), info->num_parameters_including_this(), |
571 info->scope()->MaxNestedContextChainLength(), | 571 info->scope()->MaxNestedContextChainLength(), |
572 info->scope()->num_stack_slots(), info->literal(), | 572 info->scope()->num_stack_slots(), info->literal(), |
573 info->SourcePositionRecordingMode())), | 573 info->SourcePositionRecordingMode())), |
574 info_(info), | 574 info_(info), |
575 scope_(info->scope()), | 575 scope_(info->scope()), |
576 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())), | 576 globals_builder_(new (zone()) GlobalDeclarationsBuilder(info->zone())), |
577 global_declarations_(0, info->zone()), | 577 global_declarations_(0, info->zone()), |
578 function_literals_(0, info->zone()), | 578 function_literals_(0, info->zone()), |
579 native_function_literals_(0, info->zone()), | 579 native_function_literals_(0, info->zone()), |
| 580 object_literals_(0, info->zone()), |
| 581 array_literals_(0, info->zone()), |
580 execution_control_(nullptr), | 582 execution_control_(nullptr), |
581 execution_context_(nullptr), | 583 execution_context_(nullptr), |
582 execution_result_(nullptr), | 584 execution_result_(nullptr), |
583 generator_resume_points_(info->literal()->yield_count(), info->zone()), | 585 generator_resume_points_(info->literal()->yield_count(), info->zone()), |
584 generator_state_(), | 586 generator_state_(), |
585 loop_depth_(0), | 587 loop_depth_(0), |
586 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), | 588 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), |
587 iterator_symbol_(info->isolate()->factory()->iterator_symbol()), | 589 iterator_symbol_(info->isolate()->factory()->iterator_symbol()), |
588 empty_fixed_array_(info->isolate()->factory()->empty_fixed_array()) { | 590 empty_fixed_array_(info->isolate()->factory()->empty_fixed_array()) { |
589 AstValueFactory* ast_value_factory = info->parse_info()->ast_value_factory(); | 591 AstValueFactory* ast_value_factory = info->parse_info()->ast_value_factory(); |
590 const AstRawString* prototype_string = ast_value_factory->prototype_string(); | 592 const AstRawString* prototype_string = ast_value_factory->prototype_string(); |
591 ast_value_factory->Internalize(info->isolate()); | 593 ast_value_factory->Internalize(info->isolate()); |
592 prototype_string_ = prototype_string->string(); | 594 prototype_string_ = prototype_string->string(); |
593 undefined_string_ = ast_value_factory->undefined_string(); | 595 undefined_string_ = ast_value_factory->undefined_string(); |
594 } | 596 } |
595 | 597 |
596 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { | 598 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
597 AllocateDeferredConstants(); | 599 AllocateDeferredConstants(isolate); |
598 if (HasStackOverflow()) return Handle<BytecodeArray>(); | 600 if (HasStackOverflow()) return Handle<BytecodeArray>(); |
599 return builder()->ToBytecodeArray(isolate); | 601 return builder()->ToBytecodeArray(isolate); |
600 } | 602 } |
601 | 603 |
602 void BytecodeGenerator::AllocateDeferredConstants() { | 604 void BytecodeGenerator::AllocateDeferredConstants(Isolate* isolate) { |
603 // Build global declaration pair arrays. | 605 // Build global declaration pair arrays. |
604 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { | 606 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { |
605 Handle<FixedArray> declarations = | 607 Handle<FixedArray> declarations = |
606 globals_builder->AllocateDeclarations(info()); | 608 globals_builder->AllocateDeclarations(info()); |
607 if (declarations.is_null()) return SetStackOverflow(); | 609 if (declarations.is_null()) return SetStackOverflow(); |
608 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), | 610 builder()->InsertConstantPoolEntryAt(globals_builder->constant_pool_entry(), |
609 declarations); | 611 declarations); |
610 } | 612 } |
611 | 613 |
612 // Find or build shared function infos. | 614 // Find or build shared function infos. |
613 for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) { | 615 for (std::pair<FunctionLiteral*, size_t> literal : function_literals_) { |
614 FunctionLiteral* expr = literal.first; | 616 FunctionLiteral* expr = literal.first; |
615 Handle<SharedFunctionInfo> shared_info = | 617 Handle<SharedFunctionInfo> shared_info = |
616 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); | 618 Compiler::GetSharedFunctionInfo(expr, info()->script(), info()); |
617 if (shared_info.is_null()) return SetStackOverflow(); | 619 if (shared_info.is_null()) return SetStackOverflow(); |
618 builder()->InsertConstantPoolEntryAt(literal.second, shared_info); | 620 builder()->InsertConstantPoolEntryAt(literal.second, shared_info); |
619 } | 621 } |
620 | 622 |
621 // Find or build shared function infos for the native function templates. | 623 // Find or build shared function infos for the native function templates. |
622 for (std::pair<NativeFunctionLiteral*, size_t> literal : | 624 for (std::pair<NativeFunctionLiteral*, size_t> literal : |
623 native_function_literals_) { | 625 native_function_literals_) { |
624 NativeFunctionLiteral* expr = literal.first; | 626 NativeFunctionLiteral* expr = literal.first; |
625 Handle<SharedFunctionInfo> shared_info = | 627 Handle<SharedFunctionInfo> shared_info = |
626 Compiler::GetSharedFunctionInfoForNative(expr->extension(), | 628 Compiler::GetSharedFunctionInfoForNative(expr->extension(), |
627 expr->name()); | 629 expr->name()); |
628 if (shared_info.is_null()) return SetStackOverflow(); | 630 if (shared_info.is_null()) return SetStackOverflow(); |
629 builder()->InsertConstantPoolEntryAt(literal.second, shared_info); | 631 builder()->InsertConstantPoolEntryAt(literal.second, shared_info); |
630 } | 632 } |
| 633 |
| 634 // Build object literal constant properties |
| 635 for (std::pair<ObjectLiteral*, size_t> literal : object_literals_) { |
| 636 ObjectLiteral* object_literal = literal.first; |
| 637 if (object_literal->properties_count() > 0) { |
| 638 // If constant properties is an empty fixed array, we've already added it |
| 639 // to the constant pool when visiting the object literal. |
| 640 Handle<FixedArray> constant_properties = |
| 641 object_literal->GetOrBuildConstantProperties(isolate); |
| 642 |
| 643 builder()->InsertConstantPoolEntryAt(literal.second, constant_properties); |
| 644 } |
| 645 } |
| 646 |
| 647 // Build array literal constant elements |
| 648 for (std::pair<ArrayLiteral*, size_t> literal : array_literals_) { |
| 649 ArrayLiteral* array_literal = literal.first; |
| 650 Handle<ConstantElementsPair> constant_elements = |
| 651 array_literal->GetOrBuildConstantElements(isolate); |
| 652 builder()->InsertConstantPoolEntryAt(literal.second, constant_elements); |
| 653 } |
631 } | 654 } |
632 | 655 |
633 void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) { | 656 void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) { |
634 DisallowHeapAllocation no_allocation; | 657 DisallowHeapAllocation no_allocation; |
635 DisallowHandleAllocation no_handles; | 658 DisallowHandleAllocation no_handles; |
636 DisallowHandleDereference no_deref; | 659 DisallowHandleDereference no_deref; |
637 | 660 |
638 InitializeAstVisitor(stack_limit); | 661 InitializeAstVisitor(stack_limit); |
639 | 662 |
640 // Initialize the incoming context. | 663 // Initialize the incoming context. |
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 expr->flags()); | 1627 expr->flags()); |
1605 } | 1628 } |
1606 | 1629 |
1607 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1630 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
1608 // Deep-copy the literal boilerplate. | 1631 // Deep-copy the literal boilerplate. |
1609 uint8_t flags = CreateObjectLiteralFlags::Encode( | 1632 uint8_t flags = CreateObjectLiteralFlags::Encode( |
1610 expr->IsFastCloningSupported(), | 1633 expr->IsFastCloningSupported(), |
1611 ConstructorBuiltinsAssembler::FastCloneShallowObjectPropertiesCount( | 1634 ConstructorBuiltinsAssembler::FastCloneShallowObjectPropertiesCount( |
1612 expr->properties_count()), | 1635 expr->properties_count()), |
1613 expr->ComputeFlags()); | 1636 expr->ComputeFlags()); |
| 1637 |
| 1638 Register literal = register_allocator()->NewRegister(); |
| 1639 size_t entry; |
1614 // If constant properties is an empty fixed array, use our cached | 1640 // If constant properties is an empty fixed array, use our cached |
1615 // empty_fixed_array to ensure it's only added to the constant pool once. | 1641 // empty_fixed_array to ensure it's only added to the constant pool once. |
1616 Handle<FixedArray> constant_properties = expr->properties_count() == 0 | 1642 if (expr->properties_count() == 0) { |
1617 ? empty_fixed_array() | 1643 entry = builder()->GetConstantPoolEntry(empty_fixed_array()); |
1618 : expr->constant_properties(); | 1644 } else { |
1619 Register literal = register_allocator()->NewRegister(); | 1645 entry = builder()->AllocateConstantPoolEntry(); |
1620 builder()->CreateObjectLiteral(constant_properties, expr->literal_index(), | 1646 object_literals_.push_back(std::make_pair(expr, entry)); |
1621 flags, literal); | 1647 } |
| 1648 builder()->CreateObjectLiteral(entry, expr->literal_index(), flags, literal); |
1622 | 1649 |
1623 // Store computed values into the literal. | 1650 // Store computed values into the literal. |
1624 int property_index = 0; | 1651 int property_index = 0; |
1625 AccessorTable accessor_table(zone()); | 1652 AccessorTable accessor_table(zone()); |
1626 for (; property_index < expr->properties()->length(); property_index++) { | 1653 for (; property_index < expr->properties()->length(); property_index++) { |
1627 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1654 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1628 if (property->is_computed_name()) break; | 1655 if (property->is_computed_name()) break; |
1629 if (property->IsCompileTimeValue()) continue; | 1656 if (property->IsCompileTimeValue()) continue; |
1630 | 1657 |
1631 RegisterAllocationScope inner_register_scope(this); | 1658 RegisterAllocationScope inner_register_scope(this); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1793 } | 1820 } |
1794 } | 1821 } |
1795 | 1822 |
1796 builder()->LoadAccumulatorWithRegister(literal); | 1823 builder()->LoadAccumulatorWithRegister(literal); |
1797 } | 1824 } |
1798 | 1825 |
1799 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1826 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
1800 // Deep-copy the literal boilerplate. | 1827 // Deep-copy the literal boilerplate. |
1801 uint8_t flags = CreateArrayLiteralFlags::Encode( | 1828 uint8_t flags = CreateArrayLiteralFlags::Encode( |
1802 expr->IsFastCloningSupported(), expr->ComputeFlags()); | 1829 expr->IsFastCloningSupported(), expr->ComputeFlags()); |
1803 builder()->CreateArrayLiteral(expr->constant_elements(), | 1830 |
1804 expr->literal_index(), flags); | 1831 size_t entry = builder()->AllocateConstantPoolEntry(); |
| 1832 builder()->CreateArrayLiteral(entry, expr->literal_index(), flags); |
| 1833 array_literals_.push_back(std::make_pair(expr, entry)); |
| 1834 |
1805 Register index, literal; | 1835 Register index, literal; |
1806 | 1836 |
1807 // Evaluate all the non-constant subexpressions and store them into the | 1837 // Evaluate all the non-constant subexpressions and store them into the |
1808 // newly cloned array. | 1838 // newly cloned array. |
1809 bool literal_in_accumulator = true; | 1839 bool literal_in_accumulator = true; |
1810 for (int array_index = 0; array_index < expr->values()->length(); | 1840 for (int array_index = 0; array_index < expr->values()->length(); |
1811 array_index++) { | 1841 array_index++) { |
1812 Expression* subexpr = expr->values()->at(array_index); | 1842 Expression* subexpr = expr->values()->at(array_index); |
1813 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1843 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1814 DCHECK(!subexpr->IsSpread()); | 1844 DCHECK(!subexpr->IsSpread()); |
(...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3321 } | 3351 } |
3322 | 3352 |
3323 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3353 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3324 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3354 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3325 : Runtime::kStoreKeyedToSuper_Sloppy; | 3355 : Runtime::kStoreKeyedToSuper_Sloppy; |
3326 } | 3356 } |
3327 | 3357 |
3328 } // namespace interpreter | 3358 } // namespace interpreter |
3329 } // namespace internal | 3359 } // namespace internal |
3330 } // namespace v8 | 3360 } // namespace v8 |
OLD | NEW |