| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 8734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8745 return 0; | 8745 return 0; |
| 8746 } | 8746 } |
| 8747 | 8747 |
| 8748 | 8748 |
| 8749 int Integer::CompareWith(const Integer& other) const { | 8749 int Integer::CompareWith(const Integer& other) const { |
| 8750 UNIMPLEMENTED(); | 8750 UNIMPLEMENTED(); |
| 8751 return 0; | 8751 return 0; |
| 8752 } | 8752 } |
| 8753 | 8753 |
| 8754 | 8754 |
| 8755 // Return the most compact presentation of an integer. | |
| 8756 RawInteger* Integer::AsInteger(const Integer& value) { | |
| 8757 if (value.IsSmi()) return value.raw(); | |
| 8758 if (value.IsMint()) { | |
| 8759 Mint& mint = Mint::Handle(); | |
| 8760 mint ^= value.raw(); | |
| 8761 if (Smi::IsValid64(mint.value())) { | |
| 8762 return Smi::New(mint.value()); | |
| 8763 } else { | |
| 8764 return value.raw(); | |
| 8765 } | |
| 8766 } | |
| 8767 ASSERT(value.IsBigint()); | |
| 8768 Bigint& big_value = Bigint::Handle(); | |
| 8769 big_value ^= value.raw(); | |
| 8770 if (BigintOperations::FitsIntoSmi(big_value)) { | |
| 8771 return BigintOperations::ToSmi(big_value); | |
| 8772 } else if (BigintOperations::FitsIntoMint(big_value)) { | |
| 8773 return Mint::New(BigintOperations::ToMint(big_value)); | |
| 8774 } else { | |
| 8775 return big_value.raw(); | |
| 8776 } | |
| 8777 } | |
| 8778 | |
| 8779 | |
| 8780 RawInteger* Integer::BinaryOp(Token::Kind operation, | |
| 8781 const Integer& left, | |
| 8782 const Integer& right) { | |
| 8783 // In 32-bit mode, the result of any operation between two Smis will fit in a | |
| 8784 // 32-bit signed result, except the product of two Smis, which will be 64-bit. | |
| 8785 // In 64-bit mode, the result of any operation between two Smis will fit in a | |
| 8786 // 64-bit signed result, except the product of two Smis (unless the Smis are | |
| 8787 // 32-bit or less). | |
| 8788 if (left.IsSmi() && right.IsSmi()) { | |
| 8789 Smi& left_smi = Smi::Handle(); | |
| 8790 Smi& right_smi = Smi::Handle(); | |
| 8791 left_smi ^= left.raw(); | |
| 8792 right_smi ^= right.raw(); | |
| 8793 const intptr_t left_value = left_smi.Value(); | |
| 8794 const intptr_t right_value = right_smi.Value(); | |
| 8795 switch (operation) { | |
| 8796 case Token::kADD: | |
| 8797 return Integer::New(left_value + right_value); | |
| 8798 case Token::kSUB: | |
| 8799 return Integer::New(left_value - right_value); | |
| 8800 case Token::kMUL: { | |
| 8801 if (Smi::kBits < 32) { | |
| 8802 // In 32-bit mode, the product of two Smis fits in a 64-bit result. | |
| 8803 return Integer::New(static_cast<int64_t>(left_value) * | |
| 8804 static_cast<int64_t>(right_value)); | |
| 8805 } else { | |
| 8806 // In 64-bit mode, the product of two 32-bit signed integers fits in a | |
| 8807 // 64-bit result. | |
| 8808 ASSERT(sizeof(intptr_t) == sizeof(int64_t)); | |
| 8809 if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) { | |
| 8810 return Integer::New(left_value * right_value); | |
| 8811 } | |
| 8812 } | |
| 8813 // Perform a Bigint multiplication below. | |
| 8814 break; | |
| 8815 } | |
| 8816 case Token::kTRUNCDIV: | |
| 8817 return Integer::New(left_value / right_value); | |
| 8818 case Token::kMOD: { | |
| 8819 const intptr_t remainder = left_value % right_value; | |
| 8820 if (remainder < 0) { | |
| 8821 if (right_value < 0) { | |
| 8822 return Integer::New(remainder - right_value); | |
| 8823 } else { | |
| 8824 return Integer::New(remainder + right_value); | |
| 8825 } | |
| 8826 } | |
| 8827 return Integer::New(remainder); | |
| 8828 } | |
| 8829 default: | |
| 8830 UNIMPLEMENTED(); | |
| 8831 } | |
| 8832 } | |
| 8833 // In 32-bit mode, the result of any operation between two 63-bit signed | |
| 8834 // integers (or 32-bit for multiplication) will fit in a 64-bit signed result. | |
| 8835 // In 64-bit mode, 63-bit signed integers are Smis, already processed above. | |
| 8836 if ((Smi::kBits < 32) && !left.IsBigint() && !right.IsBigint()) { | |
| 8837 const int64_t left_value = left.AsInt64Value(); | |
| 8838 if (Utils::IsInt(63, left_value)) { | |
| 8839 const int64_t right_value = right.AsInt64Value(); | |
| 8840 if (Utils::IsInt(63, right_value)) { | |
| 8841 switch (operation) { | |
| 8842 case Token::kADD: | |
| 8843 return Integer::New(left_value + right_value); | |
| 8844 case Token::kSUB: | |
| 8845 return Integer::New(left_value - right_value); | |
| 8846 case Token::kMUL: { | |
| 8847 if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) { | |
| 8848 return Integer::New(left_value * right_value); | |
| 8849 } | |
| 8850 // Perform a Bigint multiplication below. | |
| 8851 break; | |
| 8852 } | |
| 8853 case Token::kTRUNCDIV: | |
| 8854 return Integer::New(left_value / right_value); | |
| 8855 case Token::kMOD: { | |
| 8856 const int64_t remainder = left_value % right_value; | |
| 8857 if (remainder < 0) { | |
| 8858 if (right_value < 0) { | |
| 8859 return Integer::New(remainder - right_value); | |
| 8860 } else { | |
| 8861 return Integer::New(remainder + right_value); | |
| 8862 } | |
| 8863 } | |
| 8864 return Integer::New(remainder); | |
| 8865 } | |
| 8866 default: | |
| 8867 UNIMPLEMENTED(); | |
| 8868 } | |
| 8869 } | |
| 8870 } | |
| 8871 } | |
| 8872 const Bigint& left_big = Bigint::Handle(Bigint::AsBigint(left)); | |
| 8873 const Bigint& right_big = Bigint::Handle(Bigint::AsBigint(right)); | |
| 8874 const Bigint& result = | |
| 8875 Bigint::Handle(Bigint::BinaryOp(operation, left_big, right_big)); | |
| 8876 return Integer::Handle(AsInteger(result)).raw(); | |
| 8877 } | |
| 8878 | |
| 8879 | |
| 8880 bool Smi::Equals(const Instance& other) const { | 8755 bool Smi::Equals(const Instance& other) const { |
| 8881 if (other.IsNull() || !other.IsSmi()) { | 8756 if (other.IsNull() || !other.IsSmi()) { |
| 8882 return false; | 8757 return false; |
| 8883 } | 8758 } |
| 8884 return (this->Value() == Smi::Cast(other).Value()); | 8759 return (this->Value() == Smi::Cast(other).Value()); |
| 8885 } | 8760 } |
| 8886 | 8761 |
| 8887 | 8762 |
| 8888 double Smi::AsDoubleValue() const { | 8763 double Smi::AsDoubleValue() const { |
| 8889 return static_cast<double>(this->Value()); | 8764 return static_cast<double>(this->Value()); |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9172 return value() < 0 ? "-Infinity" : "Infinity"; | 9047 return value() < 0 ? "-Infinity" : "Infinity"; |
| 9173 } | 9048 } |
| 9174 const int kBufferSize = 128; | 9049 const int kBufferSize = 128; |
| 9175 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(kBufferSize); | 9050 char* buffer = Isolate::Current()->current_zone()->Alloc<char>(kBufferSize); |
| 9176 buffer[kBufferSize - 1] = '\0'; | 9051 buffer[kBufferSize - 1] = '\0'; |
| 9177 DoubleToCString(value(), buffer, kBufferSize); | 9052 DoubleToCString(value(), buffer, kBufferSize); |
| 9178 return buffer; | 9053 return buffer; |
| 9179 } | 9054 } |
| 9180 | 9055 |
| 9181 | 9056 |
| 9182 // Returns value in form of a RawBigint. | |
| 9183 RawBigint* Bigint::AsBigint(const Integer& value) { | |
| 9184 ASSERT(!value.IsNull()); | |
| 9185 if (value.IsSmi()) { | |
| 9186 Smi& smi = Smi::Handle(); | |
| 9187 smi ^= value.raw(); | |
| 9188 return BigintOperations::NewFromSmi(smi); | |
| 9189 } else if (value.IsMint()) { | |
| 9190 Mint& mint = Mint::Handle(); | |
| 9191 mint ^= value.raw(); | |
| 9192 return BigintOperations::NewFromInt64(mint.value()); | |
| 9193 } else { | |
| 9194 ASSERT(value.IsBigint()); | |
| 9195 Bigint& big = Bigint::Handle(); | |
| 9196 big ^= value.raw(); | |
| 9197 ASSERT(!BigintOperations::FitsIntoSmi(big)); | |
| 9198 return big.raw(); | |
| 9199 } | |
| 9200 } | |
| 9201 | |
| 9202 | |
| 9203 RawBigint* Bigint::BinaryOp(Token::Kind operation, | |
| 9204 const Bigint& left, | |
| 9205 const Bigint& right) { | |
| 9206 switch (operation) { | |
| 9207 case Token::kADD: | |
| 9208 return BigintOperations::Add(left, right); | |
| 9209 case Token::kSUB: | |
| 9210 return BigintOperations::Subtract(left, right); | |
| 9211 case Token::kMUL: | |
| 9212 return BigintOperations::Multiply(left, right); | |
| 9213 case Token::kTRUNCDIV: | |
| 9214 return BigintOperations::Divide(left, right); | |
| 9215 case Token::kMOD: | |
| 9216 return BigintOperations::Modulo(left, right); | |
| 9217 default: | |
| 9218 UNIMPLEMENTED(); | |
| 9219 return Bigint::null(); | |
| 9220 } | |
| 9221 } | |
| 9222 | |
| 9223 | |
| 9224 bool Bigint::Equals(const Instance& other) const { | 9057 bool Bigint::Equals(const Instance& other) const { |
| 9225 if (this->raw() == other.raw()) { | 9058 if (this->raw() == other.raw()) { |
| 9226 // Both handles point to the same raw instance. | 9059 // Both handles point to the same raw instance. |
| 9227 return true; | 9060 return true; |
| 9228 } | 9061 } |
| 9229 | 9062 |
| 9230 if (!other.IsBigint() || other.IsNull()) { | 9063 if (!other.IsBigint() || other.IsNull()) { |
| 9231 return false; | 9064 return false; |
| 9232 } | 9065 } |
| 9233 | 9066 |
| (...skipping 2573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11807 } | 11640 } |
| 11808 return result.raw(); | 11641 return result.raw(); |
| 11809 } | 11642 } |
| 11810 | 11643 |
| 11811 | 11644 |
| 11812 const char* WeakProperty::ToCString() const { | 11645 const char* WeakProperty::ToCString() const { |
| 11813 return "_WeakProperty"; | 11646 return "_WeakProperty"; |
| 11814 } | 11647 } |
| 11815 | 11648 |
| 11816 } // namespace dart | 11649 } // namespace dart |
| OLD | NEW |