| 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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
| 6 | 6 |
| 7 // Note on Mips implementation: | 7 // Note on Mips implementation: |
| 8 // | 8 // |
| 9 // The result_register() for mips is the 'v0' register, which is defined | 9 // The result_register() for mips is the 'v0' register, which is defined |
| 10 // by the ABI to contain function return values. However, the first | 10 // by the ABI to contain function return values. However, the first |
| (...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 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1416 __ lw(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 = a1; | |
| 1429 __ lw(scratch, MemOperand(sp, kPointerSize)); | |
| 1430 PushOperands(scratch, result_register()); | |
| 1431 } | |
| 1432 break; | |
| 1433 case KEYED_SUPER_PROPERTY: { | |
| 1434 VisitForStackValue( | |
| 1435 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1436 VisitForStackValue( | |
| 1437 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1438 VisitForAccumulatorValue(property->key()); | |
| 1439 PushOperand(result_register()); | |
| 1440 if (expr->is_compound()) { | |
| 1441 const Register scratch1 = t0; | |
| 1442 const Register scratch2 = a1; | |
| 1443 __ lw(scratch1, MemOperand(sp, 2 * kPointerSize)); | |
| 1444 __ lw(scratch2, MemOperand(sp, 1 * kPointerSize)); | |
| 1445 PushOperands(scratch1, scratch2, result_register()); | |
| 1446 } | |
| 1447 break; | |
| 1448 } | |
| 1449 case KEYED_PROPERTY: | 1421 case KEYED_PROPERTY: |
| 1450 // We need the key and receiver on both the stack and in v0 and a1. | 1422 // We need the key and receiver on both the stack and in v0 and a1. |
| 1451 if (expr->is_compound()) { | 1423 if (expr->is_compound()) { |
| 1452 VisitForStackValue(property->obj()); | 1424 VisitForStackValue(property->obj()); |
| 1453 VisitForStackValue(property->key()); | 1425 VisitForStackValue(property->key()); |
| 1454 __ lw(LoadDescriptor::ReceiverRegister(), | 1426 __ lw(LoadDescriptor::ReceiverRegister(), |
| 1455 MemOperand(sp, 1 * kPointerSize)); | 1427 MemOperand(sp, 1 * kPointerSize)); |
| 1456 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 1428 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| 1457 } else { | 1429 } else { |
| 1458 VisitForStackValue(property->obj()); | 1430 VisitForStackValue(property->obj()); |
| 1459 VisitForStackValue(property->key()); | 1431 VisitForStackValue(property->key()); |
| 1460 } | 1432 } |
| 1461 break; | 1433 break; |
| 1434 case NAMED_SUPER_PROPERTY: |
| 1435 case KEYED_SUPER_PROPERTY: |
| 1436 UNREACHABLE(); |
| 1437 break; |
| 1462 } | 1438 } |
| 1463 | 1439 |
| 1464 // For compound assignments we need another deoptimization point after the | 1440 // For compound assignments we need another deoptimization point after the |
| 1465 // variable/property load. | 1441 // variable/property load. |
| 1466 if (expr->is_compound()) { | 1442 if (expr->is_compound()) { |
| 1467 { AccumulatorValueContext context(this); | 1443 { AccumulatorValueContext context(this); |
| 1468 switch (assign_type) { | 1444 switch (assign_type) { |
| 1469 case VARIABLE: | 1445 case VARIABLE: |
| 1470 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1446 EmitVariableLoad(expr->target()->AsVariableProxy()); |
| 1471 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); | 1447 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); |
| 1472 break; | 1448 break; |
| 1473 case NAMED_PROPERTY: | 1449 case NAMED_PROPERTY: |
| 1474 EmitNamedPropertyLoad(property); | 1450 EmitNamedPropertyLoad(property); |
| 1475 PrepareForBailoutForId(property->LoadId(), | 1451 PrepareForBailoutForId(property->LoadId(), |
| 1476 BailoutState::TOS_REGISTER); | 1452 BailoutState::TOS_REGISTER); |
| 1477 break; | 1453 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: | 1454 case KEYED_PROPERTY: |
| 1489 EmitKeyedPropertyLoad(property); | 1455 EmitKeyedPropertyLoad(property); |
| 1490 PrepareForBailoutForId(property->LoadId(), | 1456 PrepareForBailoutForId(property->LoadId(), |
| 1491 BailoutState::TOS_REGISTER); | 1457 BailoutState::TOS_REGISTER); |
| 1492 break; | 1458 break; |
| 1459 case NAMED_SUPER_PROPERTY: |
| 1460 case KEYED_SUPER_PROPERTY: |
| 1461 UNREACHABLE(); |
| 1462 break; |
| 1493 } | 1463 } |
| 1494 } | 1464 } |
| 1495 | 1465 |
| 1496 Token::Value op = expr->binary_op(); | 1466 Token::Value op = expr->binary_op(); |
| 1497 PushOperand(v0); // Left operand goes on the stack. | 1467 PushOperand(v0); // Left operand goes on the stack. |
| 1498 VisitForAccumulatorValue(expr->value()); | 1468 VisitForAccumulatorValue(expr->value()); |
| 1499 | 1469 |
| 1500 AccumulatorValueContext context(this); | 1470 AccumulatorValueContext context(this); |
| 1501 if (ShouldInlineSmiCase(op)) { | 1471 if (ShouldInlineSmiCase(op)) { |
| 1502 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1472 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1521 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1491 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1522 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1492 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
| 1523 proxy->hole_check_mode()); | 1493 proxy->hole_check_mode()); |
| 1524 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1494 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1525 context()->Plug(v0); | 1495 context()->Plug(v0); |
| 1526 break; | 1496 break; |
| 1527 } | 1497 } |
| 1528 case NAMED_PROPERTY: | 1498 case NAMED_PROPERTY: |
| 1529 EmitNamedPropertyAssignment(expr); | 1499 EmitNamedPropertyAssignment(expr); |
| 1530 break; | 1500 break; |
| 1531 case NAMED_SUPER_PROPERTY: | |
| 1532 EmitNamedSuperPropertyStore(property); | |
| 1533 context()->Plug(v0); | |
| 1534 break; | |
| 1535 case KEYED_SUPER_PROPERTY: | |
| 1536 EmitKeyedSuperPropertyStore(property); | |
| 1537 context()->Plug(v0); | |
| 1538 break; | |
| 1539 case KEYED_PROPERTY: | 1501 case KEYED_PROPERTY: |
| 1540 EmitKeyedPropertyAssignment(expr); | 1502 EmitKeyedPropertyAssignment(expr); |
| 1541 break; | 1503 break; |
| 1504 case NAMED_SUPER_PROPERTY: |
| 1505 case KEYED_SUPER_PROPERTY: |
| 1506 UNREACHABLE(); |
| 1507 break; |
| 1542 } | 1508 } |
| 1543 } | 1509 } |
| 1544 | 1510 |
| 1545 | 1511 |
| 1546 void FullCodeGenerator::VisitYield(Yield* expr) { | 1512 void FullCodeGenerator::VisitYield(Yield* expr) { |
| 1547 // Resumable functions are not supported. | 1513 // Resumable functions are not supported. |
| 1548 UNREACHABLE(); | 1514 UNREACHABLE(); |
| 1549 } | 1515 } |
| 1550 | 1516 |
| 1551 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 1517 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1721 break; | 1687 break; |
| 1722 } | 1688 } |
| 1723 case NAMED_PROPERTY: { | 1689 case NAMED_PROPERTY: { |
| 1724 PushOperand(result_register()); // Preserve value. | 1690 PushOperand(result_register()); // Preserve value. |
| 1725 VisitForAccumulatorValue(prop->obj()); | 1691 VisitForAccumulatorValue(prop->obj()); |
| 1726 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); | 1692 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); |
| 1727 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1693 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1728 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1694 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
| 1729 break; | 1695 break; |
| 1730 } | 1696 } |
| 1731 case NAMED_SUPER_PROPERTY: { | |
| 1732 PushOperand(v0); | |
| 1733 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1734 VisitForAccumulatorValue( | |
| 1735 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1736 // stack: value, this; v0: home_object | |
| 1737 Register scratch = a2; | |
| 1738 Register scratch2 = a3; | |
| 1739 __ mov(scratch, result_register()); // home_object | |
| 1740 __ lw(v0, MemOperand(sp, kPointerSize)); // value | |
| 1741 __ lw(scratch2, MemOperand(sp, 0)); // this | |
| 1742 __ sw(scratch2, MemOperand(sp, kPointerSize)); // this | |
| 1743 __ sw(scratch, MemOperand(sp, 0)); // home_object | |
| 1744 // stack: this, home_object; v0: value | |
| 1745 EmitNamedSuperPropertyStore(prop); | |
| 1746 break; | |
| 1747 } | |
| 1748 case KEYED_SUPER_PROPERTY: { | |
| 1749 PushOperand(v0); | |
| 1750 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1751 VisitForStackValue( | |
| 1752 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1753 VisitForAccumulatorValue(prop->key()); | |
| 1754 Register scratch = a2; | |
| 1755 Register scratch2 = a3; | |
| 1756 __ lw(scratch2, MemOperand(sp, 2 * kPointerSize)); // value | |
| 1757 // stack: value, this, home_object; v0: key, a3: value | |
| 1758 __ lw(scratch, MemOperand(sp, kPointerSize)); // this | |
| 1759 __ sw(scratch, MemOperand(sp, 2 * kPointerSize)); | |
| 1760 __ lw(scratch, MemOperand(sp, 0)); // home_object | |
| 1761 __ sw(scratch, MemOperand(sp, kPointerSize)); | |
| 1762 __ sw(v0, MemOperand(sp, 0)); | |
| 1763 __ Move(v0, scratch2); | |
| 1764 // stack: this, home_object, key; v0: value. | |
| 1765 EmitKeyedSuperPropertyStore(prop); | |
| 1766 break; | |
| 1767 } | |
| 1768 case KEYED_PROPERTY: { | 1697 case KEYED_PROPERTY: { |
| 1769 PushOperand(result_register()); // Preserve value. | 1698 PushOperand(result_register()); // Preserve value. |
| 1770 VisitForStackValue(prop->obj()); | 1699 VisitForStackValue(prop->obj()); |
| 1771 VisitForAccumulatorValue(prop->key()); | 1700 VisitForAccumulatorValue(prop->key()); |
| 1772 __ mov(StoreDescriptor::NameRegister(), result_register()); | 1701 __ mov(StoreDescriptor::NameRegister(), result_register()); |
| 1773 PopOperands(StoreDescriptor::ValueRegister(), | 1702 PopOperands(StoreDescriptor::ValueRegister(), |
| 1774 StoreDescriptor::ReceiverRegister()); | 1703 StoreDescriptor::ReceiverRegister()); |
| 1775 CallKeyedStoreIC(slot); | 1704 CallKeyedStoreIC(slot); |
| 1776 break; | 1705 break; |
| 1777 } | 1706 } |
| 1707 case NAMED_SUPER_PROPERTY: |
| 1708 case KEYED_SUPER_PROPERTY: |
| 1709 UNREACHABLE(); |
| 1710 break; |
| 1778 } | 1711 } |
| 1779 context()->Plug(v0); | 1712 context()->Plug(v0); |
| 1780 } | 1713 } |
| 1781 | 1714 |
| 1782 | 1715 |
| 1783 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 1716 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 1784 Variable* var, MemOperand location) { | 1717 Variable* var, MemOperand location) { |
| 1785 __ sw(result_register(), location); | 1718 __ sw(result_register(), location); |
| 1786 if (var->IsContextSlot()) { | 1719 if (var->IsContextSlot()) { |
| 1787 // RecordWrite may destroy all its register arguments. | 1720 // RecordWrite may destroy all its register arguments. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1861 | 1794 |
| 1862 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 1795 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 1863 PopOperand(StoreDescriptor::ReceiverRegister()); | 1796 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1864 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 1797 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); |
| 1865 | 1798 |
| 1866 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1799 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1867 context()->Plug(v0); | 1800 context()->Plug(v0); |
| 1868 } | 1801 } |
| 1869 | 1802 |
| 1870 | 1803 |
| 1871 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | |
| 1872 // Assignment to named property of super. | |
| 1873 // v0 : value | |
| 1874 // stack : receiver ('this'), home_object | |
| 1875 DCHECK(prop != NULL); | |
| 1876 Literal* key = prop->key()->AsLiteral(); | |
| 1877 DCHECK(key != NULL); | |
| 1878 | |
| 1879 PushOperand(key->value()); | |
| 1880 PushOperand(v0); | |
| 1881 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1882 ? Runtime::kStoreToSuper_Strict | |
| 1883 : Runtime::kStoreToSuper_Sloppy); | |
| 1884 } | |
| 1885 | |
| 1886 | |
| 1887 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | |
| 1888 // Assignment to named property of super. | |
| 1889 // v0 : value | |
| 1890 // stack : receiver ('this'), home_object, key | |
| 1891 DCHECK(prop != NULL); | |
| 1892 | |
| 1893 PushOperand(v0); | |
| 1894 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1895 ? Runtime::kStoreKeyedToSuper_Strict | |
| 1896 : Runtime::kStoreKeyedToSuper_Sloppy); | |
| 1897 } | |
| 1898 | |
| 1899 | |
| 1900 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1804 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 1901 // Assignment to a property, using a keyed store IC. | 1805 // Assignment to a property, using a keyed store IC. |
| 1902 // Call keyed store IC. | 1806 // Call keyed store IC. |
| 1903 // The arguments are: | 1807 // The arguments are: |
| 1904 // - a0 is the value, | 1808 // - a0 is the value, |
| 1905 // - a1 is the key, | 1809 // - a1 is the key, |
| 1906 // - a2 is the receiver. | 1810 // - a2 is the receiver. |
| 1907 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 1811 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 1908 PopOperands(StoreDescriptor::ReceiverRegister(), | 1812 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 1909 StoreDescriptor::NameRegister()); | 1813 StoreDescriptor::NameRegister()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1943 __ lw(at, MemOperand(sp, 0)); | 1847 __ lw(at, MemOperand(sp, 0)); |
| 1944 PushOperand(at); | 1848 PushOperand(at); |
| 1945 __ sw(v0, MemOperand(sp, kPointerSize)); | 1849 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 1946 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 1850 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 1947 } | 1851 } |
| 1948 | 1852 |
| 1949 EmitCall(expr, convert_mode); | 1853 EmitCall(expr, convert_mode); |
| 1950 } | 1854 } |
| 1951 | 1855 |
| 1952 | 1856 |
| 1953 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | |
| 1954 SetExpressionPosition(expr); | |
| 1955 Expression* callee = expr->expression(); | |
| 1956 DCHECK(callee->IsProperty()); | |
| 1957 Property* prop = callee->AsProperty(); | |
| 1958 DCHECK(prop->IsSuperAccess()); | |
| 1959 | |
| 1960 Literal* key = prop->key()->AsLiteral(); | |
| 1961 DCHECK(!key->value()->IsSmi()); | |
| 1962 // Load the function from the receiver. | |
| 1963 const Register scratch = a1; | |
| 1964 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 1965 VisitForAccumulatorValue(super_ref->home_object()); | |
| 1966 __ mov(scratch, v0); | |
| 1967 VisitForAccumulatorValue(super_ref->this_var()); | |
| 1968 PushOperands(scratch, v0, v0, scratch); | |
| 1969 PushOperand(key->value()); | |
| 1970 | |
| 1971 // Stack here: | |
| 1972 // - home_object | |
| 1973 // - this (receiver) | |
| 1974 // - this (receiver) <-- LoadFromSuper will pop here and below. | |
| 1975 // - home_object | |
| 1976 // - key | |
| 1977 CallRuntimeWithOperands(Runtime::kLoadFromSuper); | |
| 1978 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 1979 | |
| 1980 // Replace home_object with target function. | |
| 1981 __ sw(v0, MemOperand(sp, kPointerSize)); | |
| 1982 | |
| 1983 // Stack here: | |
| 1984 // - target function | |
| 1985 // - this (receiver) | |
| 1986 EmitCall(expr); | |
| 1987 } | |
| 1988 | |
| 1989 | |
| 1990 // Code common for calls using the IC. | 1857 // Code common for calls using the IC. |
| 1991 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 1858 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 1992 Expression* key) { | 1859 Expression* key) { |
| 1993 // Load the key. | 1860 // Load the key. |
| 1994 VisitForAccumulatorValue(key); | 1861 VisitForAccumulatorValue(key); |
| 1995 | 1862 |
| 1996 Expression* callee = expr->expression(); | 1863 Expression* callee = expr->expression(); |
| 1997 | 1864 |
| 1998 // Load the function from the receiver. | 1865 // Load the function from the receiver. |
| 1999 DCHECK(callee->IsProperty()); | 1866 DCHECK(callee->IsProperty()); |
| 2000 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1867 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 2001 __ Move(LoadDescriptor::NameRegister(), v0); | 1868 __ Move(LoadDescriptor::NameRegister(), v0); |
| 2002 EmitKeyedPropertyLoad(callee->AsProperty()); | 1869 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2003 PrepareForBailoutForId(callee->AsProperty()->LoadId(), | 1870 PrepareForBailoutForId(callee->AsProperty()->LoadId(), |
| 2004 BailoutState::TOS_REGISTER); | 1871 BailoutState::TOS_REGISTER); |
| 2005 | 1872 |
| 2006 // Push the target function under the receiver. | 1873 // Push the target function under the receiver. |
| 2007 __ lw(at, MemOperand(sp, 0)); | 1874 __ lw(at, MemOperand(sp, 0)); |
| 2008 PushOperand(at); | 1875 PushOperand(at); |
| 2009 __ sw(v0, MemOperand(sp, kPointerSize)); | 1876 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 2010 | 1877 |
| 2011 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 1878 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
| 2012 } | 1879 } |
| 2013 | 1880 |
| 2014 | 1881 |
| 2015 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | |
| 2016 Expression* callee = expr->expression(); | |
| 2017 DCHECK(callee->IsProperty()); | |
| 2018 Property* prop = callee->AsProperty(); | |
| 2019 DCHECK(prop->IsSuperAccess()); | |
| 2020 | |
| 2021 SetExpressionPosition(prop); | |
| 2022 // Load the function from the receiver. | |
| 2023 const Register scratch = a1; | |
| 2024 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 2025 VisitForAccumulatorValue(super_ref->home_object()); | |
| 2026 __ Move(scratch, v0); | |
| 2027 VisitForAccumulatorValue(super_ref->this_var()); | |
| 2028 PushOperands(scratch, v0, v0, scratch); | |
| 2029 VisitForStackValue(prop->key()); | |
| 2030 | |
| 2031 // Stack here: | |
| 2032 // - home_object | |
| 2033 // - this (receiver) | |
| 2034 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | |
| 2035 // - home_object | |
| 2036 // - key | |
| 2037 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | |
| 2038 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 2039 | |
| 2040 // Replace home_object with target function. | |
| 2041 __ sw(v0, MemOperand(sp, kPointerSize)); | |
| 2042 | |
| 2043 // Stack here: | |
| 2044 // - target function | |
| 2045 // - this (receiver) | |
| 2046 EmitCall(expr); | |
| 2047 } | |
| 2048 | |
| 2049 | |
| 2050 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 1882 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
| 2051 // Load the arguments. | 1883 // Load the arguments. |
| 2052 ZoneList<Expression*>* args = expr->arguments(); | 1884 ZoneList<Expression*>* args = expr->arguments(); |
| 2053 int arg_count = args->length(); | 1885 int arg_count = args->length(); |
| 2054 for (int i = 0; i < arg_count; i++) { | 1886 for (int i = 0; i < arg_count; i++) { |
| 2055 VisitForStackValue(args->at(i)); | 1887 VisitForStackValue(args->at(i)); |
| 2056 } | 1888 } |
| 2057 | 1889 |
| 2058 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1890 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); |
| 2059 // Record source position of the IC call. | 1891 // Record source position of the IC call. |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2569 } | 2401 } |
| 2570 switch (assign_type) { | 2402 switch (assign_type) { |
| 2571 case NAMED_PROPERTY: { | 2403 case NAMED_PROPERTY: { |
| 2572 // Put the object both on the stack and in the register. | 2404 // Put the object both on the stack and in the register. |
| 2573 VisitForStackValue(prop->obj()); | 2405 VisitForStackValue(prop->obj()); |
| 2574 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2406 __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 2575 EmitNamedPropertyLoad(prop); | 2407 EmitNamedPropertyLoad(prop); |
| 2576 break; | 2408 break; |
| 2577 } | 2409 } |
| 2578 | 2410 |
| 2579 case NAMED_SUPER_PROPERTY: { | |
| 2580 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2581 VisitForAccumulatorValue( | |
| 2582 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2583 const Register scratch = a1; | |
| 2584 __ lw(scratch, MemOperand(sp, 0)); // this | |
| 2585 PushOperands(result_register(), scratch, result_register()); | |
| 2586 EmitNamedSuperPropertyLoad(prop); | |
| 2587 break; | |
| 2588 } | |
| 2589 | |
| 2590 case KEYED_SUPER_PROPERTY: { | |
| 2591 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2592 VisitForStackValue( | |
| 2593 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2594 VisitForAccumulatorValue(prop->key()); | |
| 2595 const Register scratch1 = a1; | |
| 2596 const Register scratch2 = t0; | |
| 2597 __ lw(scratch1, MemOperand(sp, 1 * kPointerSize)); // this | |
| 2598 __ lw(scratch2, MemOperand(sp, 0 * kPointerSize)); // home object | |
| 2599 PushOperands(result_register(), scratch1, scratch2, result_register()); | |
| 2600 EmitKeyedSuperPropertyLoad(prop); | |
| 2601 break; | |
| 2602 } | |
| 2603 | |
| 2604 case KEYED_PROPERTY: { | 2411 case KEYED_PROPERTY: { |
| 2605 VisitForStackValue(prop->obj()); | 2412 VisitForStackValue(prop->obj()); |
| 2606 VisitForStackValue(prop->key()); | 2413 VisitForStackValue(prop->key()); |
| 2607 __ lw(LoadDescriptor::ReceiverRegister(), | 2414 __ lw(LoadDescriptor::ReceiverRegister(), |
| 2608 MemOperand(sp, 1 * kPointerSize)); | 2415 MemOperand(sp, 1 * kPointerSize)); |
| 2609 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 2416 __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| 2610 EmitKeyedPropertyLoad(prop); | 2417 EmitKeyedPropertyLoad(prop); |
| 2611 break; | 2418 break; |
| 2612 } | 2419 } |
| 2613 | 2420 |
| 2421 case NAMED_SUPER_PROPERTY: |
| 2422 case KEYED_SUPER_PROPERTY: |
| 2614 case VARIABLE: | 2423 case VARIABLE: |
| 2615 UNREACHABLE(); | 2424 UNREACHABLE(); |
| 2616 } | 2425 } |
| 2617 } | 2426 } |
| 2618 | 2427 |
| 2619 // We need a second deoptimization point after loading the value | 2428 // We need a second deoptimization point after loading the value |
| 2620 // in case evaluating the property load my have a side effect. | 2429 // in case evaluating the property load my have a side effect. |
| 2621 if (assign_type == VARIABLE) { | 2430 if (assign_type == VARIABLE) { |
| 2622 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); | 2431 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); |
| 2623 } else { | 2432 } else { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2640 // Save the result on the stack. If we have a named or keyed property | 2449 // Save the result on the stack. If we have a named or keyed property |
| 2641 // we store the result under the receiver that is currently on top | 2450 // we store the result under the receiver that is currently on top |
| 2642 // of the stack. | 2451 // of the stack. |
| 2643 switch (assign_type) { | 2452 switch (assign_type) { |
| 2644 case VARIABLE: | 2453 case VARIABLE: |
| 2645 __ push(v0); | 2454 __ push(v0); |
| 2646 break; | 2455 break; |
| 2647 case NAMED_PROPERTY: | 2456 case NAMED_PROPERTY: |
| 2648 __ sw(v0, MemOperand(sp, kPointerSize)); | 2457 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 2649 break; | 2458 break; |
| 2650 case NAMED_SUPER_PROPERTY: | |
| 2651 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | |
| 2652 break; | |
| 2653 case KEYED_PROPERTY: | 2459 case KEYED_PROPERTY: |
| 2654 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | 2460 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); |
| 2655 break; | 2461 break; |
| 2462 case NAMED_SUPER_PROPERTY: |
| 2656 case KEYED_SUPER_PROPERTY: | 2463 case KEYED_SUPER_PROPERTY: |
| 2657 __ sw(v0, MemOperand(sp, 3 * kPointerSize)); | 2464 UNREACHABLE(); |
| 2658 break; | 2465 break; |
| 2659 } | 2466 } |
| 2660 } | 2467 } |
| 2661 } | 2468 } |
| 2662 | 2469 |
| 2663 Register scratch1 = a1; | 2470 Register scratch1 = a1; |
| 2664 __ li(scratch1, Operand(Smi::FromInt(count_value))); | 2471 __ li(scratch1, Operand(Smi::FromInt(count_value))); |
| 2665 __ AddBranchNoOvf(v0, v0, Operand(scratch1), &done); | 2472 __ AddBranchNoOvf(v0, v0, Operand(scratch1), &done); |
| 2666 // Call stub. Undo operation first. | 2473 // Call stub. Undo operation first. |
| 2667 __ Move(v0, a0); | 2474 __ Move(v0, a0); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2680 // Save the result on the stack. If we have a named or keyed property | 2487 // Save the result on the stack. If we have a named or keyed property |
| 2681 // we store the result under the receiver that is currently on top | 2488 // we store the result under the receiver that is currently on top |
| 2682 // of the stack. | 2489 // of the stack. |
| 2683 switch (assign_type) { | 2490 switch (assign_type) { |
| 2684 case VARIABLE: | 2491 case VARIABLE: |
| 2685 PushOperand(v0); | 2492 PushOperand(v0); |
| 2686 break; | 2493 break; |
| 2687 case NAMED_PROPERTY: | 2494 case NAMED_PROPERTY: |
| 2688 __ sw(v0, MemOperand(sp, kPointerSize)); | 2495 __ sw(v0, MemOperand(sp, kPointerSize)); |
| 2689 break; | 2496 break; |
| 2690 case NAMED_SUPER_PROPERTY: | |
| 2691 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | |
| 2692 break; | |
| 2693 case KEYED_PROPERTY: | 2497 case KEYED_PROPERTY: |
| 2694 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); | 2498 __ sw(v0, MemOperand(sp, 2 * kPointerSize)); |
| 2695 break; | 2499 break; |
| 2500 case NAMED_SUPER_PROPERTY: |
| 2696 case KEYED_SUPER_PROPERTY: | 2501 case KEYED_SUPER_PROPERTY: |
| 2697 __ sw(v0, MemOperand(sp, 3 * kPointerSize)); | 2502 UNREACHABLE(); |
| 2698 break; | 2503 break; |
| 2699 } | 2504 } |
| 2700 } | 2505 } |
| 2701 } | 2506 } |
| 2702 | 2507 |
| 2703 __ bind(&stub_call); | 2508 __ bind(&stub_call); |
| 2704 __ mov(a1, v0); | 2509 __ mov(a1, v0); |
| 2705 __ li(a0, Operand(Smi::FromInt(count_value))); | 2510 __ li(a0, Operand(Smi::FromInt(count_value))); |
| 2706 | 2511 |
| 2707 SetExpressionPosition(expr); | 2512 SetExpressionPosition(expr); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2744 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2549 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2745 if (expr->is_postfix()) { | 2550 if (expr->is_postfix()) { |
| 2746 if (!context()->IsEffect()) { | 2551 if (!context()->IsEffect()) { |
| 2747 context()->PlugTOS(); | 2552 context()->PlugTOS(); |
| 2748 } | 2553 } |
| 2749 } else { | 2554 } else { |
| 2750 context()->Plug(v0); | 2555 context()->Plug(v0); |
| 2751 } | 2556 } |
| 2752 break; | 2557 break; |
| 2753 } | 2558 } |
| 2754 case NAMED_SUPER_PROPERTY: { | |
| 2755 EmitNamedSuperPropertyStore(prop); | |
| 2756 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2757 if (expr->is_postfix()) { | |
| 2758 if (!context()->IsEffect()) { | |
| 2759 context()->PlugTOS(); | |
| 2760 } | |
| 2761 } else { | |
| 2762 context()->Plug(v0); | |
| 2763 } | |
| 2764 break; | |
| 2765 } | |
| 2766 case KEYED_SUPER_PROPERTY: { | |
| 2767 EmitKeyedSuperPropertyStore(prop); | |
| 2768 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2769 if (expr->is_postfix()) { | |
| 2770 if (!context()->IsEffect()) { | |
| 2771 context()->PlugTOS(); | |
| 2772 } | |
| 2773 } else { | |
| 2774 context()->Plug(v0); | |
| 2775 } | |
| 2776 break; | |
| 2777 } | |
| 2778 case KEYED_PROPERTY: { | 2559 case KEYED_PROPERTY: { |
| 2779 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2560 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 2780 PopOperands(StoreDescriptor::ReceiverRegister(), | 2561 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 2781 StoreDescriptor::NameRegister()); | 2562 StoreDescriptor::NameRegister()); |
| 2782 CallKeyedStoreIC(expr->CountSlot()); | 2563 CallKeyedStoreIC(expr->CountSlot()); |
| 2783 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2564 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2784 if (expr->is_postfix()) { | 2565 if (expr->is_postfix()) { |
| 2785 if (!context()->IsEffect()) { | 2566 if (!context()->IsEffect()) { |
| 2786 context()->PlugTOS(); | 2567 context()->PlugTOS(); |
| 2787 } | 2568 } |
| 2788 } else { | 2569 } else { |
| 2789 context()->Plug(v0); | 2570 context()->Plug(v0); |
| 2790 } | 2571 } |
| 2791 break; | 2572 break; |
| 2792 } | 2573 } |
| 2574 case NAMED_SUPER_PROPERTY: |
| 2575 case KEYED_SUPER_PROPERTY: |
| 2576 UNREACHABLE(); |
| 2577 break; |
| 2793 } | 2578 } |
| 2794 } | 2579 } |
| 2795 | 2580 |
| 2796 | 2581 |
| 2797 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 2582 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 2798 Expression* sub_expr, | 2583 Expression* sub_expr, |
| 2799 Handle<String> check) { | 2584 Handle<String> check) { |
| 2800 Label materialize_true, materialize_false; | 2585 Label materialize_true, materialize_false; |
| 2801 Label* if_true = NULL; | 2586 Label* if_true = NULL; |
| 2802 Label* if_false = NULL; | 2587 Label* if_false = NULL; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3092 reinterpret_cast<uint32_t>( | 2877 reinterpret_cast<uint32_t>( |
| 3093 isolate->builtins()->OnStackReplacement()->entry())); | 2878 isolate->builtins()->OnStackReplacement()->entry())); |
| 3094 return ON_STACK_REPLACEMENT; | 2879 return ON_STACK_REPLACEMENT; |
| 3095 } | 2880 } |
| 3096 | 2881 |
| 3097 | 2882 |
| 3098 } // namespace internal | 2883 } // namespace internal |
| 3099 } // namespace v8 | 2884 } // namespace v8 |
| 3100 | 2885 |
| 3101 #endif // V8_TARGET_ARCH_MIPS | 2886 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |