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 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1233 __ jmp(false_label_); | 1233 __ jmp(false_label_); |
1234 break; | 1234 break; |
1235 } | 1235 } |
1236 break; | 1236 break; |
1237 } | 1237 } |
1238 | 1238 |
1239 case Token::NOT: { | 1239 case Token::NOT: { |
1240 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); | 1240 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
1241 ASSERT_EQ(Expression::kTest, expr->expression()->context()); | 1241 ASSERT_EQ(Expression::kTest, expr->expression()->context()); |
1242 | 1242 |
1243 Label push_true; | 1243 Label push_true, push_false, done; |
1244 Label push_false; | |
1245 Label done; | |
1246 Label* saved_true = true_label_; | |
1247 Label* saved_false = false_label_; | |
1248 switch (expr->context()) { | 1244 switch (expr->context()) { |
1249 case Expression::kUninitialized: | 1245 case Expression::kUninitialized: |
1250 UNREACHABLE(); | 1246 UNREACHABLE(); |
1251 break; | 1247 break; |
1252 | 1248 |
| 1249 case Expression::kEffect: |
| 1250 VisitForControl(expr->expression(), &done, &done); |
| 1251 __ bind(&done); |
| 1252 break; |
| 1253 |
1253 case Expression::kValue: | 1254 case Expression::kValue: |
1254 true_label_ = &push_false; | 1255 VisitForControl(expr->expression(), &push_false, &push_true); |
1255 false_label_ = &push_true; | |
1256 Visit(expr->expression()); | |
1257 __ bind(&push_true); | 1256 __ bind(&push_true); |
1258 __ push(Immediate(Factory::true_value())); | 1257 __ push(Immediate(Factory::true_value())); |
1259 __ jmp(&done); | 1258 __ jmp(&done); |
1260 __ bind(&push_false); | 1259 __ bind(&push_false); |
1261 __ push(Immediate(Factory::false_value())); | 1260 __ push(Immediate(Factory::false_value())); |
1262 __ bind(&done); | 1261 __ bind(&done); |
1263 break; | 1262 break; |
1264 | 1263 |
1265 case Expression::kEffect: | |
1266 true_label_ = &done; | |
1267 false_label_ = &done; | |
1268 Visit(expr->expression()); | |
1269 __ bind(&done); | |
1270 break; | |
1271 | |
1272 case Expression::kTest: | 1264 case Expression::kTest: |
1273 true_label_ = saved_false; | 1265 VisitForControl(expr->expression(), false_label_, true_label_); |
1274 false_label_ = saved_true; | |
1275 Visit(expr->expression()); | |
1276 break; | 1266 break; |
1277 | 1267 |
1278 case Expression::kValueTest: | 1268 case Expression::kValueTest: |
1279 true_label_ = saved_false; | 1269 VisitForControl(expr->expression(), false_label_, &push_true); |
1280 false_label_ = &push_true; | |
1281 Visit(expr->expression()); | |
1282 __ bind(&push_true); | 1270 __ bind(&push_true); |
1283 __ push(Immediate(Factory::true_value())); | 1271 __ push(Immediate(Factory::true_value())); |
1284 __ jmp(saved_true); | 1272 __ jmp(true_label_); |
1285 break; | 1273 break; |
1286 | 1274 |
1287 case Expression::kTestValue: | 1275 case Expression::kTestValue: |
1288 true_label_ = &push_false; | 1276 VisitForControl(expr->expression(), &push_false, true_label_); |
1289 false_label_ = saved_true; | |
1290 Visit(expr->expression()); | |
1291 __ bind(&push_false); | 1277 __ bind(&push_false); |
1292 __ push(Immediate(Factory::false_value())); | 1278 __ push(Immediate(Factory::false_value())); |
1293 __ jmp(saved_false); | 1279 __ jmp(false_label_); |
1294 break; | 1280 break; |
1295 } | 1281 } |
1296 true_label_ = saved_true; | |
1297 false_label_ = saved_false; | |
1298 break; | 1282 break; |
1299 } | 1283 } |
1300 | 1284 |
1301 case Token::TYPEOF: { | 1285 case Token::TYPEOF: { |
1302 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 1286 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
1303 ASSERT_EQ(Expression::kValue, expr->expression()->context()); | 1287 ASSERT_EQ(Expression::kValue, expr->expression()->context()); |
1304 | 1288 |
1305 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 1289 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
1306 if (proxy != NULL && | 1290 if (proxy != NULL && |
1307 !proxy->var()->is_this() && | 1291 !proxy->var()->is_this() && |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1516 } | 1500 } |
1517 | 1501 |
1518 | 1502 |
1519 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 1503 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
1520 Comment cmnt(masm_, "[ CompareOperation"); | 1504 Comment cmnt(masm_, "[ CompareOperation"); |
1521 ASSERT_EQ(Expression::kValue, expr->left()->context()); | 1505 ASSERT_EQ(Expression::kValue, expr->left()->context()); |
1522 ASSERT_EQ(Expression::kValue, expr->right()->context()); | 1506 ASSERT_EQ(Expression::kValue, expr->right()->context()); |
1523 Visit(expr->left()); | 1507 Visit(expr->left()); |
1524 Visit(expr->right()); | 1508 Visit(expr->right()); |
1525 | 1509 |
1526 // Convert current context to test context: Pre-test code. | 1510 // Always perform the comparison for its control flow. Pack the result |
1527 Label push_true; | 1511 // into the expression's context after the comparison is performed. |
1528 Label push_false; | 1512 Label push_true, push_false, done; |
1529 Label done; | 1513 // Initially assume we are in a test context. |
1530 Label* saved_true = true_label_; | 1514 Label* if_true = true_label_; |
1531 Label* saved_false = false_label_; | 1515 Label* if_false = false_label_; |
1532 switch (expr->context()) { | 1516 switch (expr->context()) { |
1533 case Expression::kUninitialized: | 1517 case Expression::kUninitialized: |
1534 UNREACHABLE(); | 1518 UNREACHABLE(); |
1535 break; | 1519 break; |
1536 | 1520 case Expression::kEffect: |
| 1521 if_true = &done; |
| 1522 if_false = &done; |
| 1523 break; |
1537 case Expression::kValue: | 1524 case Expression::kValue: |
1538 true_label_ = &push_true; | 1525 if_true = &push_true; |
1539 false_label_ = &push_false; | 1526 if_false = &push_false; |
1540 break; | 1527 break; |
1541 | |
1542 case Expression::kEffect: | |
1543 true_label_ = &done; | |
1544 false_label_ = &done; | |
1545 break; | |
1546 | |
1547 case Expression::kTest: | 1528 case Expression::kTest: |
1548 break; | 1529 break; |
1549 | |
1550 case Expression::kValueTest: | 1530 case Expression::kValueTest: |
1551 true_label_ = &push_true; | 1531 if_true = &push_true; |
1552 break; | 1532 break; |
1553 | |
1554 case Expression::kTestValue: | 1533 case Expression::kTestValue: |
1555 false_label_ = &push_false; | 1534 if_false = &push_false; |
1556 break; | 1535 break; |
1557 } | 1536 } |
1558 // Convert current context to test context: End pre-test code. | |
1559 | 1537 |
1560 switch (expr->op()) { | 1538 switch (expr->op()) { |
1561 case Token::IN: { | 1539 case Token::IN: { |
1562 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 1540 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
1563 __ cmp(eax, Factory::true_value()); | 1541 __ cmp(eax, Factory::true_value()); |
1564 __ j(equal, true_label_); | 1542 __ j(equal, if_true); |
1565 __ jmp(false_label_); | 1543 __ jmp(if_false); |
1566 break; | 1544 break; |
1567 } | 1545 } |
1568 | 1546 |
1569 case Token::INSTANCEOF: { | 1547 case Token::INSTANCEOF: { |
1570 InstanceofStub stub; | 1548 InstanceofStub stub; |
1571 __ CallStub(&stub); | 1549 __ CallStub(&stub); |
1572 __ test(eax, Operand(eax)); | 1550 __ test(eax, Operand(eax)); |
1573 __ j(zero, true_label_); // The stub returns 0 for true. | 1551 __ j(zero, if_true); // The stub returns 0 for true. |
1574 __ jmp(false_label_); | 1552 __ jmp(if_false); |
1575 break; | 1553 break; |
1576 } | 1554 } |
1577 | 1555 |
1578 default: { | 1556 default: { |
1579 Condition cc = no_condition; | 1557 Condition cc = no_condition; |
1580 bool strict = false; | 1558 bool strict = false; |
1581 switch (expr->op()) { | 1559 switch (expr->op()) { |
1582 case Token::EQ_STRICT: | 1560 case Token::EQ_STRICT: |
1583 strict = true; | 1561 strict = true; |
1584 // Fall through | 1562 // Fall through |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 } | 1594 } |
1617 | 1595 |
1618 // The comparison stub expects the smi vs. smi case to be handled | 1596 // The comparison stub expects the smi vs. smi case to be handled |
1619 // before it is called. | 1597 // before it is called. |
1620 Label slow_case; | 1598 Label slow_case; |
1621 __ mov(ecx, Operand(edx)); | 1599 __ mov(ecx, Operand(edx)); |
1622 __ or_(ecx, Operand(eax)); | 1600 __ or_(ecx, Operand(eax)); |
1623 __ test(ecx, Immediate(kSmiTagMask)); | 1601 __ test(ecx, Immediate(kSmiTagMask)); |
1624 __ j(not_zero, &slow_case, not_taken); | 1602 __ j(not_zero, &slow_case, not_taken); |
1625 __ cmp(edx, Operand(eax)); | 1603 __ cmp(edx, Operand(eax)); |
1626 __ j(cc, true_label_); | 1604 __ j(cc, if_true); |
1627 __ jmp(false_label_); | 1605 __ jmp(if_false); |
1628 | 1606 |
1629 __ bind(&slow_case); | 1607 __ bind(&slow_case); |
1630 CompareStub stub(cc, strict); | 1608 CompareStub stub(cc, strict); |
1631 __ CallStub(&stub); | 1609 __ CallStub(&stub); |
1632 __ test(eax, Operand(eax)); | 1610 __ test(eax, Operand(eax)); |
1633 __ j(cc, true_label_); | 1611 __ j(cc, if_true); |
1634 __ jmp(false_label_); | 1612 __ jmp(if_false); |
1635 } | 1613 } |
1636 } | 1614 } |
1637 | 1615 |
1638 // Convert current context to test context: Post-test code. | 1616 // Convert the result of the comparison into one expected for this |
| 1617 // expression's context. |
1639 switch (expr->context()) { | 1618 switch (expr->context()) { |
1640 case Expression::kUninitialized: | 1619 case Expression::kUninitialized: |
1641 UNREACHABLE(); | 1620 UNREACHABLE(); |
1642 break; | 1621 break; |
1643 | 1622 |
| 1623 case Expression::kEffect: |
| 1624 __ bind(&done); |
| 1625 break; |
| 1626 |
1644 case Expression::kValue: | 1627 case Expression::kValue: |
1645 __ bind(&push_true); | 1628 __ bind(&push_true); |
1646 __ push(Immediate(Factory::true_value())); | 1629 __ push(Immediate(Factory::true_value())); |
1647 __ jmp(&done); | 1630 __ jmp(&done); |
1648 __ bind(&push_false); | 1631 __ bind(&push_false); |
1649 __ push(Immediate(Factory::false_value())); | 1632 __ push(Immediate(Factory::false_value())); |
1650 __ bind(&done); | 1633 __ bind(&done); |
1651 break; | 1634 break; |
1652 | 1635 |
1653 case Expression::kEffect: | |
1654 __ bind(&done); | |
1655 break; | |
1656 | |
1657 case Expression::kTest: | 1636 case Expression::kTest: |
1658 break; | 1637 break; |
1659 | 1638 |
1660 case Expression::kValueTest: | 1639 case Expression::kValueTest: |
1661 __ bind(&push_true); | 1640 __ bind(&push_true); |
1662 __ push(Immediate(Factory::true_value())); | 1641 __ push(Immediate(Factory::true_value())); |
1663 __ jmp(saved_true); | 1642 __ jmp(true_label_); |
1664 break; | 1643 break; |
1665 | 1644 |
1666 case Expression::kTestValue: | 1645 case Expression::kTestValue: |
1667 __ bind(&push_false); | 1646 __ bind(&push_false); |
1668 __ push(Immediate(Factory::false_value())); | 1647 __ push(Immediate(Factory::false_value())); |
1669 __ jmp(saved_false); | 1648 __ jmp(false_label_); |
1670 break; | 1649 break; |
1671 } | 1650 } |
1672 true_label_ = saved_true; | |
1673 false_label_ = saved_false; | |
1674 // Convert current context to test context: End post-test code. | |
1675 } | 1651 } |
1676 | 1652 |
1677 | 1653 |
1678 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 1654 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
1679 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1655 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1680 Apply(expr->context(), eax); | 1656 Apply(expr->context(), eax); |
1681 } | 1657 } |
1682 | 1658 |
1683 | 1659 |
1684 Register FastCodeGenerator::result_register() { return eax; } | 1660 Register FastCodeGenerator::result_register() { return eax; } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1725 __ add(Operand(edx), Immediate(masm_->CodeObject())); | 1701 __ add(Operand(edx), Immediate(masm_->CodeObject())); |
1726 __ mov(Operand(esp, 0), edx); | 1702 __ mov(Operand(esp, 0), edx); |
1727 // And return. | 1703 // And return. |
1728 __ ret(0); | 1704 __ ret(0); |
1729 } | 1705 } |
1730 | 1706 |
1731 | 1707 |
1732 #undef __ | 1708 #undef __ |
1733 | 1709 |
1734 } } // namespace v8::internal | 1710 } } // namespace v8::internal |
OLD | NEW |