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 |