| 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 |