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 |