| 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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| (...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1176 __ push(Immediate(info)); | 1176 __ push(Immediate(info)); |
| 1177 __ push(Immediate(pretenure | 1177 __ push(Immediate(pretenure |
| 1178 ? isolate()->factory()->true_value() | 1178 ? isolate()->factory()->true_value() |
| 1179 : isolate()->factory()->false_value())); | 1179 : isolate()->factory()->false_value())); |
| 1180 __ CallRuntime(Runtime::kNewClosure, 3); | 1180 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1181 } | 1181 } |
| 1182 context()->Plug(eax); | 1182 context()->Plug(eax); |
| 1183 } | 1183 } |
| 1184 | 1184 |
| 1185 | 1185 |
| 1186 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1186 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
| 1187 int offset, | 1187 FeedbackVectorICSlot slot) { |
| 1188 FeedbackVectorICSlot slot) { | 1188 DCHECK(NeedsHomeObject(initializer)); |
| 1189 if (NeedsHomeObject(initializer)) { | 1189 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1190 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1190 __ mov(StoreDescriptor::NameRegister(), |
| 1191 __ mov(StoreDescriptor::NameRegister(), | 1191 Immediate(isolate()->factory()->home_object_symbol())); |
| 1192 Immediate(isolate()->factory()->home_object_symbol())); | 1192 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); |
| 1193 __ mov(StoreDescriptor::ValueRegister(), | 1193 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1194 Operand(esp, offset * kPointerSize)); | 1194 CallStoreIC(); |
| 1195 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | |
| 1196 CallStoreIC(); | |
| 1197 } | |
| 1198 } | 1195 } |
| 1199 | 1196 |
| 1200 | 1197 |
| 1198 void FullCodeGenerator::EmitSetHomeObjectAccumulator( |
| 1199 Expression* initializer, int offset, FeedbackVectorICSlot slot) { |
| 1200 DCHECK(NeedsHomeObject(initializer)); |
| 1201 __ mov(StoreDescriptor::ReceiverRegister(), eax); |
| 1202 __ mov(StoreDescriptor::NameRegister(), |
| 1203 Immediate(isolate()->factory()->home_object_symbol())); |
| 1204 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); |
| 1205 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1206 CallStoreIC(); |
| 1207 } |
| 1208 |
| 1209 |
| 1201 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1210 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1202 TypeofMode typeof_mode, | 1211 TypeofMode typeof_mode, |
| 1203 Label* slow) { | 1212 Label* slow) { |
| 1204 Register context = esi; | 1213 Register context = esi; |
| 1205 Register temp = edx; | 1214 Register temp = edx; |
| 1206 | 1215 |
| 1207 Scope* s = scope(); | 1216 Scope* s = scope(); |
| 1208 while (s != NULL) { | 1217 while (s != NULL) { |
| 1209 if (s->num_heap_slots() > 0) { | 1218 if (s->num_heap_slots() > 0) { |
| 1210 if (s->calls_sloppy_eval()) { | 1219 if (s->calls_sloppy_eval()) { |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 __ mov(FieldOperand(eax, i + kPointerSize), ecx); | 1468 __ mov(FieldOperand(eax, i + kPointerSize), ecx); |
| 1460 } | 1469 } |
| 1461 if ((size % (2 * kPointerSize)) != 0) { | 1470 if ((size % (2 * kPointerSize)) != 0) { |
| 1462 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); | 1471 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); |
| 1463 __ mov(FieldOperand(eax, size - kPointerSize), edx); | 1472 __ mov(FieldOperand(eax, size - kPointerSize), edx); |
| 1464 } | 1473 } |
| 1465 context()->Plug(eax); | 1474 context()->Plug(eax); |
| 1466 } | 1475 } |
| 1467 | 1476 |
| 1468 | 1477 |
| 1469 void FullCodeGenerator::EmitAccessor(Expression* expression) { | 1478 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1479 Expression* expression = (property == NULL) ? NULL : property->value(); |
| 1470 if (expression == NULL) { | 1480 if (expression == NULL) { |
| 1471 __ push(Immediate(isolate()->factory()->null_value())); | 1481 __ push(Immediate(isolate()->factory()->null_value())); |
| 1472 } else { | 1482 } else { |
| 1473 VisitForStackValue(expression); | 1483 VisitForStackValue(expression); |
| 1484 if (NeedsHomeObject(expression)) { |
| 1485 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1486 property->kind() == ObjectLiteral::Property::SETTER); |
| 1487 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1488 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1489 } |
| 1474 } | 1490 } |
| 1475 } | 1491 } |
| 1476 | 1492 |
| 1477 | 1493 |
| 1478 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1494 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1479 Comment cmnt(masm_, "[ ObjectLiteral"); | 1495 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 1480 | 1496 |
| 1481 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1497 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1482 int flags = expr->ComputeFlags(); | 1498 int flags = expr->ComputeFlags(); |
| 1483 // If any of the keys would store to the elements array, then we shouldn't | 1499 // If any of the keys would store to the elements array, then we shouldn't |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1499 __ CallStub(&stub); | 1515 __ CallStub(&stub); |
| 1500 } | 1516 } |
| 1501 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1517 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1502 | 1518 |
| 1503 // If result_saved is true the result is on top of the stack. If | 1519 // If result_saved is true the result is on top of the stack. If |
| 1504 // result_saved is false the result is in eax. | 1520 // result_saved is false the result is in eax. |
| 1505 bool result_saved = false; | 1521 bool result_saved = false; |
| 1506 | 1522 |
| 1507 AccessorTable accessor_table(zone()); | 1523 AccessorTable accessor_table(zone()); |
| 1508 int property_index = 0; | 1524 int property_index = 0; |
| 1509 // store_slot_index points to the vector IC slot for the next store IC used. | |
| 1510 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots | |
| 1511 // and must be updated if the number of store ICs emitted here changes. | |
| 1512 int store_slot_index = 0; | |
| 1513 for (; property_index < expr->properties()->length(); property_index++) { | 1525 for (; property_index < expr->properties()->length(); property_index++) { |
| 1514 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1526 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1515 if (property->is_computed_name()) break; | 1527 if (property->is_computed_name()) break; |
| 1516 if (property->IsCompileTimeValue()) continue; | 1528 if (property->IsCompileTimeValue()) continue; |
| 1517 | 1529 |
| 1518 Literal* key = property->key()->AsLiteral(); | 1530 Literal* key = property->key()->AsLiteral(); |
| 1519 Expression* value = property->value(); | 1531 Expression* value = property->value(); |
| 1520 if (!result_saved) { | 1532 if (!result_saved) { |
| 1521 __ push(eax); // Save result on the stack | 1533 __ push(eax); // Save result on the stack |
| 1522 result_saved = true; | 1534 result_saved = true; |
| 1523 } | 1535 } |
| 1524 switch (property->kind()) { | 1536 switch (property->kind()) { |
| 1525 case ObjectLiteral::Property::CONSTANT: | 1537 case ObjectLiteral::Property::CONSTANT: |
| 1526 UNREACHABLE(); | 1538 UNREACHABLE(); |
| 1527 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1539 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1528 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1540 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1529 // Fall through. | 1541 // Fall through. |
| 1530 case ObjectLiteral::Property::COMPUTED: | 1542 case ObjectLiteral::Property::COMPUTED: |
| 1531 // It is safe to use [[Put]] here because the boilerplate already | 1543 // It is safe to use [[Put]] here because the boilerplate already |
| 1532 // contains computed properties with an uninitialized value. | 1544 // contains computed properties with an uninitialized value. |
| 1533 if (key->value()->IsInternalizedString()) { | 1545 if (key->value()->IsInternalizedString()) { |
| 1534 if (property->emit_store()) { | 1546 if (property->emit_store()) { |
| 1535 VisitForAccumulatorValue(value); | 1547 VisitForAccumulatorValue(value); |
| 1536 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1548 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 1537 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); | 1549 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); |
| 1538 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1550 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1539 if (FLAG_vector_stores) { | 1551 if (FLAG_vector_stores) { |
| 1540 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | 1552 EmitLoadStoreICSlot(property->GetSlot(0)); |
| 1541 CallStoreIC(); | 1553 CallStoreIC(); |
| 1542 } else { | 1554 } else { |
| 1543 CallStoreIC(key->LiteralFeedbackId()); | 1555 CallStoreIC(key->LiteralFeedbackId()); |
| 1544 } | 1556 } |
| 1545 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1557 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1546 | |
| 1547 if (NeedsHomeObject(value)) { | 1558 if (NeedsHomeObject(value)) { |
| 1548 __ mov(StoreDescriptor::ReceiverRegister(), eax); | 1559 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
| 1549 __ mov(StoreDescriptor::NameRegister(), | |
| 1550 Immediate(isolate()->factory()->home_object_symbol())); | |
| 1551 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0)); | |
| 1552 if (FLAG_vector_stores) { | |
| 1553 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | |
| 1554 } | |
| 1555 CallStoreIC(); | |
| 1556 } | 1560 } |
| 1557 } else { | 1561 } else { |
| 1558 VisitForEffect(value); | 1562 VisitForEffect(value); |
| 1559 } | 1563 } |
| 1560 break; | 1564 break; |
| 1561 } | 1565 } |
| 1562 __ push(Operand(esp, 0)); // Duplicate receiver. | 1566 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1563 VisitForStackValue(key); | 1567 VisitForStackValue(key); |
| 1564 VisitForStackValue(value); | 1568 VisitForStackValue(value); |
| 1565 if (property->emit_store()) { | 1569 if (property->emit_store()) { |
| 1566 EmitSetHomeObjectIfNeeded( | 1570 if (NeedsHomeObject(value)) { |
| 1567 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1571 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1572 } |
| 1568 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode | 1573 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode |
| 1569 __ CallRuntime(Runtime::kSetProperty, 4); | 1574 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1570 } else { | 1575 } else { |
| 1571 __ Drop(3); | 1576 __ Drop(3); |
| 1572 } | 1577 } |
| 1573 break; | 1578 break; |
| 1574 case ObjectLiteral::Property::PROTOTYPE: | 1579 case ObjectLiteral::Property::PROTOTYPE: |
| 1575 __ push(Operand(esp, 0)); // Duplicate receiver. | 1580 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1576 VisitForStackValue(value); | 1581 VisitForStackValue(value); |
| 1577 DCHECK(property->emit_store()); | 1582 DCHECK(property->emit_store()); |
| 1578 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1583 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1579 break; | 1584 break; |
| 1580 case ObjectLiteral::Property::GETTER: | 1585 case ObjectLiteral::Property::GETTER: |
| 1581 if (property->emit_store()) { | 1586 if (property->emit_store()) { |
| 1582 accessor_table.lookup(key)->second->getter = value; | 1587 accessor_table.lookup(key)->second->getter = property; |
| 1583 } | 1588 } |
| 1584 break; | 1589 break; |
| 1585 case ObjectLiteral::Property::SETTER: | 1590 case ObjectLiteral::Property::SETTER: |
| 1586 if (property->emit_store()) { | 1591 if (property->emit_store()) { |
| 1587 accessor_table.lookup(key)->second->setter = value; | 1592 accessor_table.lookup(key)->second->setter = property; |
| 1588 } | 1593 } |
| 1589 break; | 1594 break; |
| 1590 } | 1595 } |
| 1591 } | 1596 } |
| 1592 | 1597 |
| 1593 // Emit code to define accessors, using only a single call to the runtime for | 1598 // Emit code to define accessors, using only a single call to the runtime for |
| 1594 // each pair of corresponding getters and setters. | 1599 // each pair of corresponding getters and setters. |
| 1595 for (AccessorTable::Iterator it = accessor_table.begin(); | 1600 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1596 it != accessor_table.end(); | 1601 it != accessor_table.end(); |
| 1597 ++it) { | 1602 ++it) { |
| 1598 __ push(Operand(esp, 0)); // Duplicate receiver. | 1603 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1599 VisitForStackValue(it->first); | 1604 VisitForStackValue(it->first); |
| 1605 |
| 1600 EmitAccessor(it->second->getter); | 1606 EmitAccessor(it->second->getter); |
| 1601 EmitSetHomeObjectIfNeeded( | |
| 1602 it->second->getter, 2, | |
| 1603 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
| 1604 | |
| 1605 EmitAccessor(it->second->setter); | 1607 EmitAccessor(it->second->setter); |
| 1606 EmitSetHomeObjectIfNeeded( | |
| 1607 it->second->setter, 3, | |
| 1608 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); | |
| 1609 | 1608 |
| 1610 __ push(Immediate(Smi::FromInt(NONE))); | 1609 __ push(Immediate(Smi::FromInt(NONE))); |
| 1611 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1610 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1612 } | 1611 } |
| 1613 | 1612 |
| 1614 // Object literals have two parts. The "static" part on the left contains no | 1613 // Object literals have two parts. The "static" part on the left contains no |
| 1615 // computed property names, and so we can compute its map ahead of time; see | 1614 // computed property names, and so we can compute its map ahead of time; see |
| 1616 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1615 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1617 // starts with the first computed property name, and continues with all | 1616 // starts with the first computed property name, and continues with all |
| 1618 // properties to its right. All the code from above initializes the static | 1617 // properties to its right. All the code from above initializes the static |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1632 __ push(Operand(esp, 0)); // Duplicate receiver. | 1631 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1633 | 1632 |
| 1634 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1633 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1635 DCHECK(!property->is_computed_name()); | 1634 DCHECK(!property->is_computed_name()); |
| 1636 VisitForStackValue(value); | 1635 VisitForStackValue(value); |
| 1637 DCHECK(property->emit_store()); | 1636 DCHECK(property->emit_store()); |
| 1638 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1637 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1639 } else { | 1638 } else { |
| 1640 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1639 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1641 VisitForStackValue(value); | 1640 VisitForStackValue(value); |
| 1642 EmitSetHomeObjectIfNeeded( | 1641 if (NeedsHomeObject(value)) { |
| 1643 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1642 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1643 } |
| 1644 | 1644 |
| 1645 switch (property->kind()) { | 1645 switch (property->kind()) { |
| 1646 case ObjectLiteral::Property::CONSTANT: | 1646 case ObjectLiteral::Property::CONSTANT: |
| 1647 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1647 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1648 case ObjectLiteral::Property::COMPUTED: | 1648 case ObjectLiteral::Property::COMPUTED: |
| 1649 if (property->emit_store()) { | 1649 if (property->emit_store()) { |
| 1650 __ push(Immediate(Smi::FromInt(NONE))); | 1650 __ push(Immediate(Smi::FromInt(NONE))); |
| 1651 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1651 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1652 } else { | 1652 } else { |
| 1653 __ Drop(3); | 1653 __ Drop(3); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1675 DCHECK(result_saved); | 1675 DCHECK(result_saved); |
| 1676 __ push(Operand(esp, 0)); | 1676 __ push(Operand(esp, 0)); |
| 1677 __ CallRuntime(Runtime::kToFastProperties, 1); | 1677 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1678 } | 1678 } |
| 1679 | 1679 |
| 1680 if (result_saved) { | 1680 if (result_saved) { |
| 1681 context()->PlugTOS(); | 1681 context()->PlugTOS(); |
| 1682 } else { | 1682 } else { |
| 1683 context()->Plug(eax); | 1683 context()->Plug(eax); |
| 1684 } | 1684 } |
| 1685 | |
| 1686 // Verify that compilation exactly consumed the number of store ic slots that | |
| 1687 // the ObjectLiteral node had to offer. | |
| 1688 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); | |
| 1689 } | 1685 } |
| 1690 | 1686 |
| 1691 | 1687 |
| 1692 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1688 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1693 Comment cmnt(masm_, "[ ArrayLiteral"); | 1689 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1694 | 1690 |
| 1695 expr->BuildConstantElements(isolate()); | 1691 expr->BuildConstantElements(isolate()); |
| 1696 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1692 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1697 bool has_constant_fast_elements = | 1693 bool has_constant_fast_elements = |
| 1698 IsFastObjectElementsKind(expr->constant_elements_kind()); | 1694 IsFastObjectElementsKind(expr->constant_elements_kind()); |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2349 break; | 2345 break; |
| 2350 default: | 2346 default: |
| 2351 UNREACHABLE(); | 2347 UNREACHABLE(); |
| 2352 } | 2348 } |
| 2353 | 2349 |
| 2354 __ bind(&done); | 2350 __ bind(&done); |
| 2355 context()->Plug(eax); | 2351 context()->Plug(eax); |
| 2356 } | 2352 } |
| 2357 | 2353 |
| 2358 | 2354 |
| 2359 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit, | 2355 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
| 2360 int* used_store_slots) { | |
| 2361 // Constructor is in eax. | 2356 // Constructor is in eax. |
| 2362 DCHECK(lit != NULL); | 2357 DCHECK(lit != NULL); |
| 2363 __ push(eax); | 2358 __ push(eax); |
| 2364 | 2359 |
| 2365 // No access check is needed here since the constructor is created by the | 2360 // No access check is needed here since the constructor is created by the |
| 2366 // class literal. | 2361 // class literal. |
| 2367 Register scratch = ebx; | 2362 Register scratch = ebx; |
| 2368 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset)); | 2363 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset)); |
| 2369 __ Push(scratch); | 2364 __ Push(scratch); |
| 2370 | 2365 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2382 // The static prototype property is read only. We handle the non computed | 2377 // The static prototype property is read only. We handle the non computed |
| 2383 // property name case in the parser. Since this is the only case where we | 2378 // property name case in the parser. Since this is the only case where we |
| 2384 // need to check for an own read only property we special case this so we do | 2379 // need to check for an own read only property we special case this so we do |
| 2385 // not need to do this for every property. | 2380 // not need to do this for every property. |
| 2386 if (property->is_static() && property->is_computed_name()) { | 2381 if (property->is_static() && property->is_computed_name()) { |
| 2387 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); | 2382 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); |
| 2388 __ push(eax); | 2383 __ push(eax); |
| 2389 } | 2384 } |
| 2390 | 2385 |
| 2391 VisitForStackValue(value); | 2386 VisitForStackValue(value); |
| 2392 EmitSetHomeObjectIfNeeded(value, 2, | 2387 if (NeedsHomeObject(value)) { |
| 2393 lit->SlotForHomeObject(value, used_store_slots)); | 2388 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2389 } |
| 2394 | 2390 |
| 2395 switch (property->kind()) { | 2391 switch (property->kind()) { |
| 2396 case ObjectLiteral::Property::CONSTANT: | 2392 case ObjectLiteral::Property::CONSTANT: |
| 2397 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2393 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2398 case ObjectLiteral::Property::PROTOTYPE: | 2394 case ObjectLiteral::Property::PROTOTYPE: |
| 2399 UNREACHABLE(); | 2395 UNREACHABLE(); |
| 2400 case ObjectLiteral::Property::COMPUTED: | 2396 case ObjectLiteral::Property::COMPUTED: |
| 2401 __ CallRuntime(Runtime::kDefineClassMethod, 3); | 2397 __ CallRuntime(Runtime::kDefineClassMethod, 3); |
| 2402 break; | 2398 break; |
| 2403 | 2399 |
| (...skipping 2824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5228 Assembler::target_address_at(call_target_address, | 5224 Assembler::target_address_at(call_target_address, |
| 5229 unoptimized_code)); | 5225 unoptimized_code)); |
| 5230 return OSR_AFTER_STACK_CHECK; | 5226 return OSR_AFTER_STACK_CHECK; |
| 5231 } | 5227 } |
| 5232 | 5228 |
| 5233 | 5229 |
| 5234 } // namespace internal | 5230 } // namespace internal |
| 5235 } // namespace v8 | 5231 } // namespace v8 |
| 5236 | 5232 |
| 5237 #endif // V8_TARGET_ARCH_IA32 | 5233 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |