| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 __ jmp(false_label_); | 1252 __ jmp(false_label_); |
| 1253 break; | 1253 break; |
| 1254 } | 1254 } |
| 1255 break; | 1255 break; |
| 1256 } | 1256 } |
| 1257 | 1257 |
| 1258 case Token::NOT: { | 1258 case Token::NOT: { |
| 1259 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); | 1259 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
| 1260 ASSERT_EQ(Expression::kTest, expr->expression()->context()); | 1260 ASSERT_EQ(Expression::kTest, expr->expression()->context()); |
| 1261 | 1261 |
| 1262 Label push_true; | 1262 Label push_true, push_false, done; |
| 1263 Label push_false; | |
| 1264 Label done; | |
| 1265 Label* saved_true = true_label_; | |
| 1266 Label* saved_false = false_label_; | |
| 1267 switch (expr->context()) { | 1263 switch (expr->context()) { |
| 1268 case Expression::kUninitialized: | 1264 case Expression::kUninitialized: |
| 1269 UNREACHABLE(); | 1265 UNREACHABLE(); |
| 1270 break; | 1266 break; |
| 1271 | 1267 |
| 1272 case Expression::kValue: | 1268 case Expression::kValue: |
| 1273 true_label_ = &push_false; | 1269 VisitForControl(expr->expression(), &push_false, &push_true); |
| 1274 false_label_ = &push_true; | |
| 1275 Visit(expr->expression()); | |
| 1276 __ bind(&push_true); | 1270 __ bind(&push_true); |
| 1277 __ PushRoot(Heap::kTrueValueRootIndex); | 1271 __ PushRoot(Heap::kTrueValueRootIndex); |
| 1278 __ jmp(&done); | 1272 __ jmp(&done); |
| 1279 __ bind(&push_false); | 1273 __ bind(&push_false); |
| 1280 __ PushRoot(Heap::kFalseValueRootIndex); | 1274 __ PushRoot(Heap::kFalseValueRootIndex); |
| 1281 __ bind(&done); | 1275 __ bind(&done); |
| 1282 break; | 1276 break; |
| 1283 | 1277 |
| 1284 case Expression::kEffect: | 1278 case Expression::kEffect: |
| 1285 true_label_ = &done; | 1279 VisitForControl(expr->expression(), &done, &done); |
| 1286 false_label_ = &done; | |
| 1287 Visit(expr->expression()); | |
| 1288 __ bind(&done); | 1280 __ bind(&done); |
| 1289 break; | 1281 break; |
| 1290 | 1282 |
| 1291 case Expression::kTest: | 1283 case Expression::kTest: |
| 1292 true_label_ = saved_false; | 1284 VisitForControl(expr->expression(), false_label_, true_label_); |
| 1293 false_label_ = saved_true; | |
| 1294 Visit(expr->expression()); | |
| 1295 break; | 1285 break; |
| 1296 | 1286 |
| 1297 case Expression::kValueTest: | 1287 case Expression::kValueTest: |
| 1298 true_label_ = saved_false; | 1288 VisitForControl(expr->expression(), false_label_, &push_true); |
| 1299 false_label_ = &push_true; | |
| 1300 Visit(expr->expression()); | |
| 1301 __ bind(&push_true); | 1289 __ bind(&push_true); |
| 1302 __ PushRoot(Heap::kTrueValueRootIndex); | 1290 __ PushRoot(Heap::kTrueValueRootIndex); |
| 1303 __ jmp(saved_true); | 1291 __ jmp(true_label_); |
| 1304 break; | 1292 break; |
| 1305 | 1293 |
| 1306 case Expression::kTestValue: | 1294 case Expression::kTestValue: |
| 1307 true_label_ = &push_false; | 1295 VisitForControl(expr->expression(), &push_false, true_label_); |
| 1308 false_label_ = saved_true; | |
| 1309 Visit(expr->expression()); | |
| 1310 __ bind(&push_false); | 1296 __ bind(&push_false); |
| 1311 __ PushRoot(Heap::kFalseValueRootIndex); | 1297 __ PushRoot(Heap::kFalseValueRootIndex); |
| 1312 __ jmp(saved_false); | 1298 __ jmp(false_label_); |
| 1313 break; | 1299 break; |
| 1314 } | 1300 } |
| 1315 true_label_ = saved_true; | |
| 1316 false_label_ = saved_false; | |
| 1317 break; | 1301 break; |
| 1318 } | 1302 } |
| 1319 | 1303 |
| 1320 case Token::TYPEOF: { | 1304 case Token::TYPEOF: { |
| 1321 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 1305 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
| 1322 ASSERT_EQ(Expression::kValue, expr->expression()->context()); | 1306 ASSERT_EQ(Expression::kValue, expr->expression()->context()); |
| 1323 | 1307 |
| 1324 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 1308 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 1325 if (proxy != NULL && | 1309 if (proxy != NULL && |
| 1326 !proxy->var()->is_this() && | 1310 !proxy->var()->is_this() && |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1534 } | 1518 } |
| 1535 | 1519 |
| 1536 | 1520 |
| 1537 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 1521 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 1538 Comment cmnt(masm_, "[ CompareOperation"); | 1522 Comment cmnt(masm_, "[ CompareOperation"); |
| 1539 ASSERT_EQ(Expression::kValue, expr->left()->context()); | 1523 ASSERT_EQ(Expression::kValue, expr->left()->context()); |
| 1540 ASSERT_EQ(Expression::kValue, expr->right()->context()); | 1524 ASSERT_EQ(Expression::kValue, expr->right()->context()); |
| 1541 Visit(expr->left()); | 1525 Visit(expr->left()); |
| 1542 Visit(expr->right()); | 1526 Visit(expr->right()); |
| 1543 | 1527 |
| 1544 // Convert current context to test context: Pre-test code. | 1528 // Always perform the comparison for its control flow. Pack the result |
| 1545 Label push_true; | 1529 // into the expression's context after the comparison is performed. |
| 1546 Label push_false; | 1530 Label push_true, push_false, done; |
| 1547 Label done; | 1531 // Initially assume we are in a test context. |
| 1548 Label* saved_true = true_label_; | 1532 Label* if_true = true_label_; |
| 1549 Label* saved_false = false_label_; | 1533 Label* if_false = false_label_; |
| 1550 switch (expr->context()) { | 1534 switch (expr->context()) { |
| 1551 case Expression::kUninitialized: | 1535 case Expression::kUninitialized: |
| 1552 UNREACHABLE(); | 1536 UNREACHABLE(); |
| 1553 break; | 1537 break; |
| 1554 | |
| 1555 case Expression::kValue: | 1538 case Expression::kValue: |
| 1556 true_label_ = &push_true; | 1539 if_true = &push_true; |
| 1557 false_label_ = &push_false; | 1540 if_false = &push_false; |
| 1558 break; | 1541 break; |
| 1559 | |
| 1560 case Expression::kEffect: | 1542 case Expression::kEffect: |
| 1561 true_label_ = &done; | 1543 if_true = &done; |
| 1562 false_label_ = &done; | 1544 if_false = &done; |
| 1563 break; | 1545 break; |
| 1564 | |
| 1565 case Expression::kTest: | 1546 case Expression::kTest: |
| 1566 break; | 1547 break; |
| 1567 | |
| 1568 case Expression::kValueTest: | 1548 case Expression::kValueTest: |
| 1569 true_label_ = &push_true; | 1549 if_true = &push_true; |
| 1570 break; | 1550 break; |
| 1571 | |
| 1572 case Expression::kTestValue: | 1551 case Expression::kTestValue: |
| 1573 false_label_ = &push_false; | 1552 if_false = &push_false; |
| 1574 break; | 1553 break; |
| 1575 } | 1554 } |
| 1576 // Convert current context to test context: End pre-test code. | |
| 1577 | 1555 |
| 1578 switch (expr->op()) { | 1556 switch (expr->op()) { |
| 1579 case Token::IN: { | 1557 case Token::IN: { |
| 1580 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 1558 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
| 1581 __ CompareRoot(rax, Heap::kTrueValueRootIndex); | 1559 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
| 1582 __ j(equal, true_label_); | 1560 __ j(equal, if_true); |
| 1583 __ jmp(false_label_); | 1561 __ jmp(if_false); |
| 1584 break; | 1562 break; |
| 1585 } | 1563 } |
| 1586 | 1564 |
| 1587 case Token::INSTANCEOF: { | 1565 case Token::INSTANCEOF: { |
| 1588 InstanceofStub stub; | 1566 InstanceofStub stub; |
| 1589 __ CallStub(&stub); | 1567 __ CallStub(&stub); |
| 1590 __ testq(rax, rax); | 1568 __ testq(rax, rax); |
| 1591 __ j(zero, true_label_); // The stub returns 0 for true. | 1569 __ j(zero, if_true); // The stub returns 0 for true. |
| 1592 __ jmp(false_label_); | 1570 __ jmp(if_false); |
| 1593 break; | 1571 break; |
| 1594 } | 1572 } |
| 1595 | 1573 |
| 1596 default: { | 1574 default: { |
| 1597 Condition cc = no_condition; | 1575 Condition cc = no_condition; |
| 1598 bool strict = false; | 1576 bool strict = false; |
| 1599 switch (expr->op()) { | 1577 switch (expr->op()) { |
| 1600 case Token::EQ_STRICT: | 1578 case Token::EQ_STRICT: |
| 1601 strict = true; | 1579 strict = true; |
| 1602 // Fall through. | 1580 // Fall through. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1631 case Token::INSTANCEOF: | 1609 case Token::INSTANCEOF: |
| 1632 default: | 1610 default: |
| 1633 UNREACHABLE(); | 1611 UNREACHABLE(); |
| 1634 } | 1612 } |
| 1635 | 1613 |
| 1636 // The comparison stub expects the smi vs. smi case to be handled | 1614 // The comparison stub expects the smi vs. smi case to be handled |
| 1637 // before it is called. | 1615 // before it is called. |
| 1638 Label slow_case; | 1616 Label slow_case; |
| 1639 __ JumpIfNotBothSmi(rax, rdx, &slow_case); | 1617 __ JumpIfNotBothSmi(rax, rdx, &slow_case); |
| 1640 __ SmiCompare(rdx, rax); | 1618 __ SmiCompare(rdx, rax); |
| 1641 __ j(cc, true_label_); | 1619 __ j(cc, if_true); |
| 1642 __ jmp(false_label_); | 1620 __ jmp(if_false); |
| 1643 | 1621 |
| 1644 __ bind(&slow_case); | 1622 __ bind(&slow_case); |
| 1645 CompareStub stub(cc, strict); | 1623 CompareStub stub(cc, strict); |
| 1646 __ CallStub(&stub); | 1624 __ CallStub(&stub); |
| 1647 __ testq(rax, rax); | 1625 __ testq(rax, rax); |
| 1648 __ j(cc, true_label_); | 1626 __ j(cc, if_true); |
| 1649 __ jmp(false_label_); | 1627 __ jmp(if_false); |
| 1650 } | 1628 } |
| 1651 } | 1629 } |
| 1652 | 1630 |
| 1653 // Convert current context to test context: Post-test code. | 1631 // Convert the result of the comparison into one expected for this |
| 1632 // expression's context. |
| 1654 switch (expr->context()) { | 1633 switch (expr->context()) { |
| 1655 case Expression::kUninitialized: | 1634 case Expression::kUninitialized: |
| 1656 UNREACHABLE(); | 1635 UNREACHABLE(); |
| 1657 break; | 1636 break; |
| 1658 | 1637 |
| 1638 case Expression::kEffect: |
| 1639 __ bind(&done); |
| 1640 break; |
| 1641 |
| 1659 case Expression::kValue: | 1642 case Expression::kValue: |
| 1660 __ bind(&push_true); | 1643 __ bind(&push_true); |
| 1661 __ PushRoot(Heap::kTrueValueRootIndex); | 1644 __ PushRoot(Heap::kTrueValueRootIndex); |
| 1662 __ jmp(&done); | 1645 __ jmp(&done); |
| 1663 __ bind(&push_false); | 1646 __ bind(&push_false); |
| 1664 __ PushRoot(Heap::kFalseValueRootIndex); | 1647 __ PushRoot(Heap::kFalseValueRootIndex); |
| 1665 __ bind(&done); | 1648 __ bind(&done); |
| 1666 break; | 1649 break; |
| 1667 | 1650 |
| 1668 case Expression::kEffect: | |
| 1669 __ bind(&done); | |
| 1670 break; | |
| 1671 | |
| 1672 case Expression::kTest: | 1651 case Expression::kTest: |
| 1673 break; | 1652 break; |
| 1674 | 1653 |
| 1675 case Expression::kValueTest: | 1654 case Expression::kValueTest: |
| 1676 __ bind(&push_true); | 1655 __ bind(&push_true); |
| 1677 __ PushRoot(Heap::kTrueValueRootIndex); | 1656 __ PushRoot(Heap::kTrueValueRootIndex); |
| 1678 __ jmp(saved_true); | 1657 __ jmp(true_label_); |
| 1679 break; | 1658 break; |
| 1680 | 1659 |
| 1681 case Expression::kTestValue: | 1660 case Expression::kTestValue: |
| 1682 __ bind(&push_false); | 1661 __ bind(&push_false); |
| 1683 __ PushRoot(Heap::kFalseValueRootIndex); | 1662 __ PushRoot(Heap::kFalseValueRootIndex); |
| 1684 __ jmp(saved_false); | 1663 __ jmp(false_label_); |
| 1685 break; | 1664 break; |
| 1686 } | 1665 } |
| 1687 true_label_ = saved_true; | |
| 1688 false_label_ = saved_false; | |
| 1689 // Convert current context to test context: End post-test code. | |
| 1690 } | 1666 } |
| 1691 | 1667 |
| 1692 | 1668 |
| 1693 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 1669 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 1694 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 1670 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1695 Apply(expr->context(), rax); | 1671 Apply(expr->context(), rax); |
| 1696 } | 1672 } |
| 1697 | 1673 |
| 1698 | 1674 |
| 1699 Register FastCodeGenerator::result_register() { return rax; } | 1675 Register FastCodeGenerator::result_register() { return rax; } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1744 __ movq(Operand(rsp, 0), rdx); | 1720 __ movq(Operand(rsp, 0), rdx); |
| 1745 // And return. | 1721 // And return. |
| 1746 __ ret(0); | 1722 __ ret(0); |
| 1747 } | 1723 } |
| 1748 | 1724 |
| 1749 | 1725 |
| 1750 #undef __ | 1726 #undef __ |
| 1751 | 1727 |
| 1752 | 1728 |
| 1753 } } // namespace v8::internal | 1729 } } // namespace v8::internal |
| OLD | NEW |