| 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_X87 | 5 #if V8_TARGET_ARCH_X87 |
| 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 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1166 __ CallStub(&stub); | 1166 __ CallStub(&stub); |
| 1167 } else { | 1167 } else { |
| 1168 __ push(Immediate(info)); | 1168 __ push(Immediate(info)); |
| 1169 __ CallRuntime( | 1169 __ CallRuntime( |
| 1170 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); | 1170 pretenure ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure, 1); |
| 1171 } | 1171 } |
| 1172 context()->Plug(eax); | 1172 context()->Plug(eax); |
| 1173 } | 1173 } |
| 1174 | 1174 |
| 1175 | 1175 |
| 1176 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1176 void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset, |
| 1177 int offset, | 1177 FeedbackVectorICSlot slot) { |
| 1178 FeedbackVectorICSlot slot) { | 1178 DCHECK(NeedsHomeObject(initializer)); |
| 1179 if (NeedsHomeObject(initializer)) { | 1179 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1180 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1180 __ mov(StoreDescriptor::NameRegister(), |
| 1181 __ mov(StoreDescriptor::NameRegister(), | 1181 Immediate(isolate()->factory()->home_object_symbol())); |
| 1182 Immediate(isolate()->factory()->home_object_symbol())); | 1182 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); |
| 1183 __ mov(StoreDescriptor::ValueRegister(), | 1183 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1184 Operand(esp, offset * kPointerSize)); | 1184 CallStoreIC(); |
| 1185 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | |
| 1186 CallStoreIC(); | |
| 1187 } | |
| 1188 } | 1185 } |
| 1189 | 1186 |
| 1190 | 1187 |
| 1188 void FullCodeGenerator::EmitSetHomeObjectAccumulator( |
| 1189 Expression* initializer, int offset, FeedbackVectorICSlot slot) { |
| 1190 DCHECK(NeedsHomeObject(initializer)); |
| 1191 __ mov(StoreDescriptor::ReceiverRegister(), eax); |
| 1192 __ mov(StoreDescriptor::NameRegister(), |
| 1193 Immediate(isolate()->factory()->home_object_symbol())); |
| 1194 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize)); |
| 1195 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1196 CallStoreIC(); |
| 1197 } |
| 1198 |
| 1199 |
| 1191 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1200 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1192 TypeofMode typeof_mode, | 1201 TypeofMode typeof_mode, |
| 1193 Label* slow) { | 1202 Label* slow) { |
| 1194 Register context = esi; | 1203 Register context = esi; |
| 1195 Register temp = edx; | 1204 Register temp = edx; |
| 1196 | 1205 |
| 1197 Scope* s = scope(); | 1206 Scope* s = scope(); |
| 1198 while (s != NULL) { | 1207 while (s != NULL) { |
| 1199 if (s->num_heap_slots() > 0) { | 1208 if (s->num_heap_slots() > 0) { |
| 1200 if (s->calls_sloppy_eval()) { | 1209 if (s->calls_sloppy_eval()) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 context()->Plug(eax); | 1357 context()->Plug(eax); |
| 1349 break; | 1358 break; |
| 1350 } | 1359 } |
| 1351 | 1360 |
| 1352 case VariableLocation::PARAMETER: | 1361 case VariableLocation::PARAMETER: |
| 1353 case VariableLocation::LOCAL: | 1362 case VariableLocation::LOCAL: |
| 1354 case VariableLocation::CONTEXT: { | 1363 case VariableLocation::CONTEXT: { |
| 1355 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); | 1364 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); |
| 1356 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1365 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
| 1357 : "[ Stack variable"); | 1366 : "[ Stack variable"); |
| 1367 |
| 1358 if (NeedsHoleCheckForLoad(proxy)) { | 1368 if (NeedsHoleCheckForLoad(proxy)) { |
| 1359 // Let and const need a read barrier. | 1369 // Let and const need a read barrier. |
| 1360 Label done; | 1370 Label done; |
| 1361 GetVar(eax, var); | 1371 GetVar(eax, var); |
| 1362 __ cmp(eax, isolate()->factory()->the_hole_value()); | 1372 __ cmp(eax, isolate()->factory()->the_hole_value()); |
| 1363 __ j(not_equal, &done, Label::kNear); | 1373 __ j(not_equal, &done, Label::kNear); |
| 1364 if (var->mode() == LET || var->mode() == CONST) { | 1374 if (var->mode() == LET || var->mode() == CONST) { |
| 1365 // Throw a reference error when using an uninitialized let/const | 1375 // Throw a reference error when using an uninitialized let/const |
| 1366 // binding in harmony mode. | 1376 // binding in harmony mode. |
| 1367 __ push(Immediate(var->name())); | 1377 __ push(Immediate(var->name())); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1448 __ mov(FieldOperand(eax, i + kPointerSize), ecx); | 1458 __ mov(FieldOperand(eax, i + kPointerSize), ecx); |
| 1449 } | 1459 } |
| 1450 if ((size % (2 * kPointerSize)) != 0) { | 1460 if ((size % (2 * kPointerSize)) != 0) { |
| 1451 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); | 1461 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); |
| 1452 __ mov(FieldOperand(eax, size - kPointerSize), edx); | 1462 __ mov(FieldOperand(eax, size - kPointerSize), edx); |
| 1453 } | 1463 } |
| 1454 context()->Plug(eax); | 1464 context()->Plug(eax); |
| 1455 } | 1465 } |
| 1456 | 1466 |
| 1457 | 1467 |
| 1458 void FullCodeGenerator::EmitAccessor(Expression* expression) { | 1468 void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) { |
| 1469 Expression* expression = (property == NULL) ? NULL : property->value(); |
| 1459 if (expression == NULL) { | 1470 if (expression == NULL) { |
| 1460 __ push(Immediate(isolate()->factory()->null_value())); | 1471 __ push(Immediate(isolate()->factory()->null_value())); |
| 1461 } else { | 1472 } else { |
| 1462 VisitForStackValue(expression); | 1473 VisitForStackValue(expression); |
| 1474 if (NeedsHomeObject(expression)) { |
| 1475 DCHECK(property->kind() == ObjectLiteral::Property::GETTER || |
| 1476 property->kind() == ObjectLiteral::Property::SETTER); |
| 1477 int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3; |
| 1478 EmitSetHomeObject(expression, offset, property->GetSlot()); |
| 1479 } |
| 1463 } | 1480 } |
| 1464 } | 1481 } |
| 1465 | 1482 |
| 1466 | 1483 |
| 1467 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 1484 void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1468 Comment cmnt(masm_, "[ ObjectLiteral"); | 1485 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 1469 | 1486 |
| 1470 Handle<FixedArray> constant_properties = expr->constant_properties(); | 1487 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 1471 int flags = expr->ComputeFlags(); | 1488 int flags = expr->ComputeFlags(); |
| 1472 // If any of the keys would store to the elements array, then we shouldn't | 1489 // If any of the keys would store to the elements array, then we shouldn't |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1488 __ CallStub(&stub); | 1505 __ CallStub(&stub); |
| 1489 } | 1506 } |
| 1490 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1507 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1491 | 1508 |
| 1492 // If result_saved is true the result is on top of the stack. If | 1509 // If result_saved is true the result is on top of the stack. If |
| 1493 // result_saved is false the result is in eax. | 1510 // result_saved is false the result is in eax. |
| 1494 bool result_saved = false; | 1511 bool result_saved = false; |
| 1495 | 1512 |
| 1496 AccessorTable accessor_table(zone()); | 1513 AccessorTable accessor_table(zone()); |
| 1497 int property_index = 0; | 1514 int property_index = 0; |
| 1498 // store_slot_index points to the vector IC slot for the next store IC used. | |
| 1499 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots | |
| 1500 // and must be updated if the number of store ICs emitted here changes. | |
| 1501 int store_slot_index = 0; | |
| 1502 for (; property_index < expr->properties()->length(); property_index++) { | 1515 for (; property_index < expr->properties()->length(); property_index++) { |
| 1503 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1516 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1504 if (property->is_computed_name()) break; | 1517 if (property->is_computed_name()) break; |
| 1505 if (property->IsCompileTimeValue()) continue; | 1518 if (property->IsCompileTimeValue()) continue; |
| 1506 | 1519 |
| 1507 Literal* key = property->key()->AsLiteral(); | 1520 Literal* key = property->key()->AsLiteral(); |
| 1508 Expression* value = property->value(); | 1521 Expression* value = property->value(); |
| 1509 if (!result_saved) { | 1522 if (!result_saved) { |
| 1510 __ push(eax); // Save result on the stack | 1523 __ push(eax); // Save result on the stack |
| 1511 result_saved = true; | 1524 result_saved = true; |
| 1512 } | 1525 } |
| 1513 switch (property->kind()) { | 1526 switch (property->kind()) { |
| 1514 case ObjectLiteral::Property::CONSTANT: | 1527 case ObjectLiteral::Property::CONSTANT: |
| 1515 UNREACHABLE(); | 1528 UNREACHABLE(); |
| 1516 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1529 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1517 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1530 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1518 // Fall through. | 1531 // Fall through. |
| 1519 case ObjectLiteral::Property::COMPUTED: | 1532 case ObjectLiteral::Property::COMPUTED: |
| 1520 // It is safe to use [[Put]] here because the boilerplate already | 1533 // It is safe to use [[Put]] here because the boilerplate already |
| 1521 // contains computed properties with an uninitialized value. | 1534 // contains computed properties with an uninitialized value. |
| 1522 if (key->value()->IsInternalizedString()) { | 1535 if (key->value()->IsInternalizedString()) { |
| 1523 if (property->emit_store()) { | 1536 if (property->emit_store()) { |
| 1524 VisitForAccumulatorValue(value); | 1537 VisitForAccumulatorValue(value); |
| 1525 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1538 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 1526 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); | 1539 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); |
| 1527 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1540 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1528 if (FLAG_vector_stores) { | 1541 if (FLAG_vector_stores) { |
| 1529 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | 1542 EmitLoadStoreICSlot(property->GetSlot(0)); |
| 1530 CallStoreIC(); | 1543 CallStoreIC(); |
| 1531 } else { | 1544 } else { |
| 1532 CallStoreIC(key->LiteralFeedbackId()); | 1545 CallStoreIC(key->LiteralFeedbackId()); |
| 1533 } | 1546 } |
| 1534 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1547 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1535 | |
| 1536 if (NeedsHomeObject(value)) { | 1548 if (NeedsHomeObject(value)) { |
| 1537 __ mov(StoreDescriptor::ReceiverRegister(), eax); | 1549 EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); |
| 1538 __ mov(StoreDescriptor::NameRegister(), | |
| 1539 Immediate(isolate()->factory()->home_object_symbol())); | |
| 1540 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0)); | |
| 1541 if (FLAG_vector_stores) { | |
| 1542 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); | |
| 1543 } | |
| 1544 CallStoreIC(); | |
| 1545 } | 1550 } |
| 1546 } else { | 1551 } else { |
| 1547 VisitForEffect(value); | 1552 VisitForEffect(value); |
| 1548 } | 1553 } |
| 1549 break; | 1554 break; |
| 1550 } | 1555 } |
| 1551 __ push(Operand(esp, 0)); // Duplicate receiver. | 1556 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1552 VisitForStackValue(key); | 1557 VisitForStackValue(key); |
| 1553 VisitForStackValue(value); | 1558 VisitForStackValue(value); |
| 1554 if (property->emit_store()) { | 1559 if (property->emit_store()) { |
| 1555 EmitSetHomeObjectIfNeeded( | 1560 if (NeedsHomeObject(value)) { |
| 1556 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1561 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1562 } |
| 1557 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode | 1563 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode |
| 1558 __ CallRuntime(Runtime::kSetProperty, 4); | 1564 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1559 } else { | 1565 } else { |
| 1560 __ Drop(3); | 1566 __ Drop(3); |
| 1561 } | 1567 } |
| 1562 break; | 1568 break; |
| 1563 case ObjectLiteral::Property::PROTOTYPE: | 1569 case ObjectLiteral::Property::PROTOTYPE: |
| 1564 __ push(Operand(esp, 0)); // Duplicate receiver. | 1570 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1565 VisitForStackValue(value); | 1571 VisitForStackValue(value); |
| 1566 DCHECK(property->emit_store()); | 1572 DCHECK(property->emit_store()); |
| 1567 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1573 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1568 break; | 1574 break; |
| 1569 case ObjectLiteral::Property::GETTER: | 1575 case ObjectLiteral::Property::GETTER: |
| 1570 if (property->emit_store()) { | 1576 if (property->emit_store()) { |
| 1571 accessor_table.lookup(key)->second->getter = value; | 1577 accessor_table.lookup(key)->second->getter = property; |
| 1572 } | 1578 } |
| 1573 break; | 1579 break; |
| 1574 case ObjectLiteral::Property::SETTER: | 1580 case ObjectLiteral::Property::SETTER: |
| 1575 if (property->emit_store()) { | 1581 if (property->emit_store()) { |
| 1576 accessor_table.lookup(key)->second->setter = value; | 1582 accessor_table.lookup(key)->second->setter = property; |
| 1577 } | 1583 } |
| 1578 break; | 1584 break; |
| 1579 } | 1585 } |
| 1580 } | 1586 } |
| 1581 | 1587 |
| 1582 // Emit code to define accessors, using only a single call to the runtime for | 1588 // Emit code to define accessors, using only a single call to the runtime for |
| 1583 // each pair of corresponding getters and setters. | 1589 // each pair of corresponding getters and setters. |
| 1584 for (AccessorTable::Iterator it = accessor_table.begin(); | 1590 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1585 it != accessor_table.end(); | 1591 it != accessor_table.end(); |
| 1586 ++it) { | 1592 ++it) { |
| 1587 __ push(Operand(esp, 0)); // Duplicate receiver. | 1593 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1588 VisitForStackValue(it->first); | 1594 VisitForStackValue(it->first); |
| 1595 |
| 1589 EmitAccessor(it->second->getter); | 1596 EmitAccessor(it->second->getter); |
| 1590 EmitSetHomeObjectIfNeeded( | |
| 1591 it->second->getter, 2, | |
| 1592 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
| 1593 | |
| 1594 EmitAccessor(it->second->setter); | 1597 EmitAccessor(it->second->setter); |
| 1595 EmitSetHomeObjectIfNeeded( | |
| 1596 it->second->setter, 3, | |
| 1597 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); | |
| 1598 | 1598 |
| 1599 __ push(Immediate(Smi::FromInt(NONE))); | 1599 __ push(Immediate(Smi::FromInt(NONE))); |
| 1600 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1600 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1601 } | 1601 } |
| 1602 | 1602 |
| 1603 // Object literals have two parts. The "static" part on the left contains no | 1603 // Object literals have two parts. The "static" part on the left contains no |
| 1604 // computed property names, and so we can compute its map ahead of time; see | 1604 // computed property names, and so we can compute its map ahead of time; see |
| 1605 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1605 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1606 // starts with the first computed property name, and continues with all | 1606 // starts with the first computed property name, and continues with all |
| 1607 // properties to its right. All the code from above initializes the static | 1607 // properties to its right. All the code from above initializes the static |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1621 __ push(Operand(esp, 0)); // Duplicate receiver. | 1621 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1622 | 1622 |
| 1623 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1623 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1624 DCHECK(!property->is_computed_name()); | 1624 DCHECK(!property->is_computed_name()); |
| 1625 VisitForStackValue(value); | 1625 VisitForStackValue(value); |
| 1626 DCHECK(property->emit_store()); | 1626 DCHECK(property->emit_store()); |
| 1627 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1627 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1628 } else { | 1628 } else { |
| 1629 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1629 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1630 VisitForStackValue(value); | 1630 VisitForStackValue(value); |
| 1631 EmitSetHomeObjectIfNeeded( | 1631 if (NeedsHomeObject(value)) { |
| 1632 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); | 1632 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 1633 } |
| 1633 | 1634 |
| 1634 switch (property->kind()) { | 1635 switch (property->kind()) { |
| 1635 case ObjectLiteral::Property::CONSTANT: | 1636 case ObjectLiteral::Property::CONSTANT: |
| 1636 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1637 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1637 case ObjectLiteral::Property::COMPUTED: | 1638 case ObjectLiteral::Property::COMPUTED: |
| 1638 if (property->emit_store()) { | 1639 if (property->emit_store()) { |
| 1639 __ push(Immediate(Smi::FromInt(NONE))); | 1640 __ push(Immediate(Smi::FromInt(NONE))); |
| 1640 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1641 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1641 } else { | 1642 } else { |
| 1642 __ Drop(3); | 1643 __ Drop(3); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1664 DCHECK(result_saved); | 1665 DCHECK(result_saved); |
| 1665 __ push(Operand(esp, 0)); | 1666 __ push(Operand(esp, 0)); |
| 1666 __ CallRuntime(Runtime::kToFastProperties, 1); | 1667 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1667 } | 1668 } |
| 1668 | 1669 |
| 1669 if (result_saved) { | 1670 if (result_saved) { |
| 1670 context()->PlugTOS(); | 1671 context()->PlugTOS(); |
| 1671 } else { | 1672 } else { |
| 1672 context()->Plug(eax); | 1673 context()->Plug(eax); |
| 1673 } | 1674 } |
| 1674 | |
| 1675 // Verify that compilation exactly consumed the number of store ic slots that | |
| 1676 // the ObjectLiteral node had to offer. | |
| 1677 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); | |
| 1678 } | 1675 } |
| 1679 | 1676 |
| 1680 | 1677 |
| 1681 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1678 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1682 Comment cmnt(masm_, "[ ArrayLiteral"); | 1679 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1683 | 1680 |
| 1684 expr->BuildConstantElements(isolate()); | 1681 expr->BuildConstantElements(isolate()); |
| 1685 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1682 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1686 bool has_constant_fast_elements = | 1683 bool has_constant_fast_elements = |
| 1687 IsFastObjectElementsKind(expr->constant_elements_kind()); | 1684 IsFastObjectElementsKind(expr->constant_elements_kind()); |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2336 break; | 2333 break; |
| 2337 default: | 2334 default: |
| 2338 UNREACHABLE(); | 2335 UNREACHABLE(); |
| 2339 } | 2336 } |
| 2340 | 2337 |
| 2341 __ bind(&done); | 2338 __ bind(&done); |
| 2342 context()->Plug(eax); | 2339 context()->Plug(eax); |
| 2343 } | 2340 } |
| 2344 | 2341 |
| 2345 | 2342 |
| 2346 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit, | 2343 void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) { |
| 2347 int* used_store_slots) { | |
| 2348 // Constructor is in eax. | 2344 // Constructor is in eax. |
| 2349 DCHECK(lit != NULL); | 2345 DCHECK(lit != NULL); |
| 2350 __ push(eax); | 2346 __ push(eax); |
| 2351 | 2347 |
| 2352 // No access check is needed here since the constructor is created by the | 2348 // No access check is needed here since the constructor is created by the |
| 2353 // class literal. | 2349 // class literal. |
| 2354 Register scratch = ebx; | 2350 Register scratch = ebx; |
| 2355 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset)); | 2351 __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset)); |
| 2356 __ Push(scratch); | 2352 __ Push(scratch); |
| 2357 | 2353 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2369 // The static prototype property is read only. We handle the non computed | 2365 // The static prototype property is read only. We handle the non computed |
| 2370 // property name case in the parser. Since this is the only case where we | 2366 // property name case in the parser. Since this is the only case where we |
| 2371 // need to check for an own read only property we special case this so we do | 2367 // need to check for an own read only property we special case this so we do |
| 2372 // not need to do this for every property. | 2368 // not need to do this for every property. |
| 2373 if (property->is_static() && property->is_computed_name()) { | 2369 if (property->is_static() && property->is_computed_name()) { |
| 2374 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); | 2370 __ CallRuntime(Runtime::kThrowIfStaticPrototype, 1); |
| 2375 __ push(eax); | 2371 __ push(eax); |
| 2376 } | 2372 } |
| 2377 | 2373 |
| 2378 VisitForStackValue(value); | 2374 VisitForStackValue(value); |
| 2379 EmitSetHomeObjectIfNeeded(value, 2, | 2375 if (NeedsHomeObject(value)) { |
| 2380 lit->SlotForHomeObject(value, used_store_slots)); | 2376 EmitSetHomeObject(value, 2, property->GetSlot()); |
| 2377 } |
| 2381 | 2378 |
| 2382 switch (property->kind()) { | 2379 switch (property->kind()) { |
| 2383 case ObjectLiteral::Property::CONSTANT: | 2380 case ObjectLiteral::Property::CONSTANT: |
| 2384 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 2381 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 2385 case ObjectLiteral::Property::PROTOTYPE: | 2382 case ObjectLiteral::Property::PROTOTYPE: |
| 2386 UNREACHABLE(); | 2383 UNREACHABLE(); |
| 2387 case ObjectLiteral::Property::COMPUTED: | 2384 case ObjectLiteral::Property::COMPUTED: |
| 2388 __ CallRuntime(Runtime::kDefineClassMethod, 3); | 2385 __ CallRuntime(Runtime::kDefineClassMethod, 3); |
| 2389 break; | 2386 break; |
| 2390 | 2387 |
| (...skipping 2749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5140 Assembler::target_address_at(call_target_address, | 5137 Assembler::target_address_at(call_target_address, |
| 5141 unoptimized_code)); | 5138 unoptimized_code)); |
| 5142 return OSR_AFTER_STACK_CHECK; | 5139 return OSR_AFTER_STACK_CHECK; |
| 5143 } | 5140 } |
| 5144 | 5141 |
| 5145 | 5142 |
| 5146 } // namespace internal | 5143 } // namespace internal |
| 5147 } // namespace v8 | 5144 } // namespace v8 |
| 5148 | 5145 |
| 5149 #endif // V8_TARGET_ARCH_X87 | 5146 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |