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 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
676 function_literals_(0, info->zone()), | 676 function_literals_(0, info->zone()), |
677 native_function_literals_(0, info->zone()), | 677 native_function_literals_(0, info->zone()), |
678 execution_control_(nullptr), | 678 execution_control_(nullptr), |
679 execution_context_(nullptr), | 679 execution_context_(nullptr), |
680 execution_result_(nullptr), | 680 execution_result_(nullptr), |
681 register_allocator_(nullptr), | 681 register_allocator_(nullptr), |
682 generator_resume_points_(info->literal()->yield_count(), info->zone()), | 682 generator_resume_points_(info->literal()->yield_count(), info->zone()), |
683 generator_state_(), | 683 generator_state_(), |
684 loop_depth_(0), | 684 loop_depth_(0), |
685 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), | 685 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), |
686 prototype_string_(info->isolate()->factory()->prototype_string()) { | 686 prototype_string_(info->isolate()->factory()->prototype_string()), |
687 } | 687 name_string_(info->isolate()->factory()->name_string()), |
688 empty_string_(info->isolate()->factory()->empty_string()) {} | |
Henrique Ferreiro
2016/10/17 11:41:11
Leftover from a preview version
| |
688 | 689 |
689 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { | 690 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
690 AllocateDeferredConstants(); | 691 AllocateDeferredConstants(); |
691 if (HasStackOverflow()) return Handle<BytecodeArray>(); | 692 if (HasStackOverflow()) return Handle<BytecodeArray>(); |
692 return builder()->ToBytecodeArray(isolate); | 693 return builder()->ToBytecodeArray(isolate); |
693 } | 694 } |
694 | 695 |
695 void BytecodeGenerator::AllocateDeferredConstants() { | 696 void BytecodeGenerator::AllocateDeferredConstants() { |
696 // Build global declaration pair arrays. | 697 // Build global declaration pair arrays. |
697 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { | 698 for (GlobalDeclarationsBuilder* globals_builder : global_declarations_) { |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1486 register_allocator()->PrepareForConsecutiveAllocations(2); | 1487 register_allocator()->PrepareForConsecutiveAllocations(2); |
1487 Register literal = register_allocator()->NextConsecutiveRegister(); | 1488 Register literal = register_allocator()->NextConsecutiveRegister(); |
1488 Register prototype = register_allocator()->NextConsecutiveRegister(); | 1489 Register prototype = register_allocator()->NextConsecutiveRegister(); |
1489 FeedbackVectorSlot slot = expr->PrototypeSlot(); | 1490 FeedbackVectorSlot slot = expr->PrototypeSlot(); |
1490 builder() | 1491 builder() |
1491 ->StoreAccumulatorInRegister(literal) | 1492 ->StoreAccumulatorInRegister(literal) |
1492 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot)) | 1493 .LoadNamedProperty(literal, prototype_string(), feedback_index(slot)) |
1493 .StoreAccumulatorInRegister(prototype); | 1494 .StoreAccumulatorInRegister(prototype); |
1494 | 1495 |
1495 VisitClassLiteralProperties(expr, literal, prototype); | 1496 VisitClassLiteralProperties(expr, literal, prototype); |
1497 | |
1498 VisitClassLiteralNameProperty(expr, literal); | |
1499 | |
1496 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); | 1500 builder()->CallRuntime(Runtime::kToFastProperties, literal, 1); |
1497 // Assign to class variable. | 1501 // Assign to class variable. |
1498 if (expr->class_variable_proxy() != nullptr) { | 1502 if (expr->class_variable_proxy() != nullptr) { |
1499 Variable* var = expr->class_variable_proxy()->var(); | 1503 Variable* var = expr->class_variable_proxy()->var(); |
1500 FeedbackVectorSlot slot = expr->NeedsProxySlot() | 1504 FeedbackVectorSlot slot = expr->NeedsProxySlot() |
1501 ? expr->ProxySlot() | 1505 ? expr->ProxySlot() |
1502 : FeedbackVectorSlot::Invalid(); | 1506 : FeedbackVectorSlot::Invalid(); |
1503 VisitVariableAssignment(var, Token::INIT, slot); | 1507 VisitVariableAssignment(var, Token::INIT, slot); |
1504 } | 1508 } |
1505 execution_result()->SetResultInAccumulator(); | 1509 execution_result()->SetResultInAccumulator(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1605 Register key) { | 1609 Register key) { |
1606 BytecodeLabel done; | 1610 BytecodeLabel done; |
1607 builder() | 1611 builder() |
1608 ->LoadLiteral(prototype_string()) | 1612 ->LoadLiteral(prototype_string()) |
1609 .CompareOperation(Token::Value::EQ_STRICT, key) | 1613 .CompareOperation(Token::Value::EQ_STRICT, key) |
1610 .JumpIfFalse(&done) | 1614 .JumpIfFalse(&done) |
1611 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) | 1615 .CallRuntime(Runtime::kThrowStaticPrototypeError, Register(0), 0) |
1612 .Bind(&done); | 1616 .Bind(&done); |
1613 } | 1617 } |
1614 | 1618 |
1619 void BytecodeGenerator::VisitClassLiteralNameProperty(ClassLiteral* expr, | |
rmcilroy
2016/10/24 14:22:20
Nit - BuildClassLiteralNameProperty
| |
1620 Register literal) { | |
1621 DCHECK(!expr->constructor()->name().is_null()); | |
1622 | |
1623 // Abort if 'name' is undefined. | |
1624 // FIXME: fails many tests in a slow dcheck about dereferencing a handle | |
1625 if (expr->constructor()->name()->length() == 0) return; | |
Henrique Ferreiro
2016/10/17 11:41:11
Should I use a runtime function to check for this?
rmcilroy
2016/10/24 14:22:20
You could either do this in the runtime function I
caitp
2016/10/24 15:56:10
It looks like expr->class_variable_proxy() returns
Henrique Ferreiro
2016/11/08 22:28:58
I have moved everything to a runtime function. Is
caitp
2016/11/08 22:59:40
I'll defer to Ignition experts to answer that ---
rmcilroy
2016/11/10 12:37:44
A runtime call is just as expensive as it would be
Toon Verwaest
2016/11/24 07:16:23
This is exactly what I was referring to. Checking
| |
1626 | |
1627 BytecodeLabel end; | |
1628 | |
1629 RegisterAllocationScope register_scope(this); | |
1630 register_allocator()->PrepareForConsecutiveAllocations(5); | |
1631 Register receiver = register_allocator()->NextConsecutiveRegister(); | |
1632 Register key = register_allocator()->NextConsecutiveRegister(); | |
1633 Register value = register_allocator()->NextConsecutiveRegister(); | |
1634 Register attr = register_allocator()->NextConsecutiveRegister(); | |
1635 Register set_function_name = register_allocator()->NextConsecutiveRegister(); | |
1636 | |
1637 // If "name" is already defined, exit. | |
1638 builder() | |
1639 ->MoveRegister(literal, receiver) | |
1640 .LoadLiteral(name_string()) | |
1641 .StoreAccumulatorInRegister(key) | |
1642 .CallRuntime(Runtime::kObjectHasOwnProperty, receiver, 2) | |
1643 .JumpIfTrue(&end); | |
1644 | |
1645 // Define "name" property. | |
1646 builder() | |
1647 ->LoadLiteral(expr->constructor()->name()) | |
1648 .StoreAccumulatorInRegister(value) | |
1649 .LoadLiteral(Smi::FromInt(DONT_ENUM | READ_ONLY)) | |
1650 .StoreAccumulatorInRegister(attr) | |
1651 .LoadLiteral(Smi::FromInt(0)) | |
1652 .StoreAccumulatorInRegister(set_function_name) | |
1653 .CallRuntime(Runtime::kDefineDataPropertyInLiteral, receiver, 5); | |
rmcilroy
2016/10/24 14:22:20
Rather than creating a load of bytecode for this (
| |
1654 | |
1655 builder()->Bind(&end); | |
1656 } | |
1657 | |
1615 void BytecodeGenerator::VisitNativeFunctionLiteral( | 1658 void BytecodeGenerator::VisitNativeFunctionLiteral( |
1616 NativeFunctionLiteral* expr) { | 1659 NativeFunctionLiteral* expr) { |
1617 size_t entry = builder()->AllocateConstantPoolEntry(); | 1660 size_t entry = builder()->AllocateConstantPoolEntry(); |
1618 builder()->CreateClosure(entry, NOT_TENURED); | 1661 builder()->CreateClosure(entry, NOT_TENURED); |
1619 native_function_literals_.push_back(std::make_pair(expr, entry)); | 1662 native_function_literals_.push_back(std::make_pair(expr, entry)); |
1620 execution_result()->SetResultInAccumulator(); | 1663 execution_result()->SetResultInAccumulator(); |
1621 } | 1664 } |
1622 | 1665 |
1623 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { | 1666 void BytecodeGenerator::VisitDoExpression(DoExpression* expr) { |
1624 VisitBlock(expr->block()); | 1667 VisitBlock(expr->block()); |
(...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3463 return execution_context()->scope()->language_mode(); | 3506 return execution_context()->scope()->language_mode(); |
3464 } | 3507 } |
3465 | 3508 |
3466 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3509 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
3467 return TypeFeedbackVector::GetIndex(slot); | 3510 return TypeFeedbackVector::GetIndex(slot); |
3468 } | 3511 } |
3469 | 3512 |
3470 } // namespace interpreter | 3513 } // namespace interpreter |
3471 } // namespace internal | 3514 } // namespace internal |
3472 } // namespace v8 | 3515 } // namespace v8 |
OLD | NEW |