| 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_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 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 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 break; | 1411 break; |
| 1412 case NAMED_PROPERTY: | 1412 case NAMED_PROPERTY: |
| 1413 if (expr->is_compound()) { | 1413 if (expr->is_compound()) { |
| 1414 // We need the receiver both on the stack and in the register. | 1414 // We need the receiver both on the stack and in the register. |
| 1415 VisitForStackValue(property->obj()); | 1415 VisitForStackValue(property->obj()); |
| 1416 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1416 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 1417 } else { | 1417 } else { |
| 1418 VisitForStackValue(property->obj()); | 1418 VisitForStackValue(property->obj()); |
| 1419 } | 1419 } |
| 1420 break; | 1420 break; |
| 1421 case NAMED_SUPER_PROPERTY: | |
| 1422 VisitForStackValue( | |
| 1423 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1424 VisitForAccumulatorValue( | |
| 1425 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1426 PushOperand(result_register()); | |
| 1427 if (expr->is_compound()) { | |
| 1428 const Register scratch = r1; | |
| 1429 __ ldr(scratch, MemOperand(sp, kPointerSize)); | |
| 1430 PushOperand(scratch); | |
| 1431 PushOperand(result_register()); | |
| 1432 } | |
| 1433 break; | |
| 1434 case KEYED_SUPER_PROPERTY: | |
| 1435 VisitForStackValue( | |
| 1436 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1437 VisitForStackValue( | |
| 1438 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1439 VisitForAccumulatorValue(property->key()); | |
| 1440 PushOperand(result_register()); | |
| 1441 if (expr->is_compound()) { | |
| 1442 const Register scratch = r1; | |
| 1443 __ ldr(scratch, MemOperand(sp, 2 * kPointerSize)); | |
| 1444 PushOperand(scratch); | |
| 1445 __ ldr(scratch, MemOperand(sp, 2 * kPointerSize)); | |
| 1446 PushOperand(scratch); | |
| 1447 PushOperand(result_register()); | |
| 1448 } | |
| 1449 break; | |
| 1450 case KEYED_PROPERTY: | 1421 case KEYED_PROPERTY: |
| 1451 if (expr->is_compound()) { | 1422 if (expr->is_compound()) { |
| 1452 VisitForStackValue(property->obj()); | 1423 VisitForStackValue(property->obj()); |
| 1453 VisitForStackValue(property->key()); | 1424 VisitForStackValue(property->key()); |
| 1454 __ ldr(LoadDescriptor::ReceiverRegister(), | 1425 __ ldr(LoadDescriptor::ReceiverRegister(), |
| 1455 MemOperand(sp, 1 * kPointerSize)); | 1426 MemOperand(sp, 1 * kPointerSize)); |
| 1456 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 1427 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| 1457 } else { | 1428 } else { |
| 1458 VisitForStackValue(property->obj()); | 1429 VisitForStackValue(property->obj()); |
| 1459 VisitForStackValue(property->key()); | 1430 VisitForStackValue(property->key()); |
| 1460 } | 1431 } |
| 1461 break; | 1432 break; |
| 1433 case NAMED_SUPER_PROPERTY: |
| 1434 case KEYED_SUPER_PROPERTY: |
| 1435 UNREACHABLE(); |
| 1436 break; |
| 1462 } | 1437 } |
| 1463 | 1438 |
| 1464 // For compound assignments we need another deoptimization point after the | 1439 // For compound assignments we need another deoptimization point after the |
| 1465 // variable/property load. | 1440 // variable/property load. |
| 1466 if (expr->is_compound()) { | 1441 if (expr->is_compound()) { |
| 1467 { AccumulatorValueContext context(this); | 1442 { AccumulatorValueContext context(this); |
| 1468 switch (assign_type) { | 1443 switch (assign_type) { |
| 1469 case VARIABLE: | 1444 case VARIABLE: |
| 1470 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1445 EmitVariableLoad(expr->target()->AsVariableProxy()); |
| 1471 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); | 1446 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); |
| 1472 break; | 1447 break; |
| 1473 case NAMED_PROPERTY: | 1448 case NAMED_PROPERTY: |
| 1474 EmitNamedPropertyLoad(property); | 1449 EmitNamedPropertyLoad(property); |
| 1475 PrepareForBailoutForId(property->LoadId(), | 1450 PrepareForBailoutForId(property->LoadId(), |
| 1476 BailoutState::TOS_REGISTER); | 1451 BailoutState::TOS_REGISTER); |
| 1477 break; | 1452 break; |
| 1478 case NAMED_SUPER_PROPERTY: | |
| 1479 EmitNamedSuperPropertyLoad(property); | |
| 1480 PrepareForBailoutForId(property->LoadId(), | |
| 1481 BailoutState::TOS_REGISTER); | |
| 1482 break; | |
| 1483 case KEYED_SUPER_PROPERTY: | |
| 1484 EmitKeyedSuperPropertyLoad(property); | |
| 1485 PrepareForBailoutForId(property->LoadId(), | |
| 1486 BailoutState::TOS_REGISTER); | |
| 1487 break; | |
| 1488 case KEYED_PROPERTY: | 1453 case KEYED_PROPERTY: |
| 1489 EmitKeyedPropertyLoad(property); | 1454 EmitKeyedPropertyLoad(property); |
| 1490 PrepareForBailoutForId(property->LoadId(), | 1455 PrepareForBailoutForId(property->LoadId(), |
| 1491 BailoutState::TOS_REGISTER); | 1456 BailoutState::TOS_REGISTER); |
| 1492 break; | 1457 break; |
| 1458 case NAMED_SUPER_PROPERTY: |
| 1459 case KEYED_SUPER_PROPERTY: |
| 1460 UNREACHABLE(); |
| 1461 break; |
| 1493 } | 1462 } |
| 1494 } | 1463 } |
| 1495 | 1464 |
| 1496 Token::Value op = expr->binary_op(); | 1465 Token::Value op = expr->binary_op(); |
| 1497 PushOperand(r0); // Left operand goes on the stack. | 1466 PushOperand(r0); // Left operand goes on the stack. |
| 1498 VisitForAccumulatorValue(expr->value()); | 1467 VisitForAccumulatorValue(expr->value()); |
| 1499 | 1468 |
| 1500 AccumulatorValueContext context(this); | 1469 AccumulatorValueContext context(this); |
| 1501 if (ShouldInlineSmiCase(op)) { | 1470 if (ShouldInlineSmiCase(op)) { |
| 1502 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1471 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1521 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1490 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1522 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1491 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
| 1523 proxy->hole_check_mode()); | 1492 proxy->hole_check_mode()); |
| 1524 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1493 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1525 context()->Plug(r0); | 1494 context()->Plug(r0); |
| 1526 break; | 1495 break; |
| 1527 } | 1496 } |
| 1528 case NAMED_PROPERTY: | 1497 case NAMED_PROPERTY: |
| 1529 EmitNamedPropertyAssignment(expr); | 1498 EmitNamedPropertyAssignment(expr); |
| 1530 break; | 1499 break; |
| 1531 case NAMED_SUPER_PROPERTY: | |
| 1532 EmitNamedSuperPropertyStore(property); | |
| 1533 context()->Plug(r0); | |
| 1534 break; | |
| 1535 case KEYED_SUPER_PROPERTY: | |
| 1536 EmitKeyedSuperPropertyStore(property); | |
| 1537 context()->Plug(r0); | |
| 1538 break; | |
| 1539 case KEYED_PROPERTY: | 1500 case KEYED_PROPERTY: |
| 1540 EmitKeyedPropertyAssignment(expr); | 1501 EmitKeyedPropertyAssignment(expr); |
| 1541 break; | 1502 break; |
| 1503 case NAMED_SUPER_PROPERTY: |
| 1504 case KEYED_SUPER_PROPERTY: |
| 1505 UNREACHABLE(); |
| 1506 break; |
| 1542 } | 1507 } |
| 1543 } | 1508 } |
| 1544 | 1509 |
| 1545 | 1510 |
| 1546 void FullCodeGenerator::VisitYield(Yield* expr) { | 1511 void FullCodeGenerator::VisitYield(Yield* expr) { |
| 1547 // Resumable functions are not supported. | 1512 // Resumable functions are not supported. |
| 1548 UNREACHABLE(); | 1513 UNREACHABLE(); |
| 1549 } | 1514 } |
| 1550 | 1515 |
| 1551 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 1516 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 break; | 1676 break; |
| 1712 } | 1677 } |
| 1713 case NAMED_PROPERTY: { | 1678 case NAMED_PROPERTY: { |
| 1714 PushOperand(r0); // Preserve value. | 1679 PushOperand(r0); // Preserve value. |
| 1715 VisitForAccumulatorValue(prop->obj()); | 1680 VisitForAccumulatorValue(prop->obj()); |
| 1716 __ Move(StoreDescriptor::ReceiverRegister(), r0); | 1681 __ Move(StoreDescriptor::ReceiverRegister(), r0); |
| 1717 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1682 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1718 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1683 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
| 1719 break; | 1684 break; |
| 1720 } | 1685 } |
| 1721 case NAMED_SUPER_PROPERTY: { | |
| 1722 PushOperand(r0); | |
| 1723 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1724 VisitForAccumulatorValue( | |
| 1725 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1726 // stack: value, this; r0: home_object | |
| 1727 Register scratch = r2; | |
| 1728 Register scratch2 = r3; | |
| 1729 __ mov(scratch, result_register()); // home_object | |
| 1730 __ ldr(r0, MemOperand(sp, kPointerSize)); // value | |
| 1731 __ ldr(scratch2, MemOperand(sp, 0)); // this | |
| 1732 __ str(scratch2, MemOperand(sp, kPointerSize)); // this | |
| 1733 __ str(scratch, MemOperand(sp, 0)); // home_object | |
| 1734 // stack: this, home_object; r0: value | |
| 1735 EmitNamedSuperPropertyStore(prop); | |
| 1736 break; | |
| 1737 } | |
| 1738 case KEYED_SUPER_PROPERTY: { | |
| 1739 PushOperand(r0); | |
| 1740 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1741 VisitForStackValue( | |
| 1742 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1743 VisitForAccumulatorValue(prop->key()); | |
| 1744 Register scratch = r2; | |
| 1745 Register scratch2 = r3; | |
| 1746 __ ldr(scratch2, MemOperand(sp, 2 * kPointerSize)); // value | |
| 1747 // stack: value, this, home_object; r0: key, r3: value | |
| 1748 __ ldr(scratch, MemOperand(sp, kPointerSize)); // this | |
| 1749 __ str(scratch, MemOperand(sp, 2 * kPointerSize)); | |
| 1750 __ ldr(scratch, MemOperand(sp, 0)); // home_object | |
| 1751 __ str(scratch, MemOperand(sp, kPointerSize)); | |
| 1752 __ str(r0, MemOperand(sp, 0)); | |
| 1753 __ Move(r0, scratch2); | |
| 1754 // stack: this, home_object, key; r0: value. | |
| 1755 EmitKeyedSuperPropertyStore(prop); | |
| 1756 break; | |
| 1757 } | |
| 1758 case KEYED_PROPERTY: { | 1686 case KEYED_PROPERTY: { |
| 1759 PushOperand(r0); // Preserve value. | 1687 PushOperand(r0); // Preserve value. |
| 1760 VisitForStackValue(prop->obj()); | 1688 VisitForStackValue(prop->obj()); |
| 1761 VisitForAccumulatorValue(prop->key()); | 1689 VisitForAccumulatorValue(prop->key()); |
| 1762 __ Move(StoreDescriptor::NameRegister(), r0); | 1690 __ Move(StoreDescriptor::NameRegister(), r0); |
| 1763 PopOperands(StoreDescriptor::ValueRegister(), | 1691 PopOperands(StoreDescriptor::ValueRegister(), |
| 1764 StoreDescriptor::ReceiverRegister()); | 1692 StoreDescriptor::ReceiverRegister()); |
| 1765 CallKeyedStoreIC(slot); | 1693 CallKeyedStoreIC(slot); |
| 1766 break; | 1694 break; |
| 1767 } | 1695 } |
| 1696 case NAMED_SUPER_PROPERTY: |
| 1697 case KEYED_SUPER_PROPERTY: |
| 1698 UNREACHABLE(); |
| 1699 break; |
| 1768 } | 1700 } |
| 1769 context()->Plug(r0); | 1701 context()->Plug(r0); |
| 1770 } | 1702 } |
| 1771 | 1703 |
| 1772 | 1704 |
| 1773 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 1705 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 1774 Variable* var, MemOperand location) { | 1706 Variable* var, MemOperand location) { |
| 1775 __ str(result_register(), location); | 1707 __ str(result_register(), location); |
| 1776 if (var->IsContextSlot()) { | 1708 if (var->IsContextSlot()) { |
| 1777 // RecordWrite may destroy all its register arguments. | 1709 // RecordWrite may destroy all its register arguments. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 DCHECK(prop->key()->IsLiteral()); | 1781 DCHECK(prop->key()->IsLiteral()); |
| 1850 | 1782 |
| 1851 PopOperand(StoreDescriptor::ReceiverRegister()); | 1783 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1852 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 1784 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); |
| 1853 | 1785 |
| 1854 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1786 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1855 context()->Plug(r0); | 1787 context()->Plug(r0); |
| 1856 } | 1788 } |
| 1857 | 1789 |
| 1858 | 1790 |
| 1859 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | |
| 1860 // Assignment to named property of super. | |
| 1861 // r0 : value | |
| 1862 // stack : receiver ('this'), home_object | |
| 1863 DCHECK(prop != NULL); | |
| 1864 Literal* key = prop->key()->AsLiteral(); | |
| 1865 DCHECK(key != NULL); | |
| 1866 | |
| 1867 PushOperand(key->value()); | |
| 1868 PushOperand(r0); | |
| 1869 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1870 ? Runtime::kStoreToSuper_Strict | |
| 1871 : Runtime::kStoreToSuper_Sloppy); | |
| 1872 } | |
| 1873 | |
| 1874 | |
| 1875 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | |
| 1876 // Assignment to named property of super. | |
| 1877 // r0 : value | |
| 1878 // stack : receiver ('this'), home_object, key | |
| 1879 DCHECK(prop != NULL); | |
| 1880 | |
| 1881 PushOperand(r0); | |
| 1882 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1883 ? Runtime::kStoreKeyedToSuper_Strict | |
| 1884 : Runtime::kStoreKeyedToSuper_Sloppy); | |
| 1885 } | |
| 1886 | |
| 1887 | |
| 1888 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1791 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 1889 // Assignment to a property, using a keyed store IC. | 1792 // Assignment to a property, using a keyed store IC. |
| 1890 PopOperands(StoreDescriptor::ReceiverRegister(), | 1793 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 1891 StoreDescriptor::NameRegister()); | 1794 StoreDescriptor::NameRegister()); |
| 1892 DCHECK(StoreDescriptor::ValueRegister().is(r0)); | 1795 DCHECK(StoreDescriptor::ValueRegister().is(r0)); |
| 1893 | 1796 |
| 1894 CallKeyedStoreIC(expr->AssignmentSlot()); | 1797 CallKeyedStoreIC(expr->AssignmentSlot()); |
| 1895 | 1798 |
| 1896 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1799 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1897 context()->Plug(r0); | 1800 context()->Plug(r0); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1925 __ ldr(ip, MemOperand(sp, 0)); | 1828 __ ldr(ip, MemOperand(sp, 0)); |
| 1926 PushOperand(ip); | 1829 PushOperand(ip); |
| 1927 __ str(r0, MemOperand(sp, kPointerSize)); | 1830 __ str(r0, MemOperand(sp, kPointerSize)); |
| 1928 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 1831 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 1929 } | 1832 } |
| 1930 | 1833 |
| 1931 EmitCall(expr, convert_mode); | 1834 EmitCall(expr, convert_mode); |
| 1932 } | 1835 } |
| 1933 | 1836 |
| 1934 | 1837 |
| 1935 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | |
| 1936 Expression* callee = expr->expression(); | |
| 1937 DCHECK(callee->IsProperty()); | |
| 1938 Property* prop = callee->AsProperty(); | |
| 1939 DCHECK(prop->IsSuperAccess()); | |
| 1940 SetExpressionPosition(prop); | |
| 1941 | |
| 1942 Literal* key = prop->key()->AsLiteral(); | |
| 1943 DCHECK(!key->value()->IsSmi()); | |
| 1944 // Load the function from the receiver. | |
| 1945 const Register scratch = r1; | |
| 1946 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 1947 VisitForStackValue(super_ref->home_object()); | |
| 1948 VisitForAccumulatorValue(super_ref->this_var()); | |
| 1949 PushOperand(r0); | |
| 1950 PushOperand(r0); | |
| 1951 __ ldr(scratch, MemOperand(sp, kPointerSize * 2)); | |
| 1952 PushOperand(scratch); | |
| 1953 PushOperand(key->value()); | |
| 1954 | |
| 1955 // Stack here: | |
| 1956 // - home_object | |
| 1957 // - this (receiver) | |
| 1958 // - this (receiver) <-- LoadFromSuper will pop here and below. | |
| 1959 // - home_object | |
| 1960 // - key | |
| 1961 CallRuntimeWithOperands(Runtime::kLoadFromSuper); | |
| 1962 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 1963 | |
| 1964 // Replace home_object with target function. | |
| 1965 __ str(r0, MemOperand(sp, kPointerSize)); | |
| 1966 | |
| 1967 // Stack here: | |
| 1968 // - target function | |
| 1969 // - this (receiver) | |
| 1970 EmitCall(expr); | |
| 1971 } | |
| 1972 | |
| 1973 | |
| 1974 // Code common for calls using the IC. | 1838 // Code common for calls using the IC. |
| 1975 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 1839 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 1976 Expression* key) { | 1840 Expression* key) { |
| 1977 // Load the key. | 1841 // Load the key. |
| 1978 VisitForAccumulatorValue(key); | 1842 VisitForAccumulatorValue(key); |
| 1979 | 1843 |
| 1980 Expression* callee = expr->expression(); | 1844 Expression* callee = expr->expression(); |
| 1981 | 1845 |
| 1982 // Load the function from the receiver. | 1846 // Load the function from the receiver. |
| 1983 DCHECK(callee->IsProperty()); | 1847 DCHECK(callee->IsProperty()); |
| 1984 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1848 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 1985 __ Move(LoadDescriptor::NameRegister(), r0); | 1849 __ Move(LoadDescriptor::NameRegister(), r0); |
| 1986 EmitKeyedPropertyLoad(callee->AsProperty()); | 1850 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 1987 PrepareForBailoutForId(callee->AsProperty()->LoadId(), | 1851 PrepareForBailoutForId(callee->AsProperty()->LoadId(), |
| 1988 BailoutState::TOS_REGISTER); | 1852 BailoutState::TOS_REGISTER); |
| 1989 | 1853 |
| 1990 // Push the target function under the receiver. | 1854 // Push the target function under the receiver. |
| 1991 __ ldr(ip, MemOperand(sp, 0)); | 1855 __ ldr(ip, MemOperand(sp, 0)); |
| 1992 PushOperand(ip); | 1856 PushOperand(ip); |
| 1993 __ str(r0, MemOperand(sp, kPointerSize)); | 1857 __ str(r0, MemOperand(sp, kPointerSize)); |
| 1994 | 1858 |
| 1995 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 1859 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
| 1996 } | 1860 } |
| 1997 | 1861 |
| 1998 | 1862 |
| 1999 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | |
| 2000 Expression* callee = expr->expression(); | |
| 2001 DCHECK(callee->IsProperty()); | |
| 2002 Property* prop = callee->AsProperty(); | |
| 2003 DCHECK(prop->IsSuperAccess()); | |
| 2004 | |
| 2005 SetExpressionPosition(prop); | |
| 2006 // Load the function from the receiver. | |
| 2007 const Register scratch = r1; | |
| 2008 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 2009 VisitForStackValue(super_ref->home_object()); | |
| 2010 VisitForAccumulatorValue(super_ref->this_var()); | |
| 2011 PushOperand(r0); | |
| 2012 PushOperand(r0); | |
| 2013 __ ldr(scratch, MemOperand(sp, kPointerSize * 2)); | |
| 2014 PushOperand(scratch); | |
| 2015 VisitForStackValue(prop->key()); | |
| 2016 | |
| 2017 // Stack here: | |
| 2018 // - home_object | |
| 2019 // - this (receiver) | |
| 2020 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | |
| 2021 // - home_object | |
| 2022 // - key | |
| 2023 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | |
| 2024 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 2025 | |
| 2026 // Replace home_object with target function. | |
| 2027 __ str(r0, MemOperand(sp, kPointerSize)); | |
| 2028 | |
| 2029 // Stack here: | |
| 2030 // - target function | |
| 2031 // - this (receiver) | |
| 2032 EmitCall(expr); | |
| 2033 } | |
| 2034 | |
| 2035 | |
| 2036 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 1863 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
| 2037 // Load the arguments. | 1864 // Load the arguments. |
| 2038 ZoneList<Expression*>* args = expr->arguments(); | 1865 ZoneList<Expression*>* args = expr->arguments(); |
| 2039 int arg_count = args->length(); | 1866 int arg_count = args->length(); |
| 2040 for (int i = 0; i < arg_count; i++) { | 1867 for (int i = 0; i < arg_count; i++) { |
| 2041 VisitForStackValue(args->at(i)); | 1868 VisitForStackValue(args->at(i)); |
| 2042 } | 1869 } |
| 2043 | 1870 |
| 2044 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1871 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); |
| 2045 SetCallPosition(expr, expr->tail_call_mode()); | 1872 SetCallPosition(expr, expr->tail_call_mode()); |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2553 } | 2380 } |
| 2554 switch (assign_type) { | 2381 switch (assign_type) { |
| 2555 case NAMED_PROPERTY: { | 2382 case NAMED_PROPERTY: { |
| 2556 // Put the object both on the stack and in the register. | 2383 // Put the object both on the stack and in the register. |
| 2557 VisitForStackValue(prop->obj()); | 2384 VisitForStackValue(prop->obj()); |
| 2558 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2385 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 2559 EmitNamedPropertyLoad(prop); | 2386 EmitNamedPropertyLoad(prop); |
| 2560 break; | 2387 break; |
| 2561 } | 2388 } |
| 2562 | 2389 |
| 2563 case NAMED_SUPER_PROPERTY: { | |
| 2564 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2565 VisitForAccumulatorValue( | |
| 2566 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2567 PushOperand(result_register()); | |
| 2568 const Register scratch = r1; | |
| 2569 __ ldr(scratch, MemOperand(sp, kPointerSize)); | |
| 2570 PushOperand(scratch); | |
| 2571 PushOperand(result_register()); | |
| 2572 EmitNamedSuperPropertyLoad(prop); | |
| 2573 break; | |
| 2574 } | |
| 2575 | |
| 2576 case KEYED_SUPER_PROPERTY: { | |
| 2577 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2578 VisitForStackValue( | |
| 2579 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2580 VisitForAccumulatorValue(prop->key()); | |
| 2581 PushOperand(result_register()); | |
| 2582 const Register scratch = r1; | |
| 2583 __ ldr(scratch, MemOperand(sp, 2 * kPointerSize)); | |
| 2584 PushOperand(scratch); | |
| 2585 __ ldr(scratch, MemOperand(sp, 2 * kPointerSize)); | |
| 2586 PushOperand(scratch); | |
| 2587 PushOperand(result_register()); | |
| 2588 EmitKeyedSuperPropertyLoad(prop); | |
| 2589 break; | |
| 2590 } | |
| 2591 | |
| 2592 case KEYED_PROPERTY: { | 2390 case KEYED_PROPERTY: { |
| 2593 VisitForStackValue(prop->obj()); | 2391 VisitForStackValue(prop->obj()); |
| 2594 VisitForStackValue(prop->key()); | 2392 VisitForStackValue(prop->key()); |
| 2595 __ ldr(LoadDescriptor::ReceiverRegister(), | 2393 __ ldr(LoadDescriptor::ReceiverRegister(), |
| 2596 MemOperand(sp, 1 * kPointerSize)); | 2394 MemOperand(sp, 1 * kPointerSize)); |
| 2597 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 2395 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| 2598 EmitKeyedPropertyLoad(prop); | 2396 EmitKeyedPropertyLoad(prop); |
| 2599 break; | 2397 break; |
| 2600 } | 2398 } |
| 2601 | 2399 |
| 2400 case NAMED_SUPER_PROPERTY: |
| 2401 case KEYED_SUPER_PROPERTY: |
| 2602 case VARIABLE: | 2402 case VARIABLE: |
| 2603 UNREACHABLE(); | 2403 UNREACHABLE(); |
| 2604 } | 2404 } |
| 2605 } | 2405 } |
| 2606 | 2406 |
| 2607 // We need a second deoptimization point after loading the value | 2407 // We need a second deoptimization point after loading the value |
| 2608 // in case evaluating the property load my have a side effect. | 2408 // in case evaluating the property load my have a side effect. |
| 2609 if (assign_type == VARIABLE) { | 2409 if (assign_type == VARIABLE) { |
| 2610 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); | 2410 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); |
| 2611 } else { | 2411 } else { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2627 // Save the result on the stack. If we have a named or keyed property | 2427 // Save the result on the stack. If we have a named or keyed property |
| 2628 // we store the result under the receiver that is currently on top | 2428 // we store the result under the receiver that is currently on top |
| 2629 // of the stack. | 2429 // of the stack. |
| 2630 switch (assign_type) { | 2430 switch (assign_type) { |
| 2631 case VARIABLE: | 2431 case VARIABLE: |
| 2632 __ push(r0); | 2432 __ push(r0); |
| 2633 break; | 2433 break; |
| 2634 case NAMED_PROPERTY: | 2434 case NAMED_PROPERTY: |
| 2635 __ str(r0, MemOperand(sp, kPointerSize)); | 2435 __ str(r0, MemOperand(sp, kPointerSize)); |
| 2636 break; | 2436 break; |
| 2637 case NAMED_SUPER_PROPERTY: | |
| 2638 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | |
| 2639 break; | |
| 2640 case KEYED_PROPERTY: | 2437 case KEYED_PROPERTY: |
| 2641 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | 2438 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
| 2642 break; | 2439 break; |
| 2440 case NAMED_SUPER_PROPERTY: |
| 2643 case KEYED_SUPER_PROPERTY: | 2441 case KEYED_SUPER_PROPERTY: |
| 2644 __ str(r0, MemOperand(sp, 3 * kPointerSize)); | 2442 UNREACHABLE(); |
| 2645 break; | 2443 break; |
| 2646 } | 2444 } |
| 2647 } | 2445 } |
| 2648 } | 2446 } |
| 2649 | 2447 |
| 2650 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); | 2448 __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC); |
| 2651 __ b(vc, &done); | 2449 __ b(vc, &done); |
| 2652 // Call stub. Undo operation first. | 2450 // Call stub. Undo operation first. |
| 2653 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); | 2451 __ sub(r0, r0, Operand(Smi::FromInt(count_value))); |
| 2654 __ jmp(&stub_call); | 2452 __ jmp(&stub_call); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2666 // Save the result on the stack. If we have a named or keyed property | 2464 // Save the result on the stack. If we have a named or keyed property |
| 2667 // we store the result under the receiver that is currently on top | 2465 // we store the result under the receiver that is currently on top |
| 2668 // of the stack. | 2466 // of the stack. |
| 2669 switch (assign_type) { | 2467 switch (assign_type) { |
| 2670 case VARIABLE: | 2468 case VARIABLE: |
| 2671 PushOperand(r0); | 2469 PushOperand(r0); |
| 2672 break; | 2470 break; |
| 2673 case NAMED_PROPERTY: | 2471 case NAMED_PROPERTY: |
| 2674 __ str(r0, MemOperand(sp, kPointerSize)); | 2472 __ str(r0, MemOperand(sp, kPointerSize)); |
| 2675 break; | 2473 break; |
| 2676 case NAMED_SUPER_PROPERTY: | |
| 2677 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | |
| 2678 break; | |
| 2679 case KEYED_PROPERTY: | 2474 case KEYED_PROPERTY: |
| 2680 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | 2475 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
| 2681 break; | 2476 break; |
| 2477 case NAMED_SUPER_PROPERTY: |
| 2682 case KEYED_SUPER_PROPERTY: | 2478 case KEYED_SUPER_PROPERTY: |
| 2683 __ str(r0, MemOperand(sp, 3 * kPointerSize)); | 2479 UNREACHABLE(); |
| 2684 break; | 2480 break; |
| 2685 } | 2481 } |
| 2686 } | 2482 } |
| 2687 } | 2483 } |
| 2688 | 2484 |
| 2689 | 2485 |
| 2690 __ bind(&stub_call); | 2486 __ bind(&stub_call); |
| 2691 __ mov(r1, r0); | 2487 __ mov(r1, r0); |
| 2692 __ mov(r0, Operand(Smi::FromInt(count_value))); | 2488 __ mov(r0, Operand(Smi::FromInt(count_value))); |
| 2693 | 2489 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2730 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2526 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2731 if (expr->is_postfix()) { | 2527 if (expr->is_postfix()) { |
| 2732 if (!context()->IsEffect()) { | 2528 if (!context()->IsEffect()) { |
| 2733 context()->PlugTOS(); | 2529 context()->PlugTOS(); |
| 2734 } | 2530 } |
| 2735 } else { | 2531 } else { |
| 2736 context()->Plug(r0); | 2532 context()->Plug(r0); |
| 2737 } | 2533 } |
| 2738 break; | 2534 break; |
| 2739 } | 2535 } |
| 2740 case NAMED_SUPER_PROPERTY: { | |
| 2741 EmitNamedSuperPropertyStore(prop); | |
| 2742 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2743 if (expr->is_postfix()) { | |
| 2744 if (!context()->IsEffect()) { | |
| 2745 context()->PlugTOS(); | |
| 2746 } | |
| 2747 } else { | |
| 2748 context()->Plug(r0); | |
| 2749 } | |
| 2750 break; | |
| 2751 } | |
| 2752 case KEYED_SUPER_PROPERTY: { | |
| 2753 EmitKeyedSuperPropertyStore(prop); | |
| 2754 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2755 if (expr->is_postfix()) { | |
| 2756 if (!context()->IsEffect()) { | |
| 2757 context()->PlugTOS(); | |
| 2758 } | |
| 2759 } else { | |
| 2760 context()->Plug(r0); | |
| 2761 } | |
| 2762 break; | |
| 2763 } | |
| 2764 case KEYED_PROPERTY: { | 2536 case KEYED_PROPERTY: { |
| 2765 PopOperands(StoreDescriptor::ReceiverRegister(), | 2537 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 2766 StoreDescriptor::NameRegister()); | 2538 StoreDescriptor::NameRegister()); |
| 2767 CallKeyedStoreIC(expr->CountSlot()); | 2539 CallKeyedStoreIC(expr->CountSlot()); |
| 2768 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2540 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2769 if (expr->is_postfix()) { | 2541 if (expr->is_postfix()) { |
| 2770 if (!context()->IsEffect()) { | 2542 if (!context()->IsEffect()) { |
| 2771 context()->PlugTOS(); | 2543 context()->PlugTOS(); |
| 2772 } | 2544 } |
| 2773 } else { | 2545 } else { |
| 2774 context()->Plug(r0); | 2546 context()->Plug(r0); |
| 2775 } | 2547 } |
| 2776 break; | 2548 break; |
| 2777 } | 2549 } |
| 2550 case NAMED_SUPER_PROPERTY: |
| 2551 case KEYED_SUPER_PROPERTY: |
| 2552 UNREACHABLE(); |
| 2553 break; |
| 2778 } | 2554 } |
| 2779 } | 2555 } |
| 2780 | 2556 |
| 2781 | 2557 |
| 2782 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 2558 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 2783 Expression* sub_expr, | 2559 Expression* sub_expr, |
| 2784 Handle<String> check) { | 2560 Handle<String> check) { |
| 2785 Label materialize_true, materialize_false; | 2561 Label materialize_true, materialize_false; |
| 2786 Label* if_true = NULL; | 2562 Label* if_true = NULL; |
| 2787 Label* if_false = NULL; | 2563 Label* if_false = NULL; |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3143 DCHECK(interrupt_address == | 2919 DCHECK(interrupt_address == |
| 3144 isolate->builtins()->OnStackReplacement()->entry()); | 2920 isolate->builtins()->OnStackReplacement()->entry()); |
| 3145 return ON_STACK_REPLACEMENT; | 2921 return ON_STACK_REPLACEMENT; |
| 3146 } | 2922 } |
| 3147 | 2923 |
| 3148 | 2924 |
| 3149 } // namespace internal | 2925 } // namespace internal |
| 3150 } // namespace v8 | 2926 } // namespace v8 |
| 3151 | 2927 |
| 3152 #endif // V8_TARGET_ARCH_ARM | 2928 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |