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