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/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 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 Comment cmnt(masm_, "[ Assignment"); | 1326 Comment cmnt(masm_, "[ Assignment"); |
1327 | 1327 |
1328 Property* property = expr->target()->AsProperty(); | 1328 Property* property = expr->target()->AsProperty(); |
1329 LhsKind assign_type = Property::GetAssignType(property); | 1329 LhsKind assign_type = Property::GetAssignType(property); |
1330 | 1330 |
1331 // Evaluate LHS expression. | 1331 // Evaluate LHS expression. |
1332 switch (assign_type) { | 1332 switch (assign_type) { |
1333 case VARIABLE: | 1333 case VARIABLE: |
1334 // Nothing to do here. | 1334 // Nothing to do here. |
1335 break; | 1335 break; |
1336 case NAMED_SUPER_PROPERTY: | |
1337 VisitForStackValue( | |
1338 property->obj()->AsSuperPropertyReference()->this_var()); | |
1339 VisitForAccumulatorValue( | |
1340 property->obj()->AsSuperPropertyReference()->home_object()); | |
1341 PushOperand(result_register()); | |
1342 if (expr->is_compound()) { | |
1343 PushOperand(MemOperand(esp, kPointerSize)); | |
1344 PushOperand(result_register()); | |
1345 } | |
1346 break; | |
1347 case NAMED_PROPERTY: | 1336 case NAMED_PROPERTY: |
1348 if (expr->is_compound()) { | 1337 if (expr->is_compound()) { |
1349 // We need the receiver both on the stack and in the register. | 1338 // We need the receiver both on the stack and in the register. |
1350 VisitForStackValue(property->obj()); | 1339 VisitForStackValue(property->obj()); |
1351 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1340 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1352 } else { | 1341 } else { |
1353 VisitForStackValue(property->obj()); | 1342 VisitForStackValue(property->obj()); |
1354 } | 1343 } |
1355 break; | 1344 break; |
1356 case KEYED_SUPER_PROPERTY: | |
1357 VisitForStackValue( | |
1358 property->obj()->AsSuperPropertyReference()->this_var()); | |
1359 VisitForStackValue( | |
1360 property->obj()->AsSuperPropertyReference()->home_object()); | |
1361 VisitForAccumulatorValue(property->key()); | |
1362 PushOperand(result_register()); | |
1363 if (expr->is_compound()) { | |
1364 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
1365 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
1366 PushOperand(result_register()); | |
1367 } | |
1368 break; | |
1369 case KEYED_PROPERTY: { | 1345 case KEYED_PROPERTY: { |
1370 if (expr->is_compound()) { | 1346 if (expr->is_compound()) { |
1371 VisitForStackValue(property->obj()); | 1347 VisitForStackValue(property->obj()); |
1372 VisitForStackValue(property->key()); | 1348 VisitForStackValue(property->key()); |
1373 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); | 1349 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); |
1374 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); | 1350 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); |
1375 } else { | 1351 } else { |
1376 VisitForStackValue(property->obj()); | 1352 VisitForStackValue(property->obj()); |
1377 VisitForStackValue(property->key()); | 1353 VisitForStackValue(property->key()); |
1378 } | 1354 } |
1379 break; | 1355 break; |
1380 } | 1356 } |
| 1357 case NAMED_SUPER_PROPERTY: |
| 1358 case KEYED_SUPER_PROPERTY: |
| 1359 UNREACHABLE(); |
| 1360 break; |
1381 } | 1361 } |
1382 | 1362 |
1383 // For compound assignments we need another deoptimization point after the | 1363 // For compound assignments we need another deoptimization point after the |
1384 // variable/property load. | 1364 // variable/property load. |
1385 if (expr->is_compound()) { | 1365 if (expr->is_compound()) { |
1386 AccumulatorValueContext result_context(this); | 1366 AccumulatorValueContext result_context(this); |
1387 { AccumulatorValueContext left_operand_context(this); | 1367 { AccumulatorValueContext left_operand_context(this); |
1388 switch (assign_type) { | 1368 switch (assign_type) { |
1389 case VARIABLE: | 1369 case VARIABLE: |
1390 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1370 EmitVariableLoad(expr->target()->AsVariableProxy()); |
1391 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); | 1371 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); |
1392 break; | 1372 break; |
1393 case NAMED_SUPER_PROPERTY: | |
1394 EmitNamedSuperPropertyLoad(property); | |
1395 PrepareForBailoutForId(property->LoadId(), | |
1396 BailoutState::TOS_REGISTER); | |
1397 break; | |
1398 case NAMED_PROPERTY: | 1373 case NAMED_PROPERTY: |
1399 EmitNamedPropertyLoad(property); | 1374 EmitNamedPropertyLoad(property); |
1400 PrepareForBailoutForId(property->LoadId(), | 1375 PrepareForBailoutForId(property->LoadId(), |
1401 BailoutState::TOS_REGISTER); | 1376 BailoutState::TOS_REGISTER); |
1402 break; | 1377 break; |
1403 case KEYED_SUPER_PROPERTY: | |
1404 EmitKeyedSuperPropertyLoad(property); | |
1405 PrepareForBailoutForId(property->LoadId(), | |
1406 BailoutState::TOS_REGISTER); | |
1407 break; | |
1408 case KEYED_PROPERTY: | 1378 case KEYED_PROPERTY: |
1409 EmitKeyedPropertyLoad(property); | 1379 EmitKeyedPropertyLoad(property); |
1410 PrepareForBailoutForId(property->LoadId(), | 1380 PrepareForBailoutForId(property->LoadId(), |
1411 BailoutState::TOS_REGISTER); | 1381 BailoutState::TOS_REGISTER); |
1412 break; | 1382 break; |
| 1383 case NAMED_SUPER_PROPERTY: |
| 1384 case KEYED_SUPER_PROPERTY: |
| 1385 UNREACHABLE(); |
| 1386 break; |
1413 } | 1387 } |
1414 } | 1388 } |
1415 | 1389 |
1416 Token::Value op = expr->binary_op(); | 1390 Token::Value op = expr->binary_op(); |
1417 PushOperand(eax); // Left operand goes on the stack. | 1391 PushOperand(eax); // Left operand goes on the stack. |
1418 VisitForAccumulatorValue(expr->value()); | 1392 VisitForAccumulatorValue(expr->value()); |
1419 | 1393 |
1420 if (ShouldInlineSmiCase(op)) { | 1394 if (ShouldInlineSmiCase(op)) { |
1421 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1395 EmitInlineSmiBinaryOp(expr->binary_operation(), |
1422 op, | 1396 op, |
(...skipping 17 matching lines...) Expand all Loading... |
1440 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1414 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
1441 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1415 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
1442 proxy->hole_check_mode()); | 1416 proxy->hole_check_mode()); |
1443 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1417 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
1444 context()->Plug(eax); | 1418 context()->Plug(eax); |
1445 break; | 1419 break; |
1446 } | 1420 } |
1447 case NAMED_PROPERTY: | 1421 case NAMED_PROPERTY: |
1448 EmitNamedPropertyAssignment(expr); | 1422 EmitNamedPropertyAssignment(expr); |
1449 break; | 1423 break; |
1450 case NAMED_SUPER_PROPERTY: | |
1451 EmitNamedSuperPropertyStore(property); | |
1452 context()->Plug(result_register()); | |
1453 break; | |
1454 case KEYED_SUPER_PROPERTY: | |
1455 EmitKeyedSuperPropertyStore(property); | |
1456 context()->Plug(result_register()); | |
1457 break; | |
1458 case KEYED_PROPERTY: | 1424 case KEYED_PROPERTY: |
1459 EmitKeyedPropertyAssignment(expr); | 1425 EmitKeyedPropertyAssignment(expr); |
1460 break; | 1426 break; |
| 1427 case NAMED_SUPER_PROPERTY: |
| 1428 case KEYED_SUPER_PROPERTY: |
| 1429 UNREACHABLE(); |
| 1430 break; |
1461 } | 1431 } |
1462 } | 1432 } |
1463 | 1433 |
1464 | 1434 |
1465 void FullCodeGenerator::VisitYield(Yield* expr) { | 1435 void FullCodeGenerator::VisitYield(Yield* expr) { |
1466 // Resumable functions are not supported. | 1436 // Resumable functions are not supported. |
1467 UNREACHABLE(); | 1437 UNREACHABLE(); |
1468 } | 1438 } |
1469 | 1439 |
1470 void FullCodeGenerator::PushOperand(MemOperand operand) { | 1440 void FullCodeGenerator::PushOperand(MemOperand operand) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 break; | 1599 break; |
1630 } | 1600 } |
1631 case NAMED_PROPERTY: { | 1601 case NAMED_PROPERTY: { |
1632 PushOperand(eax); // Preserve value. | 1602 PushOperand(eax); // Preserve value. |
1633 VisitForAccumulatorValue(prop->obj()); | 1603 VisitForAccumulatorValue(prop->obj()); |
1634 __ Move(StoreDescriptor::ReceiverRegister(), eax); | 1604 __ Move(StoreDescriptor::ReceiverRegister(), eax); |
1635 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1605 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
1636 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1606 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
1637 break; | 1607 break; |
1638 } | 1608 } |
1639 case NAMED_SUPER_PROPERTY: { | |
1640 PushOperand(eax); | |
1641 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
1642 VisitForAccumulatorValue( | |
1643 prop->obj()->AsSuperPropertyReference()->home_object()); | |
1644 // stack: value, this; eax: home_object | |
1645 Register scratch = ecx; | |
1646 Register scratch2 = edx; | |
1647 __ mov(scratch, result_register()); // home_object | |
1648 __ mov(eax, MemOperand(esp, kPointerSize)); // value | |
1649 __ mov(scratch2, MemOperand(esp, 0)); // this | |
1650 __ mov(MemOperand(esp, kPointerSize), scratch2); // this | |
1651 __ mov(MemOperand(esp, 0), scratch); // home_object | |
1652 // stack: this, home_object. eax: value | |
1653 EmitNamedSuperPropertyStore(prop); | |
1654 break; | |
1655 } | |
1656 case KEYED_SUPER_PROPERTY: { | |
1657 PushOperand(eax); | |
1658 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
1659 VisitForStackValue( | |
1660 prop->obj()->AsSuperPropertyReference()->home_object()); | |
1661 VisitForAccumulatorValue(prop->key()); | |
1662 Register scratch = ecx; | |
1663 Register scratch2 = edx; | |
1664 __ mov(scratch2, MemOperand(esp, 2 * kPointerSize)); // value | |
1665 // stack: value, this, home_object; eax: key, edx: value | |
1666 __ mov(scratch, MemOperand(esp, kPointerSize)); // this | |
1667 __ mov(MemOperand(esp, 2 * kPointerSize), scratch); | |
1668 __ mov(scratch, MemOperand(esp, 0)); // home_object | |
1669 __ mov(MemOperand(esp, kPointerSize), scratch); | |
1670 __ mov(MemOperand(esp, 0), eax); | |
1671 __ mov(eax, scratch2); | |
1672 // stack: this, home_object, key; eax: value. | |
1673 EmitKeyedSuperPropertyStore(prop); | |
1674 break; | |
1675 } | |
1676 case KEYED_PROPERTY: { | 1609 case KEYED_PROPERTY: { |
1677 PushOperand(eax); // Preserve value. | 1610 PushOperand(eax); // Preserve value. |
1678 VisitForStackValue(prop->obj()); | 1611 VisitForStackValue(prop->obj()); |
1679 VisitForAccumulatorValue(prop->key()); | 1612 VisitForAccumulatorValue(prop->key()); |
1680 __ Move(StoreDescriptor::NameRegister(), eax); | 1613 __ Move(StoreDescriptor::NameRegister(), eax); |
1681 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver. | 1614 PopOperand(StoreDescriptor::ReceiverRegister()); // Receiver. |
1682 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1615 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
1683 CallKeyedStoreIC(slot); | 1616 CallKeyedStoreIC(slot); |
1684 break; | 1617 break; |
1685 } | 1618 } |
| 1619 case NAMED_SUPER_PROPERTY: |
| 1620 case KEYED_SUPER_PROPERTY: |
| 1621 UNREACHABLE(); |
| 1622 break; |
1686 } | 1623 } |
1687 context()->Plug(eax); | 1624 context()->Plug(eax); |
1688 } | 1625 } |
1689 | 1626 |
1690 | 1627 |
1691 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 1628 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
1692 Variable* var, MemOperand location) { | 1629 Variable* var, MemOperand location) { |
1693 __ mov(location, eax); | 1630 __ mov(location, eax); |
1694 if (var->IsContextSlot()) { | 1631 if (var->IsContextSlot()) { |
1695 __ mov(edx, eax); | 1632 __ mov(edx, eax); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 DCHECK(prop != NULL); | 1704 DCHECK(prop != NULL); |
1768 DCHECK(prop->key()->IsLiteral()); | 1705 DCHECK(prop->key()->IsLiteral()); |
1769 | 1706 |
1770 PopOperand(StoreDescriptor::ReceiverRegister()); | 1707 PopOperand(StoreDescriptor::ReceiverRegister()); |
1771 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 1708 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); |
1772 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1709 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
1773 context()->Plug(eax); | 1710 context()->Plug(eax); |
1774 } | 1711 } |
1775 | 1712 |
1776 | 1713 |
1777 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | |
1778 // Assignment to named property of super. | |
1779 // eax : value | |
1780 // stack : receiver ('this'), home_object | |
1781 DCHECK(prop != NULL); | |
1782 Literal* key = prop->key()->AsLiteral(); | |
1783 DCHECK(key != NULL); | |
1784 | |
1785 PushOperand(key->value()); | |
1786 PushOperand(eax); | |
1787 CallRuntimeWithOperands(is_strict(language_mode()) | |
1788 ? Runtime::kStoreToSuper_Strict | |
1789 : Runtime::kStoreToSuper_Sloppy); | |
1790 } | |
1791 | |
1792 | |
1793 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | |
1794 // Assignment to named property of super. | |
1795 // eax : value | |
1796 // stack : receiver ('this'), home_object, key | |
1797 | |
1798 PushOperand(eax); | |
1799 CallRuntimeWithOperands(is_strict(language_mode()) | |
1800 ? Runtime::kStoreKeyedToSuper_Strict | |
1801 : Runtime::kStoreKeyedToSuper_Sloppy); | |
1802 } | |
1803 | |
1804 | |
1805 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1714 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
1806 // Assignment to a property, using a keyed store IC. | 1715 // Assignment to a property, using a keyed store IC. |
1807 // eax : value | 1716 // eax : value |
1808 // esp[0] : key | 1717 // esp[0] : key |
1809 // esp[kPointerSize] : receiver | 1718 // esp[kPointerSize] : receiver |
1810 | 1719 |
1811 PopOperand(StoreDescriptor::NameRegister()); // Key. | 1720 PopOperand(StoreDescriptor::NameRegister()); // Key. |
1812 PopOperand(StoreDescriptor::ReceiverRegister()); | 1721 PopOperand(StoreDescriptor::ReceiverRegister()); |
1813 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1722 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
1814 CallKeyedStoreIC(expr->AssignmentSlot()); | 1723 CallKeyedStoreIC(expr->AssignmentSlot()); |
(...skipping 27 matching lines...) Expand all Loading... |
1842 // Push the target function under the receiver. | 1751 // Push the target function under the receiver. |
1843 PushOperand(Operand(esp, 0)); | 1752 PushOperand(Operand(esp, 0)); |
1844 __ mov(Operand(esp, kPointerSize), eax); | 1753 __ mov(Operand(esp, kPointerSize), eax); |
1845 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 1754 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
1846 } | 1755 } |
1847 | 1756 |
1848 EmitCall(expr, convert_mode); | 1757 EmitCall(expr, convert_mode); |
1849 } | 1758 } |
1850 | 1759 |
1851 | 1760 |
1852 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | |
1853 SetExpressionPosition(expr); | |
1854 Expression* callee = expr->expression(); | |
1855 DCHECK(callee->IsProperty()); | |
1856 Property* prop = callee->AsProperty(); | |
1857 DCHECK(prop->IsSuperAccess()); | |
1858 | |
1859 Literal* key = prop->key()->AsLiteral(); | |
1860 DCHECK(!key->value()->IsSmi()); | |
1861 // Load the function from the receiver. | |
1862 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
1863 VisitForStackValue(super_ref->home_object()); | |
1864 VisitForAccumulatorValue(super_ref->this_var()); | |
1865 PushOperand(eax); | |
1866 PushOperand(eax); | |
1867 PushOperand(Operand(esp, kPointerSize * 2)); | |
1868 PushOperand(key->value()); | |
1869 // Stack here: | |
1870 // - home_object | |
1871 // - this (receiver) | |
1872 // - this (receiver) <-- LoadFromSuper will pop here and below. | |
1873 // - home_object | |
1874 // - key | |
1875 CallRuntimeWithOperands(Runtime::kLoadFromSuper); | |
1876 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
1877 | |
1878 // Replace home_object with target function. | |
1879 __ mov(Operand(esp, kPointerSize), eax); | |
1880 | |
1881 // Stack here: | |
1882 // - target function | |
1883 // - this (receiver) | |
1884 EmitCall(expr); | |
1885 } | |
1886 | |
1887 | |
1888 // Code common for calls using the IC. | 1761 // Code common for calls using the IC. |
1889 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 1762 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
1890 Expression* key) { | 1763 Expression* key) { |
1891 // Load the key. | 1764 // Load the key. |
1892 VisitForAccumulatorValue(key); | 1765 VisitForAccumulatorValue(key); |
1893 | 1766 |
1894 Expression* callee = expr->expression(); | 1767 Expression* callee = expr->expression(); |
1895 | 1768 |
1896 // Load the function from the receiver. | 1769 // Load the function from the receiver. |
1897 DCHECK(callee->IsProperty()); | 1770 DCHECK(callee->IsProperty()); |
1898 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1771 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
1899 __ mov(LoadDescriptor::NameRegister(), eax); | 1772 __ mov(LoadDescriptor::NameRegister(), eax); |
1900 EmitKeyedPropertyLoad(callee->AsProperty()); | 1773 EmitKeyedPropertyLoad(callee->AsProperty()); |
1901 PrepareForBailoutForId(callee->AsProperty()->LoadId(), | 1774 PrepareForBailoutForId(callee->AsProperty()->LoadId(), |
1902 BailoutState::TOS_REGISTER); | 1775 BailoutState::TOS_REGISTER); |
1903 | 1776 |
1904 // Push the target function under the receiver. | 1777 // Push the target function under the receiver. |
1905 PushOperand(Operand(esp, 0)); | 1778 PushOperand(Operand(esp, 0)); |
1906 __ mov(Operand(esp, kPointerSize), eax); | 1779 __ mov(Operand(esp, kPointerSize), eax); |
1907 | 1780 |
1908 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 1781 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
1909 } | 1782 } |
1910 | 1783 |
1911 | 1784 |
1912 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | |
1913 Expression* callee = expr->expression(); | |
1914 DCHECK(callee->IsProperty()); | |
1915 Property* prop = callee->AsProperty(); | |
1916 DCHECK(prop->IsSuperAccess()); | |
1917 | |
1918 SetExpressionPosition(prop); | |
1919 // Load the function from the receiver. | |
1920 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
1921 VisitForStackValue(super_ref->home_object()); | |
1922 VisitForAccumulatorValue(super_ref->this_var()); | |
1923 PushOperand(eax); | |
1924 PushOperand(eax); | |
1925 PushOperand(Operand(esp, kPointerSize * 2)); | |
1926 VisitForStackValue(prop->key()); | |
1927 // Stack here: | |
1928 // - home_object | |
1929 // - this (receiver) | |
1930 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | |
1931 // - home_object | |
1932 // - key | |
1933 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | |
1934 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
1935 | |
1936 // Replace home_object with target function. | |
1937 __ mov(Operand(esp, kPointerSize), eax); | |
1938 | |
1939 // Stack here: | |
1940 // - target function | |
1941 // - this (receiver) | |
1942 EmitCall(expr); | |
1943 } | |
1944 | |
1945 | |
1946 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 1785 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
1947 // Load the arguments. | 1786 // Load the arguments. |
1948 ZoneList<Expression*>* args = expr->arguments(); | 1787 ZoneList<Expression*>* args = expr->arguments(); |
1949 int arg_count = args->length(); | 1788 int arg_count = args->length(); |
1950 for (int i = 0; i < arg_count; i++) { | 1789 for (int i = 0; i < arg_count; i++) { |
1951 VisitForStackValue(args->at(i)); | 1790 VisitForStackValue(args->at(i)); |
1952 } | 1791 } |
1953 | 1792 |
1954 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1793 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); |
1955 SetCallPosition(expr, expr->tail_call_mode()); | 1794 SetCallPosition(expr, expr->tail_call_mode()); |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2466 } | 2305 } |
2467 switch (assign_type) { | 2306 switch (assign_type) { |
2468 case NAMED_PROPERTY: { | 2307 case NAMED_PROPERTY: { |
2469 // Put the object both on the stack and in the register. | 2308 // Put the object both on the stack and in the register. |
2470 VisitForStackValue(prop->obj()); | 2309 VisitForStackValue(prop->obj()); |
2471 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); | 2310 __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); |
2472 EmitNamedPropertyLoad(prop); | 2311 EmitNamedPropertyLoad(prop); |
2473 break; | 2312 break; |
2474 } | 2313 } |
2475 | 2314 |
2476 case NAMED_SUPER_PROPERTY: { | |
2477 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
2478 VisitForAccumulatorValue( | |
2479 prop->obj()->AsSuperPropertyReference()->home_object()); | |
2480 PushOperand(result_register()); | |
2481 PushOperand(MemOperand(esp, kPointerSize)); | |
2482 PushOperand(result_register()); | |
2483 EmitNamedSuperPropertyLoad(prop); | |
2484 break; | |
2485 } | |
2486 | |
2487 case KEYED_SUPER_PROPERTY: { | |
2488 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
2489 VisitForStackValue( | |
2490 prop->obj()->AsSuperPropertyReference()->home_object()); | |
2491 VisitForAccumulatorValue(prop->key()); | |
2492 PushOperand(result_register()); | |
2493 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
2494 PushOperand(MemOperand(esp, 2 * kPointerSize)); | |
2495 PushOperand(result_register()); | |
2496 EmitKeyedSuperPropertyLoad(prop); | |
2497 break; | |
2498 } | |
2499 | |
2500 case KEYED_PROPERTY: { | 2315 case KEYED_PROPERTY: { |
2501 VisitForStackValue(prop->obj()); | 2316 VisitForStackValue(prop->obj()); |
2502 VisitForStackValue(prop->key()); | 2317 VisitForStackValue(prop->key()); |
2503 __ mov(LoadDescriptor::ReceiverRegister(), | 2318 __ mov(LoadDescriptor::ReceiverRegister(), |
2504 Operand(esp, kPointerSize)); // Object. | 2319 Operand(esp, kPointerSize)); // Object. |
2505 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. | 2320 __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. |
2506 EmitKeyedPropertyLoad(prop); | 2321 EmitKeyedPropertyLoad(prop); |
2507 break; | 2322 break; |
2508 } | 2323 } |
2509 | 2324 |
| 2325 case NAMED_SUPER_PROPERTY: |
| 2326 case KEYED_SUPER_PROPERTY: |
2510 case VARIABLE: | 2327 case VARIABLE: |
2511 UNREACHABLE(); | 2328 UNREACHABLE(); |
2512 } | 2329 } |
2513 } | 2330 } |
2514 | 2331 |
2515 // We need a second deoptimization point after loading the value | 2332 // We need a second deoptimization point after loading the value |
2516 // in case evaluating the property load my have a side effect. | 2333 // in case evaluating the property load my have a side effect. |
2517 if (assign_type == VARIABLE) { | 2334 if (assign_type == VARIABLE) { |
2518 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); | 2335 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); |
2519 } else { | 2336 } else { |
(...skipping 13 matching lines...) Expand all Loading... |
2533 // Save the result on the stack. If we have a named or keyed property | 2350 // Save the result on the stack. If we have a named or keyed property |
2534 // we store the result under the receiver that is currently on top | 2351 // we store the result under the receiver that is currently on top |
2535 // of the stack. | 2352 // of the stack. |
2536 switch (assign_type) { | 2353 switch (assign_type) { |
2537 case VARIABLE: | 2354 case VARIABLE: |
2538 __ push(eax); | 2355 __ push(eax); |
2539 break; | 2356 break; |
2540 case NAMED_PROPERTY: | 2357 case NAMED_PROPERTY: |
2541 __ mov(Operand(esp, kPointerSize), eax); | 2358 __ mov(Operand(esp, kPointerSize), eax); |
2542 break; | 2359 break; |
2543 case NAMED_SUPER_PROPERTY: | |
2544 __ mov(Operand(esp, 2 * kPointerSize), eax); | |
2545 break; | |
2546 case KEYED_PROPERTY: | 2360 case KEYED_PROPERTY: |
2547 __ mov(Operand(esp, 2 * kPointerSize), eax); | 2361 __ mov(Operand(esp, 2 * kPointerSize), eax); |
2548 break; | 2362 break; |
| 2363 case NAMED_SUPER_PROPERTY: |
2549 case KEYED_SUPER_PROPERTY: | 2364 case KEYED_SUPER_PROPERTY: |
2550 __ mov(Operand(esp, 3 * kPointerSize), eax); | 2365 UNREACHABLE(); |
2551 break; | 2366 break; |
2552 } | 2367 } |
2553 } | 2368 } |
2554 } | 2369 } |
2555 | 2370 |
2556 if (expr->op() == Token::INC) { | 2371 if (expr->op() == Token::INC) { |
2557 __ add(eax, Immediate(Smi::FromInt(1))); | 2372 __ add(eax, Immediate(Smi::FromInt(1))); |
2558 } else { | 2373 } else { |
2559 __ sub(eax, Immediate(Smi::FromInt(1))); | 2374 __ sub(eax, Immediate(Smi::FromInt(1))); |
2560 } | 2375 } |
(...skipping 19 matching lines...) Expand all Loading... |
2580 // Save the result on the stack. If we have a named or keyed property | 2395 // Save the result on the stack. If we have a named or keyed property |
2581 // we store the result under the receiver that is currently on top | 2396 // we store the result under the receiver that is currently on top |
2582 // of the stack. | 2397 // of the stack. |
2583 switch (assign_type) { | 2398 switch (assign_type) { |
2584 case VARIABLE: | 2399 case VARIABLE: |
2585 PushOperand(eax); | 2400 PushOperand(eax); |
2586 break; | 2401 break; |
2587 case NAMED_PROPERTY: | 2402 case NAMED_PROPERTY: |
2588 __ mov(Operand(esp, kPointerSize), eax); | 2403 __ mov(Operand(esp, kPointerSize), eax); |
2589 break; | 2404 break; |
2590 case NAMED_SUPER_PROPERTY: | |
2591 __ mov(Operand(esp, 2 * kPointerSize), eax); | |
2592 break; | |
2593 case KEYED_PROPERTY: | 2405 case KEYED_PROPERTY: |
2594 __ mov(Operand(esp, 2 * kPointerSize), eax); | 2406 __ mov(Operand(esp, 2 * kPointerSize), eax); |
2595 break; | 2407 break; |
| 2408 case NAMED_SUPER_PROPERTY: |
2596 case KEYED_SUPER_PROPERTY: | 2409 case KEYED_SUPER_PROPERTY: |
2597 __ mov(Operand(esp, 3 * kPointerSize), eax); | 2410 UNREACHABLE(); |
2598 break; | 2411 break; |
2599 } | 2412 } |
2600 } | 2413 } |
2601 } | 2414 } |
2602 | 2415 |
2603 SetExpressionPosition(expr); | 2416 SetExpressionPosition(expr); |
2604 | 2417 |
2605 // Call stub for +1/-1. | 2418 // Call stub for +1/-1. |
2606 __ bind(&stub_call); | 2419 __ bind(&stub_call); |
2607 __ mov(edx, eax); | 2420 __ mov(edx, eax); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2646 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2459 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2647 if (expr->is_postfix()) { | 2460 if (expr->is_postfix()) { |
2648 if (!context()->IsEffect()) { | 2461 if (!context()->IsEffect()) { |
2649 context()->PlugTOS(); | 2462 context()->PlugTOS(); |
2650 } | 2463 } |
2651 } else { | 2464 } else { |
2652 context()->Plug(eax); | 2465 context()->Plug(eax); |
2653 } | 2466 } |
2654 break; | 2467 break; |
2655 } | 2468 } |
2656 case NAMED_SUPER_PROPERTY: { | |
2657 EmitNamedSuperPropertyStore(prop); | |
2658 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
2659 if (expr->is_postfix()) { | |
2660 if (!context()->IsEffect()) { | |
2661 context()->PlugTOS(); | |
2662 } | |
2663 } else { | |
2664 context()->Plug(eax); | |
2665 } | |
2666 break; | |
2667 } | |
2668 case KEYED_SUPER_PROPERTY: { | |
2669 EmitKeyedSuperPropertyStore(prop); | |
2670 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
2671 if (expr->is_postfix()) { | |
2672 if (!context()->IsEffect()) { | |
2673 context()->PlugTOS(); | |
2674 } | |
2675 } else { | |
2676 context()->Plug(eax); | |
2677 } | |
2678 break; | |
2679 } | |
2680 case KEYED_PROPERTY: { | 2469 case KEYED_PROPERTY: { |
2681 PopOperand(StoreDescriptor::NameRegister()); | 2470 PopOperand(StoreDescriptor::NameRegister()); |
2682 PopOperand(StoreDescriptor::ReceiverRegister()); | 2471 PopOperand(StoreDescriptor::ReceiverRegister()); |
2683 CallKeyedStoreIC(expr->CountSlot()); | 2472 CallKeyedStoreIC(expr->CountSlot()); |
2684 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2473 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2685 if (expr->is_postfix()) { | 2474 if (expr->is_postfix()) { |
2686 // Result is on the stack | 2475 // Result is on the stack |
2687 if (!context()->IsEffect()) { | 2476 if (!context()->IsEffect()) { |
2688 context()->PlugTOS(); | 2477 context()->PlugTOS(); |
2689 } | 2478 } |
2690 } else { | 2479 } else { |
2691 context()->Plug(eax); | 2480 context()->Plug(eax); |
2692 } | 2481 } |
2693 break; | 2482 break; |
2694 } | 2483 } |
| 2484 case NAMED_SUPER_PROPERTY: |
| 2485 case KEYED_SUPER_PROPERTY: |
| 2486 UNREACHABLE(); |
| 2487 break; |
2695 } | 2488 } |
2696 } | 2489 } |
2697 | 2490 |
2698 | 2491 |
2699 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 2492 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
2700 Expression* sub_expr, | 2493 Expression* sub_expr, |
2701 Handle<String> check) { | 2494 Handle<String> check) { |
2702 Label materialize_true, materialize_false; | 2495 Label materialize_true, materialize_false; |
2703 Label* if_true = NULL; | 2496 Label* if_true = NULL; |
2704 Label* if_false = NULL; | 2497 Label* if_false = NULL; |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2995 isolate->builtins()->OnStackReplacement()->entry(), | 2788 isolate->builtins()->OnStackReplacement()->entry(), |
2996 Assembler::target_address_at(call_target_address, unoptimized_code)); | 2789 Assembler::target_address_at(call_target_address, unoptimized_code)); |
2997 return ON_STACK_REPLACEMENT; | 2790 return ON_STACK_REPLACEMENT; |
2998 } | 2791 } |
2999 | 2792 |
3000 | 2793 |
3001 } // namespace internal | 2794 } // namespace internal |
3002 } // namespace v8 | 2795 } // namespace v8 |
3003 | 2796 |
3004 #endif // V8_TARGET_ARCH_IA32 | 2797 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |