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 #if V8_TARGET_ARCH_S390 | 5 #if V8_TARGET_ARCH_S390 |
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-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 __ Check(ne, kDeclarationInWithContext); | 689 __ Check(ne, kDeclarationInWithContext); |
690 __ CompareRoot(r3, Heap::kCatchContextMapRootIndex); | 690 __ CompareRoot(r3, Heap::kCatchContextMapRootIndex); |
691 __ Check(ne, kDeclarationInCatchContext); | 691 __ Check(ne, kDeclarationInCatchContext); |
692 } | 692 } |
693 } | 693 } |
694 | 694 |
695 void FullCodeGenerator::VisitVariableDeclaration( | 695 void FullCodeGenerator::VisitVariableDeclaration( |
696 VariableDeclaration* declaration) { | 696 VariableDeclaration* declaration) { |
697 VariableProxy* proxy = declaration->proxy(); | 697 VariableProxy* proxy = declaration->proxy(); |
698 Variable* variable = proxy->var(); | 698 Variable* variable = proxy->var(); |
| 699 DCHECK(!variable->binding_needs_init()); |
699 switch (variable->location()) { | 700 switch (variable->location()) { |
700 case VariableLocation::UNALLOCATED: { | 701 case VariableLocation::UNALLOCATED: { |
701 DCHECK(!variable->binding_needs_init()); | |
702 globals_->Add(variable->name(), zone()); | 702 globals_->Add(variable->name(), zone()); |
703 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); | 703 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); |
704 DCHECK(!slot.IsInvalid()); | 704 DCHECK(!slot.IsInvalid()); |
705 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); | 705 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); |
706 globals_->Add(isolate()->factory()->undefined_value(), zone()); | 706 globals_->Add(isolate()->factory()->undefined_value(), zone()); |
707 break; | 707 break; |
708 } | 708 } |
709 case VariableLocation::PARAMETER: | 709 case VariableLocation::PARAMETER: |
710 case VariableLocation::LOCAL: | 710 case VariableLocation::LOCAL: |
711 if (variable->binding_needs_init()) { | |
712 Comment cmnt(masm_, "[ VariableDeclaration"); | |
713 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
714 __ StoreP(ip, StackOperand(variable)); | |
715 } | |
716 break; | |
717 | |
718 case VariableLocation::CONTEXT: | 711 case VariableLocation::CONTEXT: |
719 if (variable->binding_needs_init()) { | |
720 Comment cmnt(masm_, "[ VariableDeclaration"); | |
721 EmitDebugCheckDeclarationContext(variable); | |
722 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | |
723 __ StoreP(ip, ContextMemOperand(cp, variable->index())); | |
724 // No write barrier since the_hole_value is in old space. | |
725 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); | |
726 } | |
727 break; | 712 break; |
728 | 713 |
729 case VariableLocation::LOOKUP: | 714 case VariableLocation::LOOKUP: |
730 case VariableLocation::MODULE: | 715 case VariableLocation::MODULE: |
731 UNREACHABLE(); | 716 UNREACHABLE(); |
732 } | 717 } |
733 } | 718 } |
734 | 719 |
735 void FullCodeGenerator::VisitFunctionDeclaration( | 720 void FullCodeGenerator::VisitFunctionDeclaration( |
736 FunctionDeclaration* declaration) { | 721 FunctionDeclaration* declaration) { |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 context()->Plug(r2); | 1077 context()->Plug(r2); |
1093 break; | 1078 break; |
1094 } | 1079 } |
1095 | 1080 |
1096 case VariableLocation::PARAMETER: | 1081 case VariableLocation::PARAMETER: |
1097 case VariableLocation::LOCAL: | 1082 case VariableLocation::LOCAL: |
1098 case VariableLocation::CONTEXT: { | 1083 case VariableLocation::CONTEXT: { |
1099 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); | 1084 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); |
1100 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1085 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
1101 : "[ Stack variable"); | 1086 : "[ Stack variable"); |
1102 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) { | |
1103 // Throw a reference error when using an uninitialized let/const | |
1104 // binding in harmony mode. | |
1105 Label done; | |
1106 GetVar(r2, var); | |
1107 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); | |
1108 __ bne(&done); | |
1109 __ mov(r2, Operand(var->name())); | |
1110 __ push(r2); | |
1111 __ CallRuntime(Runtime::kThrowReferenceError); | |
1112 __ bind(&done); | |
1113 context()->Plug(r2); | |
1114 break; | |
1115 } | |
1116 context()->Plug(var); | 1087 context()->Plug(var); |
1117 break; | 1088 break; |
1118 } | 1089 } |
1119 | 1090 |
1120 case VariableLocation::LOOKUP: | 1091 case VariableLocation::LOOKUP: |
1121 case VariableLocation::MODULE: | 1092 case VariableLocation::MODULE: |
1122 UNREACHABLE(); | 1093 UNREACHABLE(); |
1123 } | 1094 } |
1124 } | 1095 } |
1125 | 1096 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 } else { | 1385 } else { |
1415 VisitForAccumulatorValue(expr->value()); | 1386 VisitForAccumulatorValue(expr->value()); |
1416 } | 1387 } |
1417 | 1388 |
1418 SetExpressionPosition(expr); | 1389 SetExpressionPosition(expr); |
1419 | 1390 |
1420 // Store the value. | 1391 // Store the value. |
1421 switch (assign_type) { | 1392 switch (assign_type) { |
1422 case VARIABLE: { | 1393 case VARIABLE: { |
1423 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1394 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
1424 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1395 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot()); |
1425 proxy->hole_check_mode()); | |
1426 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1396 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
1427 context()->Plug(r2); | 1397 context()->Plug(r2); |
1428 break; | 1398 break; |
1429 } | 1399 } |
1430 case NAMED_PROPERTY: | 1400 case NAMED_PROPERTY: |
1431 EmitNamedPropertyAssignment(expr); | 1401 EmitNamedPropertyAssignment(expr); |
1432 break; | 1402 break; |
1433 case KEYED_PROPERTY: | 1403 case KEYED_PROPERTY: |
1434 EmitKeyedPropertyAssignment(expr); | 1404 EmitKeyedPropertyAssignment(expr); |
1435 break; | 1405 break; |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 FeedbackVectorSlot slot) { | 1611 FeedbackVectorSlot slot) { |
1642 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 1612 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
1643 | 1613 |
1644 Property* prop = expr->AsProperty(); | 1614 Property* prop = expr->AsProperty(); |
1645 LhsKind assign_type = Property::GetAssignType(prop); | 1615 LhsKind assign_type = Property::GetAssignType(prop); |
1646 | 1616 |
1647 switch (assign_type) { | 1617 switch (assign_type) { |
1648 case VARIABLE: { | 1618 case VARIABLE: { |
1649 VariableProxy* proxy = expr->AsVariableProxy(); | 1619 VariableProxy* proxy = expr->AsVariableProxy(); |
1650 EffectContext context(this); | 1620 EffectContext context(this); |
1651 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot, | 1621 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot); |
1652 proxy->hole_check_mode()); | |
1653 break; | 1622 break; |
1654 } | 1623 } |
1655 case NAMED_PROPERTY: { | 1624 case NAMED_PROPERTY: { |
1656 PushOperand(r2); // Preserve value. | 1625 PushOperand(r2); // Preserve value. |
1657 VisitForAccumulatorValue(prop->obj()); | 1626 VisitForAccumulatorValue(prop->obj()); |
1658 __ Move(StoreDescriptor::ReceiverRegister(), r2); | 1627 __ Move(StoreDescriptor::ReceiverRegister(), r2); |
1659 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1628 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
1660 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1629 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
1661 break; | 1630 break; |
1662 } | 1631 } |
(...skipping 21 matching lines...) Expand all Loading... |
1684 if (var->IsContextSlot()) { | 1653 if (var->IsContextSlot()) { |
1685 // RecordWrite may destroy all its register arguments. | 1654 // RecordWrite may destroy all its register arguments. |
1686 __ LoadRR(r5, result_register()); | 1655 __ LoadRR(r5, result_register()); |
1687 int offset = Context::SlotOffset(var->index()); | 1656 int offset = Context::SlotOffset(var->index()); |
1688 __ RecordWriteContextSlot(r3, offset, r5, r4, kLRHasBeenSaved, | 1657 __ RecordWriteContextSlot(r3, offset, r5, r4, kLRHasBeenSaved, |
1689 kDontSaveFPRegs); | 1658 kDontSaveFPRegs); |
1690 } | 1659 } |
1691 } | 1660 } |
1692 | 1661 |
1693 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 1662 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
1694 FeedbackVectorSlot slot, | 1663 FeedbackVectorSlot slot) { |
1695 HoleCheckMode hole_check_mode) { | 1664 DCHECK(!var->binding_needs_init()); |
1696 if (var->IsUnallocated()) { | 1665 if (var->IsUnallocated()) { |
1697 // Global var, const, or let. | 1666 // Global var, const, or let. |
1698 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); | 1667 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); |
1699 CallStoreIC(slot, var->name()); | 1668 CallStoreIC(slot, var->name()); |
1700 | 1669 |
1701 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { | 1670 } else if (var->mode() == CONST && op != Token::INIT) { |
1702 // Non-initializing assignment to let variable needs a write barrier. | 1671 if (var->throw_on_const_assignment(language_mode())) { |
1703 DCHECK(!var->IsLookupSlot()); | |
1704 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
1705 MemOperand location = VarOperand(var, r3); | |
1706 // Perform an initialization check for lexically declared variables. | |
1707 if (hole_check_mode == HoleCheckMode::kRequired) { | |
1708 Label assign; | |
1709 __ LoadP(r5, location); | |
1710 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | |
1711 __ bne(&assign); | |
1712 __ mov(r5, Operand(var->name())); | |
1713 __ push(r5); | |
1714 __ CallRuntime(Runtime::kThrowReferenceError); | |
1715 __ bind(&assign); | |
1716 } | |
1717 if (var->mode() != CONST) { | |
1718 EmitStoreToStackLocalOrContextSlot(var, location); | |
1719 } else if (var->throw_on_const_assignment(language_mode())) { | |
1720 __ CallRuntime(Runtime::kThrowConstAssignError); | 1672 __ CallRuntime(Runtime::kThrowConstAssignError); |
1721 } | 1673 } |
1722 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { | |
1723 // Initializing assignment to const {this} needs a write barrier. | |
1724 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | |
1725 Label uninitialized_this; | |
1726 MemOperand location = VarOperand(var, r3); | |
1727 __ LoadP(r5, location); | |
1728 __ CompareRoot(r5, Heap::kTheHoleValueRootIndex); | |
1729 __ beq(&uninitialized_this); | |
1730 __ mov(r3, Operand(var->name())); | |
1731 __ push(r3); | |
1732 __ CallRuntime(Runtime::kThrowReferenceError); | |
1733 __ bind(&uninitialized_this); | |
1734 EmitStoreToStackLocalOrContextSlot(var, location); | |
1735 } else { | 1674 } else { |
1736 DCHECK(var->mode() != CONST || op == Token::INIT); | 1675 DCHECK(!var->is_this()); |
1737 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); | 1676 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); |
1738 DCHECK(!var->IsLookupSlot()); | 1677 DCHECK(!var->IsLookupSlot()); |
1739 // Assignment to var or initializing assignment to let/const in harmony | |
1740 // mode. | |
1741 MemOperand location = VarOperand(var, r3); | 1678 MemOperand location = VarOperand(var, r3); |
1742 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) { | |
1743 // Check for an uninitialized let binding. | |
1744 __ LoadP(r4, location); | |
1745 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | |
1746 __ Check(eq, kLetBindingReInitialization); | |
1747 } | |
1748 EmitStoreToStackLocalOrContextSlot(var, location); | 1679 EmitStoreToStackLocalOrContextSlot(var, location); |
1749 } | 1680 } |
1750 } | 1681 } |
1751 | 1682 |
1752 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 1683 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
1753 // Assignment to a property, using a named store IC. | 1684 // Assignment to a property, using a named store IC. |
1754 Property* prop = expr->target()->AsProperty(); | 1685 Property* prop = expr->target()->AsProperty(); |
1755 DCHECK(prop != NULL); | 1686 DCHECK(prop != NULL); |
1756 DCHECK(prop->key()->IsLiteral()); | 1687 DCHECK(prop->key()->IsLiteral()); |
1757 | 1688 |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2450 patch_site.EmitPatchInfo(); | 2381 patch_site.EmitPatchInfo(); |
2451 __ bind(&done); | 2382 __ bind(&done); |
2452 | 2383 |
2453 // Store the value returned in r2. | 2384 // Store the value returned in r2. |
2454 switch (assign_type) { | 2385 switch (assign_type) { |
2455 case VARIABLE: { | 2386 case VARIABLE: { |
2456 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2387 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2457 if (expr->is_postfix()) { | 2388 if (expr->is_postfix()) { |
2458 { | 2389 { |
2459 EffectContext context(this); | 2390 EffectContext context(this); |
2460 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), | 2391 EmitVariableAssignment(proxy->var(), Token::ASSIGN, |
2461 proxy->hole_check_mode()); | 2392 expr->CountSlot()); |
2462 PrepareForBailoutForId(expr->AssignmentId(), | 2393 PrepareForBailoutForId(expr->AssignmentId(), |
2463 BailoutState::TOS_REGISTER); | 2394 BailoutState::TOS_REGISTER); |
2464 context.Plug(r2); | 2395 context.Plug(r2); |
2465 } | 2396 } |
2466 // For all contexts except EffectConstant We have the result on | 2397 // For all contexts except EffectConstant We have the result on |
2467 // top of the stack. | 2398 // top of the stack. |
2468 if (!context()->IsEffect()) { | 2399 if (!context()->IsEffect()) { |
2469 context()->PlugTOS(); | 2400 context()->PlugTOS(); |
2470 } | 2401 } |
2471 } else { | 2402 } else { |
2472 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), | 2403 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot()); |
2473 proxy->hole_check_mode()); | |
2474 PrepareForBailoutForId(expr->AssignmentId(), | 2404 PrepareForBailoutForId(expr->AssignmentId(), |
2475 BailoutState::TOS_REGISTER); | 2405 BailoutState::TOS_REGISTER); |
2476 context()->Plug(r2); | 2406 context()->Plug(r2); |
2477 } | 2407 } |
2478 break; | 2408 break; |
2479 } | 2409 } |
2480 case NAMED_PROPERTY: { | 2410 case NAMED_PROPERTY: { |
2481 PopOperand(StoreDescriptor::ReceiverRegister()); | 2411 PopOperand(StoreDescriptor::ReceiverRegister()); |
2482 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); | 2412 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); |
2483 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2413 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2799 DCHECK(kOSRBranchInstruction == br_instr); | 2729 DCHECK(kOSRBranchInstruction == br_instr); |
2800 | 2730 |
2801 DCHECK(interrupt_address == | 2731 DCHECK(interrupt_address == |
2802 isolate->builtins()->OnStackReplacement()->entry()); | 2732 isolate->builtins()->OnStackReplacement()->entry()); |
2803 return ON_STACK_REPLACEMENT; | 2733 return ON_STACK_REPLACEMENT; |
2804 } | 2734 } |
2805 | 2735 |
2806 } // namespace internal | 2736 } // namespace internal |
2807 } // namespace v8 | 2737 } // namespace v8 |
2808 #endif // V8_TARGET_ARCH_S390 | 2738 #endif // V8_TARGET_ARCH_S390 |
OLD | NEW |