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 } | |
rmcilroy
2017/01/13 09:53:57
nit - newline
Leszek Swirski
2017/01/13 10:58:10
Done.
| |
646 // Build array literal constant elements | |
647 for (std::pair<ArrayLiteral*, size_t> literal : array_literals_) { | |
648 ArrayLiteral* array_literal = literal.first; | |
649 Handle<ConstantElementsPair> constant_elements = | |
650 array_literal->GetOrBuildConstantElements(isolate); | |
651 builder()->InsertConstantPoolEntryAt(literal.second, constant_elements); | |
652 } | |
631 } | 653 } |
632 | 654 |
633 void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) { | 655 void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) { |
634 DisallowHeapAllocation no_allocation; | 656 DisallowHeapAllocation no_allocation; |
635 DisallowHandleAllocation no_handles; | 657 DisallowHandleAllocation no_handles; |
636 DisallowHandleDereference no_deref; | 658 DisallowHandleDereference no_deref; |
637 | 659 |
638 InitializeAstVisitor(stack_limit); | 660 InitializeAstVisitor(stack_limit); |
639 | 661 |
640 // Initialize the incoming context. | 662 // Initialize the incoming context. |
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1604 expr->flags()); | 1626 expr->flags()); |
1605 } | 1627 } |
1606 | 1628 |
1607 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1629 void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
1608 // Deep-copy the literal boilerplate. | 1630 // Deep-copy the literal boilerplate. |
1609 uint8_t flags = CreateObjectLiteralFlags::Encode( | 1631 uint8_t flags = CreateObjectLiteralFlags::Encode( |
1610 expr->IsFastCloningSupported(), | 1632 expr->IsFastCloningSupported(), |
1611 ConstructorBuiltinsAssembler::FastCloneShallowObjectPropertiesCount( | 1633 ConstructorBuiltinsAssembler::FastCloneShallowObjectPropertiesCount( |
1612 expr->properties_count()), | 1634 expr->properties_count()), |
1613 expr->ComputeFlags()); | 1635 expr->ComputeFlags()); |
1614 // If constant properties is an empty fixed array, use our cached | 1636 |
1615 // empty_fixed_array to ensure it's only added to the constant pool once. | |
1616 Handle<FixedArray> constant_properties = expr->properties_count() == 0 | |
1617 ? empty_fixed_array() | |
1618 : expr->constant_properties(); | |
1619 Register literal = register_allocator()->NewRegister(); | 1637 Register literal = register_allocator()->NewRegister(); |
1620 builder()->CreateObjectLiteral(constant_properties, expr->literal_index(), | 1638 size_t entry; |
1621 flags, literal); | 1639 if (expr->properties_count() == 0) { |
1640 entry = builder()->GetConstantPoolEntry(empty_fixed_array()); | |
1641 } else { | |
1642 entry = builder()->AllocateConstantPoolEntry(); | |
1643 object_literals_.push_back(std::make_pair(expr, entry)); | |
1644 } | |
1645 builder()->CreateObjectLiteral(entry, expr->literal_index(), flags, literal); | |
1622 | 1646 |
1623 // Store computed values into the literal. | 1647 // Store computed values into the literal. |
1624 int property_index = 0; | 1648 int property_index = 0; |
1625 AccessorTable accessor_table(zone()); | 1649 AccessorTable accessor_table(zone()); |
1626 for (; property_index < expr->properties()->length(); property_index++) { | 1650 for (; property_index < expr->properties()->length(); property_index++) { |
1627 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1651 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1628 if (property->is_computed_name()) break; | 1652 if (property->is_computed_name()) break; |
1629 if (property->IsCompileTimeValue()) continue; | 1653 if (property->IsCompileTimeValue()) continue; |
1630 | 1654 |
1631 RegisterAllocationScope inner_register_scope(this); | 1655 RegisterAllocationScope inner_register_scope(this); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1793 } | 1817 } |
1794 } | 1818 } |
1795 | 1819 |
1796 builder()->LoadAccumulatorWithRegister(literal); | 1820 builder()->LoadAccumulatorWithRegister(literal); |
1797 } | 1821 } |
1798 | 1822 |
1799 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1823 void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
1800 // Deep-copy the literal boilerplate. | 1824 // Deep-copy the literal boilerplate. |
1801 uint8_t flags = CreateArrayLiteralFlags::Encode( | 1825 uint8_t flags = CreateArrayLiteralFlags::Encode( |
1802 expr->IsFastCloningSupported(), expr->ComputeFlags()); | 1826 expr->IsFastCloningSupported(), expr->ComputeFlags()); |
1803 builder()->CreateArrayLiteral(expr->constant_elements(), | 1827 |
1804 expr->literal_index(), flags); | 1828 size_t entry = builder()->AllocateConstantPoolEntry(); |
1829 builder()->CreateArrayLiteral(entry, expr->literal_index(), flags); | |
1830 array_literals_.push_back(std::make_pair(expr, entry)); | |
1831 | |
1805 Register index, literal; | 1832 Register index, literal; |
1806 | 1833 |
1807 // Evaluate all the non-constant subexpressions and store them into the | 1834 // Evaluate all the non-constant subexpressions and store them into the |
1808 // newly cloned array. | 1835 // newly cloned array. |
1809 bool literal_in_accumulator = true; | 1836 bool literal_in_accumulator = true; |
1810 for (int array_index = 0; array_index < expr->values()->length(); | 1837 for (int array_index = 0; array_index < expr->values()->length(); |
1811 array_index++) { | 1838 array_index++) { |
1812 Expression* subexpr = expr->values()->at(array_index); | 1839 Expression* subexpr = expr->values()->at(array_index); |
1813 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1840 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1814 DCHECK(!subexpr->IsSpread()); | 1841 DCHECK(!subexpr->IsSpread()); |
(...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3321 } | 3348 } |
3322 | 3349 |
3323 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3350 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3324 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3351 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3325 : Runtime::kStoreKeyedToSuper_Sloppy; | 3352 : Runtime::kStoreKeyedToSuper_Sloppy; |
3326 } | 3353 } |
3327 | 3354 |
3328 } // namespace interpreter | 3355 } // namespace interpreter |
3329 } // namespace internal | 3356 } // namespace internal |
3330 } // namespace v8 | 3357 } // namespace v8 |
OLD | NEW |