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 8790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8801 if (BigintOperations::FitsIntoSmi(big_value)) { | 8801 if (BigintOperations::FitsIntoSmi(big_value)) { |
8802 return BigintOperations::ToSmi(big_value); | 8802 return BigintOperations::ToSmi(big_value); |
8803 } else if (BigintOperations::FitsIntoMint(big_value)) { | 8803 } else if (BigintOperations::FitsIntoMint(big_value)) { |
8804 return Mint::New(BigintOperations::ToMint(big_value)); | 8804 return Mint::New(BigintOperations::ToMint(big_value)); |
8805 } else { | 8805 } else { |
8806 return big_value.raw(); | 8806 return big_value.raw(); |
8807 } | 8807 } |
8808 } | 8808 } |
8809 | 8809 |
8810 | 8810 |
8811 RawInteger* Integer::BinaryOp(Token::Kind operation, | 8811 RawInteger* Integer::ArithmeticOp(Token::Kind operation, |
8812 const Integer& other) const { | 8812 const Integer& other) const { |
8813 // In 32-bit mode, the result of any operation between two Smis will fit in a | 8813 // In 32-bit mode, the result of any operation between two Smis will fit in a |
8814 // 32-bit signed result, except the product of two Smis, which will be 64-bit. | 8814 // 32-bit signed result, except the product of two Smis, which will be 64-bit. |
8815 // In 64-bit mode, the result of any operation between two Smis will fit in a | 8815 // In 64-bit mode, the result of any operation between two Smis will fit in a |
8816 // 64-bit signed result, except the product of two Smis (unless the Smis are | 8816 // 64-bit signed result, except the product of two Smis (unless the Smis are |
8817 // 32-bit or less). | 8817 // 32-bit or less). |
8818 if (IsSmi() && other.IsSmi()) { | 8818 if (IsSmi() && other.IsSmi()) { |
8819 Smi& left_smi = Smi::Handle(); | 8819 Smi& left_smi = Smi::Handle(); |
8820 Smi& right_smi = Smi::Handle(); | 8820 Smi& right_smi = Smi::Handle(); |
8821 left_smi ^= raw(); | 8821 left_smi ^= raw(); |
8822 right_smi ^= other.raw(); | 8822 right_smi ^= other.raw(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8895 } | 8895 } |
8896 default: | 8896 default: |
8897 UNIMPLEMENTED(); | 8897 UNIMPLEMENTED(); |
8898 } | 8898 } |
8899 } | 8899 } |
8900 } | 8900 } |
8901 } | 8901 } |
8902 const Bigint& left_big = Bigint::Handle(AsBigint()); | 8902 const Bigint& left_big = Bigint::Handle(AsBigint()); |
8903 const Bigint& right_big = Bigint::Handle(other.AsBigint()); | 8903 const Bigint& right_big = Bigint::Handle(other.AsBigint()); |
8904 const Bigint& result = | 8904 const Bigint& result = |
8905 Bigint::Handle(left_big.BinaryOp(operation, right_big)); | 8905 Bigint::Handle(left_big.ArithmeticOp(operation, right_big)); |
8906 return Integer::Handle(result.AsInteger()).raw(); | 8906 return Integer::Handle(result.AsInteger()).raw(); |
8907 } | 8907 } |
8908 | 8908 |
8909 | 8909 |
| 8910 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { |
| 8911 return !op1.IsBigint() && !op2.IsBigint(); |
| 8912 } |
| 8913 |
| 8914 |
| 8915 RawInteger* Integer::BitOp(Token::Kind kind, const Integer& other) const { |
| 8916 if (IsSmi() && other.IsSmi()) { |
| 8917 Smi& op1 = Smi::Handle(); |
| 8918 Smi& op2 = Smi::Handle(); |
| 8919 op1 ^= raw(); |
| 8920 op2 ^= other.raw(); |
| 8921 intptr_t result = 0; |
| 8922 switch (kind) { |
| 8923 case Token::kBIT_AND: |
| 8924 result = op1.Value() & op2.Value(); |
| 8925 break; |
| 8926 case Token::kBIT_OR: |
| 8927 result = op1.Value() | op2.Value(); |
| 8928 break; |
| 8929 case Token::kBIT_XOR: |
| 8930 result = op1.Value() ^ op2.Value(); |
| 8931 break; |
| 8932 default: |
| 8933 UNIMPLEMENTED(); |
| 8934 } |
| 8935 ASSERT(Smi::IsValid(result)); |
| 8936 return Smi::New(result); |
| 8937 } else if (Are64bitOperands(*this, other)) { |
| 8938 int64_t a = AsInt64Value(); |
| 8939 int64_t b = other.AsInt64Value(); |
| 8940 switch (kind) { |
| 8941 case Token::kBIT_AND: |
| 8942 return Integer::New(a & b); |
| 8943 case Token::kBIT_OR: |
| 8944 return Integer::New(a | b); |
| 8945 case Token::kBIT_XOR: |
| 8946 return Integer::New(a ^ b); |
| 8947 default: |
| 8948 UNIMPLEMENTED(); |
| 8949 } |
| 8950 } else { |
| 8951 Bigint& op1 = Bigint::Handle(AsBigint()); |
| 8952 Bigint& op2 = Bigint::Handle(other.AsBigint()); |
| 8953 switch (kind) { |
| 8954 case Token::kBIT_AND: |
| 8955 return BigintOperations::BitAnd(op1, op2); |
| 8956 case Token::kBIT_OR: |
| 8957 return BigintOperations::BitOr(op1, op2); |
| 8958 case Token::kBIT_XOR: |
| 8959 return BigintOperations::BitXor(op1, op2); |
| 8960 default: |
| 8961 UNIMPLEMENTED(); |
| 8962 } |
| 8963 } |
| 8964 return Integer::null(); |
| 8965 } |
| 8966 |
| 8967 |
| 8968 // TODO(srdjan): Clarify handling of negative right operand in a shift op. |
| 8969 RawInteger* Smi::ShiftOp(Token::Kind kind, const Smi& other) const { |
| 8970 intptr_t result = 0; |
| 8971 const intptr_t left_value = Value(); |
| 8972 const intptr_t right_value = other.Value(); |
| 8973 ASSERT(right_value >= 0); |
| 8974 switch (kind) { |
| 8975 case Token::kSHL: { |
| 8976 if ((left_value == 0) || (right_value == 0)) { |
| 8977 return raw(); |
| 8978 } |
| 8979 { // Check for overflow. |
| 8980 int cnt = Utils::HighestBit(left_value); |
| 8981 if ((cnt + right_value) >= Smi::kBits) { |
| 8982 if ((cnt + right_value) >= Mint::kBits) { |
| 8983 return BigintOperations::ShiftLeft( |
| 8984 Bigint::Handle(AsBigint()), right_value); |
| 8985 } else { |
| 8986 int64_t left_64 = left_value; |
| 8987 return Integer::New(left_64 << right_value); |
| 8988 } |
| 8989 } |
| 8990 } |
| 8991 result = left_value << right_value; |
| 8992 break; |
| 8993 } |
| 8994 case Token::kSHR: { |
| 8995 const intptr_t shift_amount = |
| 8996 (right_value >= kBitsPerWord) ? (kBitsPerWord - 1) : right_value; |
| 8997 result = left_value >> shift_amount; |
| 8998 break; |
| 8999 } |
| 9000 default: |
| 9001 UNIMPLEMENTED(); |
| 9002 } |
| 9003 ASSERT(Smi::IsValid(result)); |
| 9004 return Smi::New(result); |
| 9005 } |
| 9006 |
| 9007 |
8910 bool Smi::Equals(const Instance& other) const { | 9008 bool Smi::Equals(const Instance& other) const { |
8911 if (other.IsNull() || !other.IsSmi()) { | 9009 if (other.IsNull() || !other.IsSmi()) { |
8912 return false; | 9010 return false; |
8913 } | 9011 } |
8914 return (this->Value() == Smi::Cast(other).Value()); | 9012 return (this->Value() == Smi::Cast(other).Value()); |
8915 } | 9013 } |
8916 | 9014 |
8917 | 9015 |
8918 double Smi::AsDoubleValue() const { | 9016 double Smi::AsDoubleValue() const { |
8919 return static_cast<double>(this->Value()); | 9017 return static_cast<double>(this->Value()); |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9222 } else { | 9320 } else { |
9223 ASSERT(IsBigint()); | 9321 ASSERT(IsBigint()); |
9224 Bigint& big = Bigint::Handle(); | 9322 Bigint& big = Bigint::Handle(); |
9225 big ^= raw(); | 9323 big ^= raw(); |
9226 ASSERT(!BigintOperations::FitsIntoSmi(big)); | 9324 ASSERT(!BigintOperations::FitsIntoSmi(big)); |
9227 return big.raw(); | 9325 return big.raw(); |
9228 } | 9326 } |
9229 } | 9327 } |
9230 | 9328 |
9231 | 9329 |
9232 RawBigint* Bigint::BinaryOp(Token::Kind operation, const Bigint& other) const { | 9330 RawBigint* Bigint::ArithmeticOp(Token::Kind operation, |
| 9331 const Bigint& other) const { |
9233 switch (operation) { | 9332 switch (operation) { |
9234 case Token::kADD: | 9333 case Token::kADD: |
9235 return BigintOperations::Add(*this, other); | 9334 return BigintOperations::Add(*this, other); |
9236 case Token::kSUB: | 9335 case Token::kSUB: |
9237 return BigintOperations::Subtract(*this, other); | 9336 return BigintOperations::Subtract(*this, other); |
9238 case Token::kMUL: | 9337 case Token::kMUL: |
9239 return BigintOperations::Multiply(*this, other); | 9338 return BigintOperations::Multiply(*this, other); |
9240 case Token::kTRUNCDIV: | 9339 case Token::kTRUNCDIV: |
9241 return BigintOperations::Divide(*this, other); | 9340 return BigintOperations::Divide(*this, other); |
9242 case Token::kMOD: | 9341 case Token::kMOD: |
(...skipping 2591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11834 } | 11933 } |
11835 return result.raw(); | 11934 return result.raw(); |
11836 } | 11935 } |
11837 | 11936 |
11838 | 11937 |
11839 const char* WeakProperty::ToCString() const { | 11938 const char* WeakProperty::ToCString() const { |
11840 return "_WeakProperty"; | 11939 return "_WeakProperty"; |
11841 } | 11940 } |
11842 | 11941 |
11843 } // namespace dart | 11942 } // namespace dart |
OLD | NEW |