| 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/full-codegen/full-codegen.h" | 7 #include "src/full-codegen/full-codegen.h" |
| 8 #include "src/ast/compile-time-value.h" | 8 #include "src/ast/compile-time-value.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 Comment cmnt(masm_, "[ Assignment"); | 1318 Comment cmnt(masm_, "[ Assignment"); |
| 1319 | 1319 |
| 1320 Property* property = expr->target()->AsProperty(); | 1320 Property* property = expr->target()->AsProperty(); |
| 1321 LhsKind assign_type = Property::GetAssignType(property); | 1321 LhsKind assign_type = Property::GetAssignType(property); |
| 1322 | 1322 |
| 1323 // Evaluate LHS expression. | 1323 // Evaluate LHS expression. |
| 1324 switch (assign_type) { | 1324 switch (assign_type) { |
| 1325 case VARIABLE: | 1325 case VARIABLE: |
| 1326 // Nothing to do here. | 1326 // Nothing to do here. |
| 1327 break; | 1327 break; |
| 1328 case NAMED_SUPER_PROPERTY: | |
| 1329 VisitForStackValue( | |
| 1330 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1331 VisitForAccumulatorValue( | |
| 1332 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1333 PushOperand(result_register()); | |
| 1334 if (expr->is_compound()) { | |
| 1335 PushOperand(MemOperand(esp, kPointerSize)); | |
| 1336 PushOperand(result_register()); | |
| 1337 } | |
| 1338 break; | |
| 1339 case NAMED_PROPERTY: | 1328 case NAMED_PROPERTY: |
| 1340 if (expr->is_compound()) { | 1329 if (expr->is_compound()) { |
| 1341 // We need the receiver both on the stack and in the register. | 1330 // We need the receiver both on the stack and in the register. |
| 1342 VisitForStackValue(property->obj()); | 1331 VisitForStackValue(property->obj()); |
| 1343 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1332 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1344 } else { | 1333 } else { |
| 1345 VisitForStackValue(property->obj()); | 1334 VisitForStackValue(property->obj()); |
| 1346 } | 1335 } |
| 1347 break; | 1336 break; |
| 1348 case KEYED_SUPER_PROPERTY: | |
| 1349 VisitForStackValue( | |
| 1350 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1351 VisitForStackValue( | |
| 1352 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1353 VisitForAccumulatorValue(property->key()); | |
| 1354 PushOperand(result_register()); | |
| 1355 if (expr->is_compound()) { | |
| 1356 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
| 1357 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
| 1358 PushOperand(result_register()); | |
| 1359 } | |
| 1360 break; | |
| 1361 case KEYED_PROPERTY: { | 1337 case KEYED_PROPERTY: { |
| 1362 if (expr->is_compound()) { | 1338 if (expr->is_compound()) { |
| 1363 VisitForStackValue(property->obj()); | 1339 VisitForStackValue(property->obj()); |
| 1364 VisitForStackValue(property->key()); | 1340 VisitForStackValue(property->key()); |
| 1365 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); | 1341 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); |
| 1366 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); | 1342 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); |
| 1367 } else { | 1343 } else { |
| 1368 VisitForStackValue(property->obj()); | 1344 VisitForStackValue(property->obj()); |
| 1369 VisitForStackValue(property->key()); | 1345 VisitForStackValue(property->key()); |
| 1370 } | 1346 } |
| 1371 break; | 1347 break; |
| 1372 } | 1348 } |
| 1349 case NAMED_SUPER_PROPERTY: |
| 1350 case KEYED_SUPER_PROPERTY: |
| 1351 UNREACHABLE(); |
| 1352 break; |
| 1373 } | 1353 } |
| 1374 | 1354 |
| 1375 // For compound assignments we need another deoptimization point after the | 1355 // For compound assignments we need another deoptimization point after the |
| 1376 // variable/property load. | 1356 // variable/property load. |
| 1377 if (expr->is_compound()) { | 1357 if (expr->is_compound()) { |
| 1378 AccumulatorValueContext result_context(this); | 1358 AccumulatorValueContext result_context(this); |
| 1379 { AccumulatorValueContext left_operand_context(this); | 1359 { AccumulatorValueContext left_operand_context(this); |
| 1380 switch (assign_type) { | 1360 switch (assign_type) { |
| 1381 case VARIABLE: | 1361 case VARIABLE: |
| 1382 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1362 EmitVariableLoad(expr->target()->AsVariableProxy()); |
| 1383 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); | 1363 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); |
| 1384 break; | 1364 break; |
| 1385 case NAMED_SUPER_PROPERTY: | |
| 1386 EmitNamedSuperPropertyLoad(property); | |
| 1387 PrepareForBailoutForId(property->LoadId(), | |
| 1388 BailoutState::TOS_REGISTER); | |
| 1389 break; | |
| 1390 case NAMED_PROPERTY: | 1365 case NAMED_PROPERTY: |
| 1391 EmitNamedPropertyLoad(property); | 1366 EmitNamedPropertyLoad(property); |
| 1392 PrepareForBailoutForId(property->LoadId(), | 1367 PrepareForBailoutForId(property->LoadId(), |
| 1393 BailoutState::TOS_REGISTER); | 1368 BailoutState::TOS_REGISTER); |
| 1394 break; | 1369 break; |
| 1395 case KEYED_SUPER_PROPERTY: | |
| 1396 EmitKeyedSuperPropertyLoad(property); | |
| 1397 PrepareForBailoutForId(property->LoadId(), | |
| 1398 BailoutState::TOS_REGISTER); | |
| 1399 break; | |
| 1400 case KEYED_PROPERTY: | 1370 case KEYED_PROPERTY: |
| 1401 EmitKeyedPropertyLoad(property); | 1371 EmitKeyedPropertyLoad(property); |
| 1402 PrepareForBailoutForId(property->LoadId(), | 1372 PrepareForBailoutForId(property->LoadId(), |
| 1403 BailoutState::TOS_REGISTER); | 1373 BailoutState::TOS_REGISTER); |
| 1404 break; | 1374 break; |
| 1375 case NAMED_SUPER_PROPERTY: |
| 1376 case KEYED_SUPER_PROPERTY: |
| 1377 UNREACHABLE(); |
| 1378 break; |
| 1405 } | 1379 } |
| 1406 } | 1380 } |
| 1407 | 1381 |
| 1408 Token::Value op = expr->binary_op(); | 1382 Token::Value op = expr->binary_op(); |
| 1409 PushOperand(eax); // Left operand goes on the stack. | 1383 PushOperand(eax); // Left operand goes on the stack. |
| 1410 VisitForAccumulatorValue(expr->value()); | 1384 VisitForAccumulatorValue(expr->value()); |
| 1411 | 1385 |
| 1412 if (ShouldInlineSmiCase(op)) { | 1386 if (ShouldInlineSmiCase(op)) { |
| 1413 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1387 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| 1414 op, | 1388 op, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1432 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1406 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1433 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1407 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
| 1434 proxy->hole_check_mode()); | 1408 proxy->hole_check_mode()); |
| 1435 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1409 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1436 context()->Plug(eax); | 1410 context()->Plug(eax); |
| 1437 break; | 1411 break; |
| 1438 } | 1412 } |
| 1439 case NAMED_PROPERTY: | 1413 case NAMED_PROPERTY: |
| 1440 EmitNamedPropertyAssignment(expr); | 1414 EmitNamedPropertyAssignment(expr); |
| 1441 break; | 1415 break; |
| 1442 case NAMED_SUPER_PROPERTY: | |
| 1443 EmitNamedSuperPropertyStore(property); | |
| 1444 context()->Plug(result_register()); | |
| 1445 break; | |
| 1446 case KEYED_SUPER_PROPERTY: | |
| 1447 EmitKeyedSuperPropertyStore(property); | |
| 1448 context()->Plug(result_register()); | |
| 1449 break; | |
| 1450 case KEYED_PROPERTY: | 1416 case KEYED_PROPERTY: |
| 1451 EmitKeyedPropertyAssignment(expr); | 1417 EmitKeyedPropertyAssignment(expr); |
| 1452 break; | 1418 break; |
| 1419 case NAMED_SUPER_PROPERTY: |
| 1420 case KEYED_SUPER_PROPERTY: |
| 1421 UNREACHABLE(); |
| 1422 break; |
| 1453 } | 1423 } |
| 1454 } | 1424 } |
| 1455 | 1425 |
| 1456 | 1426 |
| 1457 void FullCodeGenerator::VisitYield(Yield* expr) { | 1427 void FullCodeGenerator::VisitYield(Yield* expr) { |
| 1458 // Resumable functions are not supported. | 1428 // Resumable functions are not supported. |
| 1459 UNREACHABLE(); | 1429 UNREACHABLE(); |
| 1460 } | 1430 } |
| 1461 | 1431 |
| 1462 void FullCodeGenerator::PushOperand(MemOperand operand) { | 1432 void FullCodeGenerator::PushOperand(MemOperand operand) { |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1621 break; | 1591 break; |
| 1622 } | 1592 } |
| 1623 case NAMED_PROPERTY: { | 1593 case NAMED_PROPERTY: { |
| 1624 PushOperand(eax); // Preserve value. | 1594 PushOperand(eax); // Preserve value. |
| 1625 VisitForAccumulatorValue(prop->obj()); | 1595 VisitForAccumulatorValue(prop->obj()); |
| 1626 __ Move(StoreDescriptor::ReceiverRegister(), eax); | 1596 __ Move(StoreDescriptor::ReceiverRegister(), eax); |
| 1627 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1597 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1628 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1598 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
| 1629 break; | 1599 break; |
| 1630 } | 1600 } |
| 1631 case NAMED_SUPER_PROPERTY: { | |
| 1632 PushOperand(eax); | |
| 1633 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1634 VisitForAccumulatorValue( | |
| 1635 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1636 // stack: value, this; eax: home_object | |
| 1637 Register scratch = ecx; | |
| 1638 Register scratch2 = edx; | |
| 1639 __ mov(scratch, result_register()); // home_object | |
| 1640 __ mov(eax, MemOperand(esp, kPointerSize)); // value | |
| 1641 __ mov(scratch2, MemOperand(esp, 0)); // this | |
| 1642 __ mov(MemOperand(esp, kPointerSize), scratch2); // this | |
| 1643 __ mov(MemOperand(esp, 0), scratch); // home_object | |
| 1644 // stack: this, home_object. eax: value | |
| 1645 EmitNamedSuperPropertyStore(prop); | |
| 1646 break; | |
| 1647 } | |
| 1648 case KEYED_SUPER_PROPERTY: { | |
| 1649 PushOperand(eax); | |
| 1650 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1651 VisitForStackValue( | |
| 1652 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1653 VisitForAccumulatorValue(prop->key()); | |
| 1654 Register scratch = ecx; | |
| 1655 Register scratch2 = edx; | |
| 1656 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value | |
| 1657 // stack: value, this, home_object; eax: key, edx: value | |
| 1658 __ mov(scratch, MemOperand(esp, kPointerSize)); // this | |
| 1659 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); | |
| 1660 __ mov(scratch, MemOperand(esp, 0)); // home_object | |
| 1661 __ mov(MemOperand(esp, kPointerSize), scratch); | |
| 1662 __ mov(MemOperand(esp, 0), eax); | |
| 1663 __ mov(eax, scratch2); | |
| 1664 // stack: this, home_object, key; eax: value. | |
| 1665 EmitKeyedSuperPropertyStore(prop); | |
| 1666 break; | |
| 1667 } | |
| 1668 case KEYED_PROPERTY: { | 1601 case KEYED_PROPERTY: { |
| 1669 PushOperand(eax); // Preserve value. | 1602 PushOperand(eax); // Preserve value. |
| 1670 VisitForStackValue(prop->obj()); | 1603 VisitForStackValue(prop->obj()); |
| 1671 VisitForAccumulatorValue(prop->key()); | 1604 VisitForAccumulatorValue(prop->key()); |
| 1672 __ Move(StoreDescriptor::NameRegister(), eax); | 1605 __ Move(StoreDescriptor::NameRegister(), eax); |
| 1673 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver. | 1606 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver. |
| 1674 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1607 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1675 CallKeyedStoreIC(slot); | 1608 CallKeyedStoreIC(slot); |
| 1676 break; | 1609 break; |
| 1677 } | 1610 } |
| 1611 case NAMED_SUPER_PROPERTY: |
| 1612 case KEYED_SUPER_PROPERTY: |
| 1613 UNREACHABLE(); |
| 1614 break; |
| 1678 } | 1615 } |
| 1679 context()->Plug(eax); | 1616 context()->Plug(eax); |
| 1680 } | 1617 } |
| 1681 | 1618 |
| 1682 | 1619 |
| 1683 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 1620 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 1684 Variable* var, MemOperand location) { | 1621 Variable* var, MemOperand location) { |
| 1685 __ mov(location, eax); | 1622 __ mov(location, eax); |
| 1686 if (var->IsContextSlot()) { | 1623 if (var->IsContextSlot()) { |
| 1687 __ mov(edx, eax); | 1624 __ mov(edx, eax); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1759 DCHECK(prop != NULL); | 1696 DCHECK(prop != NULL); |
| 1760 DCHECK(prop->key()->IsLiteral()); | 1697 DCHECK(prop->key()->IsLiteral()); |
| 1761 | 1698 |
| 1762 PopOperand(StoreDescriptor::ReceiverRegister()); | 1699 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1763 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 1700 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); |
| 1764 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1701 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1765 context()->Plug(eax); | 1702 context()->Plug(eax); |
| 1766 } | 1703 } |
| 1767 | 1704 |
| 1768 | 1705 |
| 1769 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | |
| 1770 // Assignment to named property of super. | |
| 1771 // eax : value | |
| 1772 // stack : receiver ('this'), home_object | |
| 1773 DCHECK(prop != NULL); | |
| 1774 Literal* key = prop->key()->AsLiteral(); | |
| 1775 DCHECK(key != NULL); | |
| 1776 | |
| 1777 PushOperand(key->value()); | |
| 1778 PushOperand(eax); | |
| 1779 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1780 ? Runtime::kStoreToSuper_Strict | |
| 1781 : Runtime::kStoreToSuper_Sloppy); | |
| 1782 } | |
| 1783 | |
| 1784 | |
| 1785 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | |
| 1786 // Assignment to named property of super. | |
| 1787 // eax : value | |
| 1788 // stack : receiver ('this'), home_object, key | |
| 1789 | |
| 1790 PushOperand(eax); | |
| 1791 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1792 ? Runtime::kStoreKeyedToSuper_Strict | |
| 1793 : Runtime::kStoreKeyedToSuper_Sloppy); | |
| 1794 } | |
| 1795 | |
| 1796 | |
| 1797 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1706 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 1798 // Assignment to a property, using a keyed store IC. | 1707 // Assignment to a property, using a keyed store IC. |
| 1799 // eax : value | 1708 // eax : value |
| 1800 // esp[0] : key | 1709 // esp[0] : key |
| 1801 // esp[kPointerSize] : receiver | 1710 // esp[kPointerSize] : receiver |
| 1802 | 1711 |
| 1803 PopOperand(StoreDescriptor::NameRegister()); // Key. | 1712 PopOperand(StoreDescriptor::NameRegister()); // Key. |
| 1804 PopOperand(StoreDescriptor::ReceiverRegister()); | 1713 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1805 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1714 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 1806 CallKeyedStoreIC(expr->AssignmentSlot()); | 1715 CallKeyedStoreIC(expr->AssignmentSlot()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1834 // Push the target function under the receiver. | 1743 // Push the target function under the receiver. |
| 1835 PushOperand(Operand(esp, 0)); | 1744 PushOperand(Operand(esp, 0)); |
| 1836 __ mov(Operand(esp, kPointerSize), eax); | 1745 __ mov(Operand(esp, kPointerSize), eax); |
| 1837 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 1746 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 1838 } | 1747 } |
| 1839 | 1748 |
| 1840 EmitCall(expr, convert_mode); | 1749 EmitCall(expr, convert_mode); |
| 1841 } | 1750 } |
| 1842 | 1751 |
| 1843 | 1752 |
| 1844 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | |
| 1845 SetExpressionPosition(expr); | |
| 1846 Expression* callee = expr->expression(); | |
| 1847 DCHECK(callee->IsProperty()); | |
| 1848 Property* prop = callee->AsProperty(); | |
| 1849 DCHECK(prop->IsSuperAccess()); | |
| 1850 | |
| 1851 Literal* key = prop->key()->AsLiteral(); | |
| 1852 DCHECK(!key->value()->IsSmi()); | |
| 1853 // Load the function from the receiver. | |
| 1854 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 1855 VisitForStackValue(super_ref->home_object()); | |
| 1856 VisitForAccumulatorValue(super_ref->this_var()); | |
| 1857 PushOperand(eax); | |
| 1858 PushOperand(eax); | |
| 1859 PushOperand(Operand(esp, kPointerSize * 2)); | |
| 1860 PushOperand(key->value()); | |
| 1861 // Stack here: | |
| 1862 // - home_object | |
| 1863 // - this (receiver) | |
| 1864 // - this (receiver) <-- LoadFromSuper will pop here and below. | |
| 1865 // - home_object | |
| 1866 // - key | |
| 1867 CallRuntimeWithOperands(Runtime::kLoadFromSuper); | |
| 1868 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 1869 | |
| 1870 // Replace home_object with target function. | |
| 1871 __ mov(Operand(esp, kPointerSize), eax); | |
| 1872 | |
| 1873 // Stack here: | |
| 1874 // - target function | |
| 1875 // - this (receiver) | |
| 1876 EmitCall(expr); | |
| 1877 } | |
| 1878 | |
| 1879 | |
| 1880 // Code common for calls using the IC. | 1753 // Code common for calls using the IC. |
| 1881 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 1754 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 1882 Expression* key) { | 1755 Expression* key) { |
| 1883 // Load the key. | 1756 // Load the key. |
| 1884 VisitForAccumulatorValue(key); | 1757 VisitForAccumulatorValue(key); |
| 1885 | 1758 |
| 1886 Expression* callee = expr->expression(); | 1759 Expression* callee = expr->expression(); |
| 1887 | 1760 |
| 1888 // Load the function from the receiver. | 1761 // Load the function from the receiver. |
| 1889 DCHECK(callee->IsProperty()); | 1762 DCHECK(callee->IsProperty()); |
| 1890 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1763 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1891 __ mov(LoadDescriptor::NameRegister(), eax); | 1764 __ mov(LoadDescriptor::NameRegister(), eax); |
| 1892 EmitKeyedPropertyLoad(callee->AsProperty()); | 1765 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 1893 PrepareForBailoutForId(callee->AsProperty()->LoadId(), | 1766 PrepareForBailoutForId(callee->AsProperty()->LoadId(), |
| 1894 BailoutState::TOS_REGISTER); | 1767 BailoutState::TOS_REGISTER); |
| 1895 | 1768 |
| 1896 // Push the target function under the receiver. | 1769 // Push the target function under the receiver. |
| 1897 PushOperand(Operand(esp, 0)); | 1770 PushOperand(Operand(esp, 0)); |
| 1898 __ mov(Operand(esp, kPointerSize), eax); | 1771 __ mov(Operand(esp, kPointerSize), eax); |
| 1899 | 1772 |
| 1900 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 1773 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
| 1901 } | 1774 } |
| 1902 | 1775 |
| 1903 | 1776 |
| 1904 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | |
| 1905 Expression* callee = expr->expression(); | |
| 1906 DCHECK(callee->IsProperty()); | |
| 1907 Property* prop = callee->AsProperty(); | |
| 1908 DCHECK(prop->IsSuperAccess()); | |
| 1909 | |
| 1910 SetExpressionPosition(prop); | |
| 1911 // Load the function from the receiver. | |
| 1912 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 1913 VisitForStackValue(super_ref->home_object()); | |
| 1914 VisitForAccumulatorValue(super_ref->this_var()); | |
| 1915 PushOperand(eax); | |
| 1916 PushOperand(eax); | |
| 1917 PushOperand(Operand(esp, kPointerSize * 2)); | |
| 1918 VisitForStackValue(prop->key()); | |
| 1919 // Stack here: | |
| 1920 // - home_object | |
| 1921 // - this (receiver) | |
| 1922 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | |
| 1923 // - home_object | |
| 1924 // - key | |
| 1925 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | |
| 1926 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 1927 | |
| 1928 // Replace home_object with target function. | |
| 1929 __ mov(Operand(esp, kPointerSize), eax); | |
| 1930 | |
| 1931 // Stack here: | |
| 1932 // - target function | |
| 1933 // - this (receiver) | |
| 1934 EmitCall(expr); | |
| 1935 } | |
| 1936 | |
| 1937 | |
| 1938 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 1777 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
| 1939 // Load the arguments. | 1778 // Load the arguments. |
| 1940 ZoneList<Expression*>* args = expr->arguments(); | 1779 ZoneList<Expression*>* args = expr->arguments(); |
| 1941 int arg_count = args->length(); | 1780 int arg_count = args->length(); |
| 1942 for (int i = 0; i < arg_count; i++) { | 1781 for (int i = 0; i < arg_count; i++) { |
| 1943 VisitForStackValue(args->at(i)); | 1782 VisitForStackValue(args->at(i)); |
| 1944 } | 1783 } |
| 1945 | 1784 |
| 1946 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1785 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); |
| 1947 SetCallPosition(expr, expr->tail_call_mode()); | 1786 SetCallPosition(expr, expr->tail_call_mode()); |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2458 } | 2297 } |
| 2459 switch (assign_type) { | 2298 switch (assign_type) { |
| 2460 case NAMED_PROPERTY: { | 2299 case NAMED_PROPERTY: { |
| 2461 // Put the object both on the stack and in the register. | 2300 // Put the object both on the stack and in the register. |
| 2462 VisitForStackValue(prop->obj()); | 2301 VisitForStackValue(prop->obj()); |
| 2463 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2302 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 2464 EmitNamedPropertyLoad(prop); | 2303 EmitNamedPropertyLoad(prop); |
| 2465 break; | 2304 break; |
| 2466 } | 2305 } |
| 2467 | 2306 |
| 2468 case NAMED_SUPER_PROPERTY: { | |
| 2469 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2470 VisitForAccumulatorValue( | |
| 2471 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2472 PushOperand(result_register()); | |
| 2473 PushOperand(MemOperand(esp, kPointerSize)); | |
| 2474 PushOperand(result_register()); | |
| 2475 EmitNamedSuperPropertyLoad(prop); | |
| 2476 break; | |
| 2477 } | |
| 2478 | |
| 2479 case KEYED_SUPER_PROPERTY: { | |
| 2480 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2481 VisitForStackValue( | |
| 2482 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2483 VisitForAccumulatorValue(prop->key()); | |
| 2484 PushOperand(result_register()); | |
| 2485 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
| 2486 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
| 2487 PushOperand(result_register()); | |
| 2488 EmitKeyedSuperPropertyLoad(prop); | |
| 2489 break; | |
| 2490 } | |
| 2491 | |
| 2492 case KEYED_PROPERTY: { | 2307 case KEYED_PROPERTY: { |
| 2493 VisitForStackValue(prop->obj()); | 2308 VisitForStackValue(prop->obj()); |
| 2494 VisitForStackValue(prop->key()); | 2309 VisitForStackValue(prop->key()); |
| 2495 __ mov(LoadDescriptor::ReceiverRegister(), | 2310 __ mov(LoadDescriptor::ReceiverRegister(), |
| 2496 Operand(esp, kPointerSize)); // Object. | 2311 Operand(esp, kPointerSize)); // Object. |
| 2497 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. | 2312 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. |
| 2498 EmitKeyedPropertyLoad(prop); | 2313 EmitKeyedPropertyLoad(prop); |
| 2499 break; | 2314 break; |
| 2500 } | 2315 } |
| 2501 | 2316 |
| 2317 case NAMED_SUPER_PROPERTY: |
| 2318 case KEYED_SUPER_PROPERTY: |
| 2502 case VARIABLE: | 2319 case VARIABLE: |
| 2503 UNREACHABLE(); | 2320 UNREACHABLE(); |
| 2504 } | 2321 } |
| 2505 } | 2322 } |
| 2506 | 2323 |
| 2507 // We need a second deoptimization point after loading the value | 2324 // We need a second deoptimization point after loading the value |
| 2508 // in case evaluating the property load my have a side effect. | 2325 // in case evaluating the property load my have a side effect. |
| 2509 if (assign_type == VARIABLE) { | 2326 if (assign_type == VARIABLE) { |
| 2510 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); | 2327 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); |
| 2511 } else { | 2328 } else { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2525 // Save the result on the stack. If we have a named or keyed property | 2342 // Save the result on the stack. If we have a named or keyed property |
| 2526 // we store the result under the receiver that is currently on top | 2343 // we store the result under the receiver that is currently on top |
| 2527 // of the stack. | 2344 // of the stack. |
| 2528 switch (assign_type) { | 2345 switch (assign_type) { |
| 2529 case VARIABLE: | 2346 case VARIABLE: |
| 2530 __ push(eax); | 2347 __ push(eax); |
| 2531 break; | 2348 break; |
| 2532 case NAMED_PROPERTY: | 2349 case NAMED_PROPERTY: |
| 2533 __ mov(Operand(esp, kPointerSize), eax); | 2350 __ mov(Operand(esp, kPointerSize), eax); |
| 2534 break; | 2351 break; |
| 2535 case NAMED_SUPER_PROPERTY: | |
| 2536 __ mov(Operand(esp, 2 * kPointerSize), eax); | |
| 2537 break; | |
| 2538 case KEYED_PROPERTY: | 2352 case KEYED_PROPERTY: |
| 2539 __ mov(Operand(esp, 2 * kPointerSize), eax); | 2353 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 2540 break; | 2354 break; |
| 2355 case NAMED_SUPER_PROPERTY: |
| 2541 case KEYED_SUPER_PROPERTY: | 2356 case KEYED_SUPER_PROPERTY: |
| 2542 __ mov(Operand(esp, 3 * kPointerSize), eax); | 2357 UNREACHABLE(); |
| 2543 break; | 2358 break; |
| 2544 } | 2359 } |
| 2545 } | 2360 } |
| 2546 } | 2361 } |
| 2547 | 2362 |
| 2548 if (expr->op() == Token::INC) { | 2363 if (expr->op() == Token::INC) { |
| 2549 __ add(eax, Immediate(Smi::FromInt(1))); | 2364 __ add(eax, Immediate(Smi::FromInt(1))); |
| 2550 } else { | 2365 } else { |
| 2551 __ sub(eax, Immediate(Smi::FromInt(1))); | 2366 __ sub(eax, Immediate(Smi::FromInt(1))); |
| 2552 } | 2367 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2572 // Save the result on the stack. If we have a named or keyed property | 2387 // Save the result on the stack. If we have a named or keyed property |
| 2573 // we store the result under the receiver that is currently on top | 2388 // we store the result under the receiver that is currently on top |
| 2574 // of the stack. | 2389 // of the stack. |
| 2575 switch (assign_type) { | 2390 switch (assign_type) { |
| 2576 case VARIABLE: | 2391 case VARIABLE: |
| 2577 PushOperand(eax); | 2392 PushOperand(eax); |
| 2578 break; | 2393 break; |
| 2579 case NAMED_PROPERTY: | 2394 case NAMED_PROPERTY: |
| 2580 __ mov(Operand(esp, kPointerSize), eax); | 2395 __ mov(Operand(esp, kPointerSize), eax); |
| 2581 break; | 2396 break; |
| 2582 case NAMED_SUPER_PROPERTY: | |
| 2583 __ mov(Operand(esp, 2 * kPointerSize), eax); | |
| 2584 break; | |
| 2585 case KEYED_PROPERTY: | 2397 case KEYED_PROPERTY: |
| 2586 __ mov(Operand(esp, 2 * kPointerSize), eax); | 2398 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 2587 break; | 2399 break; |
| 2400 case NAMED_SUPER_PROPERTY: |
| 2588 case KEYED_SUPER_PROPERTY: | 2401 case KEYED_SUPER_PROPERTY: |
| 2589 __ mov(Operand(esp, 3 * kPointerSize), eax); | 2402 UNREACHABLE(); |
| 2590 break; | 2403 break; |
| 2591 } | 2404 } |
| 2592 } | 2405 } |
| 2593 } | 2406 } |
| 2594 | 2407 |
| 2595 SetExpressionPosition(expr); | 2408 SetExpressionPosition(expr); |
| 2596 | 2409 |
| 2597 // Call stub for +1/-1. | 2410 // Call stub for +1/-1. |
| 2598 __ bind(&stub_call); | 2411 __ bind(&stub_call); |
| 2599 __ mov(edx, eax); | 2412 __ mov(edx, eax); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2638 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2451 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2639 if (expr->is_postfix()) { | 2452 if (expr->is_postfix()) { |
| 2640 if (!context()->IsEffect()) { | 2453 if (!context()->IsEffect()) { |
| 2641 context()->PlugTOS(); | 2454 context()->PlugTOS(); |
| 2642 } | 2455 } |
| 2643 } else { | 2456 } else { |
| 2644 context()->Plug(eax); | 2457 context()->Plug(eax); |
| 2645 } | 2458 } |
| 2646 break; | 2459 break; |
| 2647 } | 2460 } |
| 2648 case NAMED_SUPER_PROPERTY: { | |
| 2649 EmitNamedSuperPropertyStore(prop); | |
| 2650 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2651 if (expr->is_postfix()) { | |
| 2652 if (!context()->IsEffect()) { | |
| 2653 context()->PlugTOS(); | |
| 2654 } | |
| 2655 } else { | |
| 2656 context()->Plug(eax); | |
| 2657 } | |
| 2658 break; | |
| 2659 } | |
| 2660 case KEYED_SUPER_PROPERTY: { | |
| 2661 EmitKeyedSuperPropertyStore(prop); | |
| 2662 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2663 if (expr->is_postfix()) { | |
| 2664 if (!context()->IsEffect()) { | |
| 2665 context()->PlugTOS(); | |
| 2666 } | |
| 2667 } else { | |
| 2668 context()->Plug(eax); | |
| 2669 } | |
| 2670 break; | |
| 2671 } | |
| 2672 case KEYED_PROPERTY: { | 2461 case KEYED_PROPERTY: { |
| 2673 PopOperand(StoreDescriptor::NameRegister()); | 2462 PopOperand(StoreDescriptor::NameRegister()); |
| 2674 PopOperand(StoreDescriptor::ReceiverRegister()); | 2463 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 2675 CallKeyedStoreIC(expr->CountSlot()); | 2464 CallKeyedStoreIC(expr->CountSlot()); |
| 2676 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2465 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2677 if (expr->is_postfix()) { | 2466 if (expr->is_postfix()) { |
| 2678 // Result is on the stack | 2467 // Result is on the stack |
| 2679 if (!context()->IsEffect()) { | 2468 if (!context()->IsEffect()) { |
| 2680 context()->PlugTOS(); | 2469 context()->PlugTOS(); |
| 2681 } | 2470 } |
| 2682 } else { | 2471 } else { |
| 2683 context()->Plug(eax); | 2472 context()->Plug(eax); |
| 2684 } | 2473 } |
| 2685 break; | 2474 break; |
| 2686 } | 2475 } |
| 2476 case NAMED_SUPER_PROPERTY: |
| 2477 case KEYED_SUPER_PROPERTY: |
| 2478 UNREACHABLE(); |
| 2479 break; |
| 2687 } | 2480 } |
| 2688 } | 2481 } |
| 2689 | 2482 |
| 2690 | 2483 |
| 2691 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 2484 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 2692 Expression* sub_expr, | 2485 Expression* sub_expr, |
| 2693 Handle<String> check) { | 2486 Handle<String> check) { |
| 2694 Label materialize_true, materialize_false; | 2487 Label materialize_true, materialize_false; |
| 2695 Label* if_true = NULL; | 2488 Label* if_true = NULL; |
| 2696 Label* if_false = NULL; | 2489 Label* if_false = NULL; |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2987 isolate->builtins()->OnStackReplacement()->entry(), | 2780 isolate->builtins()->OnStackReplacement()->entry(), |
| 2988 Assembler::target_address_at(call_target_address, unoptimized_code)); | 2781 Assembler::target_address_at(call_target_address, unoptimized_code)); |
| 2989 return ON_STACK_REPLACEMENT; | 2782 return ON_STACK_REPLACEMENT; |
| 2990 } | 2783 } |
| 2991 | 2784 |
| 2992 | 2785 |
| 2993 } // namespace internal | 2786 } // namespace internal |
| 2994 } // namespace v8 | 2787 } // namespace v8 |
| 2995 | 2788 |
| 2996 #endif // V8_TARGET_ARCH_X87 | 2789 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |