| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
| 6 | 6 |
| 7 // Note on Mips implementation: | 7 // Note on Mips implementation: |
| 8 // | 8 // |
| 9 // The result_register() for mips is the 'v0' register, which is defined | 9 // The result_register() for mips is the 'v0' register, which is defined |
| 10 // by the ABI to contain function return values. However, the first | 10 // by the ABI to contain function return values. However, the first |
| (...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1242 __ CallStub(&stub); | 1242 __ CallStub(&stub); |
| 1243 } else { | 1243 } else { |
| 1244 __ Push(info); | 1244 __ Push(info); |
| 1245 __ CallRuntime( | 1245 __ CallRuntime( |
| 1246 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); | 1246 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); |
| 1247 } | 1247 } |
| 1248 context()->Plug(v0); | 1248 context()->Plug(v0); |
| 1249 } | 1249 } |
| 1250 | 1250 |
| 1251 | 1251 |
| 1252 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1252 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
| 1253 int offset, | 1253 FeedbackVectorICSlot slot) { |
| 1254 FeedbackVectorICSlot slot) { | 1254 DCHECK(NeedsHomeObject(initializer)); |
| 1255 if (NeedsHomeObject(initializer)) { | 1255 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1256 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1256 __ li(StoreDescriptor::NameRegister(), |
| 1257 __ li(StoreDescriptor::NameRegister(), | 1257 Operand(isolate()->factory()->home_object_symbol())); |
| 1258 Operand(isolate()->factory()->home_object_symbol())); | 1258 __ lw(StoreDescriptor::ValueRegister(), |
| 1259 __ lw(StoreDescriptor::ValueRegister(), | 1259 MemOperand(sp, offset * kPointerSize)); |
| 1260 MemOperand(sp, offset * kPointerSize)); | 1260 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1261 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 1261 CallStoreIC(); |
| 1262 CallStoreIC(); | |
| 1263 } | |
| 1264 } | 1262 } |
| 1265 | 1263 |
| 1266 | 1264 |
| 1265 void FullCodeGenerator::EmitSetHomeObjectAccumulator( |
| 1266 Expression* initializer, int offset, FeedbackVectorICSlot slot) { |
| 1267 DCHECK(NeedsHomeObject(initializer)); |
| 1268 __ Move(StoreDescriptor::ReceiverRegister(), v0); |
| 1269 __ li(StoreDescriptor::NameRegister(), |
| 1270 Operand(isolate()->factory()->home_object_symbol())); |
| 1271 __ lw(StoreDescriptor::ValueRegister(), |
| 1272 MemOperand(sp, offset * kPointerSize)); |
| 1273 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1274 CallStoreIC(); |
| 1275 } |
| 1276 |
| 1277 |
| 1267 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1278 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1268 TypeofMode typeof_mode, | 1279 TypeofMode typeof_mode, |
| 1269 Label* slow) { | 1280 Label* slow) { |
| 1270 Register current = cp; | 1281 Register current = cp; |
| 1271 Register next = a1; | 1282 Register next = a1; |
| 1272 Register temp = a2; | 1283 Register temp = a2; |
| 1273 | 1284 |
| 1274 Scope* s = scope(); | 1285 Scope* s = scope(); |
| 1275 while (s != NULL) { | 1286 while (s != NULL) { |
| 1276 if (s->num_heap_slots() > 0) { | 1287 if (s->num_heap_slots() > 0) { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 | 1534 |
| 1524 // After this, registers are used as follows: | 1535 // After this, registers are used as follows: |
| 1525 // v0: Newly allocated regexp. | 1536 // v0: Newly allocated regexp. |
| 1526 // t1: Materialized regexp. | 1537 // t1: Materialized regexp. |
| 1527 // a2: temp. | 1538 // a2: temp. |
| 1528 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize); | 1539 __ CopyFields(v0, t1, a2.bit(), size / kPointerSize); |
| 1529 context()->Plug(v0); | 1540 context()->Plug(v0); |
| 1530 } | 1541 } |
| 1531 | 1542 |
| 1532 | 1543 |
| 1533 void FullCodeGenerator::EmitAccessor(Expression* expression) { | 1544 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1545 Expression* expression = (property == NULL) ? NULL : property->value(); |
| 1534 if (expression == NULL) { | 1546 if (expression == NULL) { |
| 1535 __ LoadRoot(a1, Heap::kNullValueRootIndex); | 1547 __ LoadRoot(a1, Heap::kNullValueRootIndex); |
| 1536 __ push(a1); | 1548 __ push(a1); |
| 1537 } else { | 1549 } else { |
| 1538 VisitForStackValue(expression); | 1550 VisitForStackValue(expression); |
| 1551 if (NeedsHomeObject(expression)) { |
| 1552 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1553 property->kind() == ObjectLiteral::Property::SETTER); |
| 1554 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1555 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1556 } |
| 1539 } | 1557 } |
| 1540 } | 1558 } |
| 1541 | 1559 |
| 1542 | 1560 |
| 1543 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1561 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1544 Comment cmnt(masm_, "[ ObjectLiteral"); | 1562 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 1545 | 1563 |
| 1546 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1564 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1547 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1565 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1548 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); | 1566 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); |
| 1549 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1567 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
| 1550 __ li(a1, Operand(constant_properties)); | 1568 __ li(a1, Operand(constant_properties)); |
| 1551 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); | 1569 __ li(a0, Operand(Smi::FromInt(expr->ComputeFlags()))); |
| 1552 if (MustCreateObjectLiteralWithRuntime(expr)) { | 1570 if (MustCreateObjectLiteralWithRuntime(expr)) { |
| 1553 __ Push(a3, a2, a1, a0); | 1571 __ Push(a3, a2, a1, a0); |
| 1554 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1572 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
| 1555 } else { | 1573 } else { |
| 1556 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); | 1574 FastCloneShallowObjectStub stub(isolate(), expr->properties_count()); |
| 1557 __ CallStub(&stub); | 1575 __ CallStub(&stub); |
| 1558 } | 1576 } |
| 1559 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1577 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1560 | 1578 |
| 1561 // If result_saved is true the result is on top of the stack. If | 1579 // If result_saved is true the result is on top of the stack. If |
| 1562 // result_saved is false the result is in v0. | 1580 // result_saved is false the result is in v0. |
| 1563 bool result_saved = false; | 1581 bool result_saved = false; |
| 1564 | 1582 |
| 1565 AccessorTable accessor_table(zone()); | 1583 AccessorTable accessor_table(zone()); |
| 1566 int property_index = 0; | 1584 int property_index = 0; |
| 1567 // store_slot_index points to the vector IC slot for the next store IC used. | |
| 1568 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots | |
| 1569 // and must be updated if the number of store ICs emitted here changes. | |
| 1570 int store_slot_index = 0; | |
| 1571 for (; property_index < expr->properties()->length(); property_index++) { | 1585 for (; property_index < expr->properties()->length(); property_index++) { |
| 1572 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1586 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1573 if (property->is_computed_name()) break; | 1587 if (property->is_computed_name()) break; |
| 1574 if (property->IsCompileTimeValue()) continue; | 1588 if (property->IsCompileTimeValue()) continue; |
| 1575 | 1589 |
| 1576 Literal* key = property->key()->AsLiteral(); | 1590 Literal* key = property->key()->AsLiteral(); |
| 1577 Expression* value = property->value(); | 1591 Expression* value = property->value(); |
| 1578 if (!result_saved) { | 1592 if (!result_saved) { |
| 1579 __ push(v0); // Save result on stack. | 1593 __ push(v0); // Save result on stack. |
| 1580 result_saved = true; | 1594 result_saved = true; |
| 1581 } | 1595 } |
| 1582 switch (property->kind()) { | 1596 switch (property->kind()) { |
| 1583 case ObjectLiteral::Property::CONSTANT: | 1597 case ObjectLiteral::Property::CONSTANT: |
| 1584 UNREACHABLE(); | 1598 UNREACHABLE(); |
| 1585 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1599 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1586 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1600 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1587 // Fall through. | 1601 // Fall through. |
| 1588 case ObjectLiteral::Property::COMPUTED: | 1602 case ObjectLiteral::Property::COMPUTED: |
| 1589 // It is safe to use [[Put]] here because the boilerplate already | 1603 // It is safe to use [[Put]] here because the boilerplate already |
| 1590 // contains computed properties with an uninitialized value. | 1604 // contains computed properties with an uninitialized value. |
| 1591 if (key->value()->IsInternalizedString()) { | 1605 if (key->value()->IsInternalizedString()) { |
| 1592 if (property->emit_store()) { | 1606 if (property->emit_store()) { |
| 1593 VisitForAccumulatorValue(value); | 1607 VisitForAccumulatorValue(value); |
| 1594 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 1608 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 1595 DCHECK(StoreDescriptor::ValueRegister().is(a0)); | 1609 DCHECK(StoreDescriptor::ValueRegister().is(a0)); |
| 1596 __ li(StoreDescriptor::NameRegister(), Operand(key->value())); | 1610 __ li(StoreDescriptor::NameRegister(), Operand(key->value())); |
| 1597 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1611 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1598 if (FLAG_vector_stores) { | 1612 if (FLAG_vector_stores) { |
| 1599 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | 1613 EmitLoadStoreICSlot(property->GetSlot(0)); |
| 1600 CallStoreIC(); | 1614 CallStoreIC(); |
| 1601 } else { | 1615 } else { |
| 1602 CallStoreIC(key->LiteralFeedbackId()); | 1616 CallStoreIC(key->LiteralFeedbackId()); |
| 1603 } | 1617 } |
| 1604 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1618 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1605 | 1619 |
| 1606 if (NeedsHomeObject(value)) { | 1620 if (NeedsHomeObject(value)) { |
| 1607 __ Move(StoreDescriptor::ReceiverRegister(), v0); | 1621 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
| 1608 __ li(StoreDescriptor::NameRegister(), | |
| 1609 Operand(isolate()->factory()->home_object_symbol())); | |
| 1610 __ lw(StoreDescriptor::ValueRegister(), MemOperand(sp)); | |
| 1611 if (FLAG_vector_stores) { | |
| 1612 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | |
| 1613 } | |
| 1614 CallStoreIC(); | |
| 1615 } | 1622 } |
| 1616 } else { | 1623 } else { |
| 1617 VisitForEffect(value); | 1624 VisitForEffect(value); |
| 1618 } | 1625 } |
| 1619 break; | 1626 break; |
| 1620 } | 1627 } |
| 1621 // Duplicate receiver on stack. | 1628 // Duplicate receiver on stack. |
| 1622 __ lw(a0, MemOperand(sp)); | 1629 __ lw(a0, MemOperand(sp)); |
| 1623 __ push(a0); | 1630 __ push(a0); |
| 1624 VisitForStackValue(key); | 1631 VisitForStackValue(key); |
| 1625 VisitForStackValue(value); | 1632 VisitForStackValue(value); |
| 1626 if (property->emit_store()) { | 1633 if (property->emit_store()) { |
| 1627 EmitSetHomeObjectIfNeeded( | 1634 if (NeedsHomeObject(value)) { |
| 1628 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1635 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1636 } |
| 1629 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. | 1637 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. |
| 1630 __ push(a0); | 1638 __ push(a0); |
| 1631 __ CallRuntime(Runtime::kSetProperty, 4); | 1639 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1632 } else { | 1640 } else { |
| 1633 __ Drop(3); | 1641 __ Drop(3); |
| 1634 } | 1642 } |
| 1635 break; | 1643 break; |
| 1636 case ObjectLiteral::Property::PROTOTYPE: | 1644 case ObjectLiteral::Property::PROTOTYPE: |
| 1637 // Duplicate receiver on stack. | 1645 // Duplicate receiver on stack. |
| 1638 __ lw(a0, MemOperand(sp)); | 1646 __ lw(a0, MemOperand(sp)); |
| 1639 __ push(a0); | 1647 __ push(a0); |
| 1640 VisitForStackValue(value); | 1648 VisitForStackValue(value); |
| 1641 DCHECK(property->emit_store()); | 1649 DCHECK(property->emit_store()); |
| 1642 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1650 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1643 break; | 1651 break; |
| 1644 case ObjectLiteral::Property::GETTER: | 1652 case ObjectLiteral::Property::GETTER: |
| 1645 if (property->emit_store()) { | 1653 if (property->emit_store()) { |
| 1646 accessor_table.lookup(key)->second->getter = value; | 1654 accessor_table.lookup(key)->second->getter = property; |
| 1647 } | 1655 } |
| 1648 break; | 1656 break; |
| 1649 case ObjectLiteral::Property::SETTER: | 1657 case ObjectLiteral::Property::SETTER: |
| 1650 if (property->emit_store()) { | 1658 if (property->emit_store()) { |
| 1651 accessor_table.lookup(key)->second->setter = value; | 1659 accessor_table.lookup(key)->second->setter = property; |
| 1652 } | 1660 } |
| 1653 break; | 1661 break; |
| 1654 } | 1662 } |
| 1655 } | 1663 } |
| 1656 | 1664 |
| 1657 // Emit code to define accessors, using only a single call to the runtime for | 1665 // Emit code to define accessors, using only a single call to the runtime for |
| 1658 // each pair of corresponding getters and setters. | 1666 // each pair of corresponding getters and setters. |
| 1659 for (AccessorTable::Iterator it = accessor_table.begin(); | 1667 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1660 it != accessor_table.end(); | 1668 it != accessor_table.end(); |
| 1661 ++it) { | 1669 ++it) { |
| 1662 __ lw(a0, MemOperand(sp)); // Duplicate receiver. | 1670 __ lw(a0, MemOperand(sp)); // Duplicate receiver. |
| 1663 __ push(a0); | 1671 __ push(a0); |
| 1664 VisitForStackValue(it->first); | 1672 VisitForStackValue(it->first); |
| 1665 EmitAccessor(it->second->getter); | 1673 EmitAccessor(it->second->getter); |
| 1666 EmitSetHomeObjectIfNeeded( | |
| 1667 it->second->getter, 2, | |
| 1668 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
| 1669 EmitAccessor(it->second->setter); | 1674 EmitAccessor(it->second->setter); |
| 1670 EmitSetHomeObjectIfNeeded( | |
| 1671 it->second->setter, 3, | |
| 1672 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); | |
| 1673 __ li(a0, Operand(Smi::FromInt(NONE))); | 1675 __ li(a0, Operand(Smi::FromInt(NONE))); |
| 1674 __ push(a0); | 1676 __ push(a0); |
| 1675 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1677 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1676 } | 1678 } |
| 1677 | 1679 |
| 1678 // Object literals have two parts. The "static" part on the left contains no | 1680 // Object literals have two parts. The "static" part on the left contains no |
| 1679 // computed property names, and so we can compute its map ahead of time; see | 1681 // computed property names, and so we can compute its map ahead of time; see |
| 1680 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1682 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1681 // starts with the first computed property name, and continues with all | 1683 // starts with the first computed property name, and continues with all |
| 1682 // properties to its right. All the code from above initializes the static | 1684 // properties to its right. All the code from above initializes the static |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1697 __ push(a0); | 1699 __ push(a0); |
| 1698 | 1700 |
| 1699 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1701 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1700 DCHECK(!property->is_computed_name()); | 1702 DCHECK(!property->is_computed_name()); |
| 1701 VisitForStackValue(value); | 1703 VisitForStackValue(value); |
| 1702 DCHECK(property->emit_store()); | 1704 DCHECK(property->emit_store()); |
| 1703 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1705 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1704 } else { | 1706 } else { |
| 1705 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1707 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1706 VisitForStackValue(value); | 1708 VisitForStackValue(value); |
| 1707 EmitSetHomeObjectIfNeeded( | 1709 if (NeedsHomeObject(value)) { |
| 1708 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1710 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1711 } |
| 1709 | 1712 |
| 1710 switch (property->kind()) { | 1713 switch (property->kind()) { |
| 1711 case ObjectLiteral::Property::CONSTANT: | 1714 case ObjectLiteral::Property::CONSTANT: |
| 1712 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1715 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1713 case ObjectLiteral::Property::COMPUTED: | 1716 case ObjectLiteral::Property::COMPUTED: |
| 1714 if (property->emit_store()) { | 1717 if (property->emit_store()) { |
| 1715 __ li(a0, Operand(Smi::FromInt(NONE))); | 1718 __ li(a0, Operand(Smi::FromInt(NONE))); |
| 1716 __ push(a0); | 1719 __ push(a0); |
| 1717 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1720 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1718 } else { | 1721 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1744 __ lw(a0, MemOperand(sp)); | 1747 __ lw(a0, MemOperand(sp)); |
| 1745 __ push(a0); | 1748 __ push(a0); |
| 1746 __ CallRuntime(Runtime::kToFastProperties, 1); | 1749 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1747 } | 1750 } |
| 1748 | 1751 |
| 1749 if (result_saved) { | 1752 if (result_saved) { |
| 1750 context()->PlugTOS(); | 1753 context()->PlugTOS(); |
| 1751 } else { | 1754 } else { |
| 1752 context()->Plug(v0); | 1755 context()->Plug(v0); |
| 1753 } | 1756 } |
| 1754 | |
| 1755 // Verify that compilation exactly consumed the number of store ic slots that | |
| 1756 // the ObjectLiteral node had to offer. | |
| 1757 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); | |
| 1758 } | 1757 } |
| 1759 | 1758 |
| 1760 | 1759 |
| 1761 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1760 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1762 Comment cmnt(masm_, "[ ArrayLiteral"); | 1761 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1763 | 1762 |
| 1764 expr->BuildConstantElements(isolate()); | 1763 expr->BuildConstantElements(isolate()); |
| 1765 | 1764 |
| 1766 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1765 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1767 bool has_fast_elements = | 1766 bool has_fast_elements = |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2419 break; | 2418 break; |
| 2420 default: | 2419 default: |
| 2421 UNREACHABLE(); | 2420 UNREACHABLE(); |
| 2422 } | 2421 } |
| 2423 | 2422 |
| 2424 __ bind(&done); | 2423 __ bind(&done); |
| 2425 context()->Plug(v0); | 2424 context()->Plug(v0); |
| 2426 } | 2425 } |
| 2427 | 2426 |
| 2428 | 2427 |
| 2429 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit, | 2428 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
| 2430 int* used_store_slots) { | |
| 2431 // Constructor is in v0. | 2429 // Constructor is in v0. |
| 2432 DCHECK(lit != NULL); | 2430 DCHECK(lit != NULL); |
| 2433 __ push(v0); | 2431 __ push(v0); |
| 2434 | 2432 |
| 2435 // No access check is needed here since the constructor is created by the | 2433 // No access check is needed here since the constructor is created by the |
| 2436 // class literal. | 2434 // class literal. |
| 2437 Register scratch = a1; | 2435 Register scratch = a1; |
| 2438 __ lw(scratch, | 2436 __ lw(scratch, |
| 2439 FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset)); | 2437 FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset)); |
| 2440 __ push(scratch); | 2438 __ push(scratch); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2454 // The static prototype property is read only. We handle the non computed | 2452 // The static prototype property is read only. We handle the non computed |
| 2455 // property name case in the parser. Since this is the only case where we | 2453 // property name case in the parser. Since this is the only case where we |
| 2456 // need to check for an own read only property we special case this so we do | 2454 // need to check for an own read only property we special case this so we do |
| 2457 // not need to do this for every property. | 2455 // not need to do this for every property. |
| 2458 if (property->is_static() && property->is_computed_name()) { | 2456 if (property->is_static() && property->is_computed_name()) { |
| 2459 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); | 2457 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); |
| 2460 __ push(v0); | 2458 __ push(v0); |
| 2461 } | 2459 } |
| 2462 | 2460 |
| 2463 VisitForStackValue(value); | 2461 VisitForStackValue(value); |
| 2464 EmitSetHomeObjectIfNeeded(value, 2, | 2462 if (NeedsHomeObject(value)) { |
| 2465 lit->SlotForHomeObject(value, used_store_slots)); | 2463 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2464 } |
| 2466 | 2465 |
| 2467 switch (property->kind()) { | 2466 switch (property->kind()) { |
| 2468 case ObjectLiteral::Property::CONSTANT: | 2467 case ObjectLiteral::Property::CONSTANT: |
| 2469 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2468 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2470 case ObjectLiteral::Property::PROTOTYPE: | 2469 case ObjectLiteral::Property::PROTOTYPE: |
| 2471 UNREACHABLE(); | 2470 UNREACHABLE(); |
| 2472 case ObjectLiteral::Property::COMPUTED: | 2471 case ObjectLiteral::Property::COMPUTED: |
| 2473 __ CallRuntime(Runtime::kDefineClassMethod, 3); | 2472 __ CallRuntime(Runtime::kDefineClassMethod, 3); |
| 2474 break; | 2473 break; |
| 2475 | 2474 |
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3157 | 3156 |
| 3158 | 3157 |
| 3159 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 3158 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
| 3160 Comment cmnt(masm_, "[ CallNew"); | 3159 Comment cmnt(masm_, "[ CallNew"); |
| 3161 // According to ECMA-262, section 11.2.2, page 44, the function | 3160 // According to ECMA-262, section 11.2.2, page 44, the function |
| 3162 // expression in new calls must be evaluated before the | 3161 // expression in new calls must be evaluated before the |
| 3163 // arguments. | 3162 // arguments. |
| 3164 | 3163 |
| 3165 // Push constructor on the stack. If it's not a function it's used as | 3164 // Push constructor on the stack. If it's not a function it's used as |
| 3166 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is | 3165 // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is |
| 3167 // ignored. | 3166 // ignored.g |
| 3168 DCHECK(!expr->expression()->IsSuperPropertyReference()); | 3167 DCHECK(!expr->expression()->IsSuperPropertyReference()); |
| 3169 VisitForStackValue(expr->expression()); | 3168 VisitForStackValue(expr->expression()); |
| 3170 | 3169 |
| 3171 // Push the arguments ("left-to-right") on the stack. | 3170 // Push the arguments ("left-to-right") on the stack. |
| 3172 ZoneList<Expression*>* args = expr->arguments(); | 3171 ZoneList<Expression*>* args = expr->arguments(); |
| 3173 int arg_count = args->length(); | 3172 int arg_count = args->length(); |
| 3174 for (int i = 0; i < arg_count; i++) { | 3173 for (int i = 0; i < arg_count; i++) { |
| 3175 VisitForStackValue(args->at(i)); | 3174 VisitForStackValue(args->at(i)); |
| 3176 } | 3175 } |
| 3177 | 3176 |
| (...skipping 2154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5332 reinterpret_cast<uint32_t>( | 5331 reinterpret_cast<uint32_t>( |
| 5333 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5332 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 5334 return OSR_AFTER_STACK_CHECK; | 5333 return OSR_AFTER_STACK_CHECK; |
| 5335 } | 5334 } |
| 5336 | 5335 |
| 5337 | 5336 |
| 5338 } // namespace internal | 5337 } // namespace internal |
| 5339 } // namespace v8 | 5338 } // namespace v8 |
| 5340 | 5339 |
| 5341 #endif // V8_TARGET_ARCH_MIPS | 5340 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |