| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
| 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. | |
| 4 | 2 |
| 5 #ifndef VM_BIGINT_OPERATIONS_H_ | 3 #ifndef VM_BIGINT_OPERATIONS_H_ |
| 6 #define VM_BIGINT_OPERATIONS_H_ | 4 #define VM_BIGINT_OPERATIONS_H_ |
| 7 | 5 |
| 8 #include "vm/heap.h" | 6 #include "platform/utils.h" |
| 7 |
| 9 #include "vm/object.h" | 8 #include "vm/object.h" |
| 10 #include "vm/token.h" | |
| 11 | |
| 12 // This should be folded into OpenSSL | |
| 13 #undef BN_abs_is_word | |
| 14 #define BN_abs_is_word(a, w) (((a)->top == 1) \ | |
| 15 && ((a)->d[0] == static_cast<BN_ULONG>(w))) | |
| 16 | 9 |
| 17 namespace dart { | 10 namespace dart { |
| 18 | 11 |
| 19 class BigintOperations : public AllStatic { | 12 class BigintOperations : public AllStatic { |
| 20 public: | 13 public: |
| 21 static RawBigint* NewFromSmi(const Smi& smi, Heap::Space space = Heap::kNew); | 14 static RawBigint* NewFromSmi(const Smi& smi, Heap::Space space = Heap::kNew); |
| 22 static RawBigint* NewFromInt64(int64_t value, Heap::Space space = Heap::kNew); | 15 static RawBigint* NewFromInt64(int64_t value, Heap::Space space = Heap::kNew); |
| 23 static RawBigint* NewFromUint64(uint64_t value, | 16 static RawBigint* NewFromUint64(uint64_t value, |
| 24 Heap::Space space = Heap::kNew); | 17 Heap::Space space = Heap::kNew); |
| 25 // The given string must be a valid integer representation. It may be | 18 // The given string must be a valid integer representation. It may be |
| 26 // prefixed by a minus and/or "0x". | 19 // prefixed by a minus and/or "0x". |
| 27 // Returns Bigint::null() if the string cannot be parsed. | 20 // Returns Bigint::null() if the string cannot be parsed. |
| 28 static RawBigint* NewFromCString(const char* str, | 21 static RawBigint* NewFromCString(const char* str, |
| 29 Heap::Space space = Heap::kNew); | 22 Heap::Space space = Heap::kNew); |
| 30 static RawBigint* NewFromDouble(double d, Heap::Space space = Heap::kNew); | 23 static RawBigint* NewFromDouble(double d, Heap::Space space = Heap::kNew); |
| 31 | 24 |
| 32 // The given string must be a nul-terminated string of hex-digits. It must | 25 // The given string must be a nul-terminated string of hex-digits. It must |
| 33 // only contain hex-digits. No sign or leading "0x" is allowed. | 26 // only contain hex-digits. No sign or leading "0x" is allowed. |
| 34 static RawBigint* FromHexCString(const char* str, | 27 static RawBigint* FromHexCString(const char* str, |
| 35 Heap::Space space = Heap::kNew); | 28 Heap::Space space = Heap::kNew); |
| 29 |
| 36 // The given string must be a nul-terminated string of decimal digits. It | 30 // The given string must be a nul-terminated string of decimal digits. It |
| 37 // must only contain decimal digits (0-9). No sign is allowed. Leading | 31 // must only contain decimal digits (0-9). No sign is allowed. Leading |
| 38 // zeroes are ignored. | 32 // zeroes are ignored. |
| 39 static RawBigint* FromDecimalCString(const char* str, | 33 static RawBigint* FromDecimalCString(const char* str, |
| 40 Heap::Space space = Heap::kNew); | 34 Heap::Space space = Heap::kNew); |
| 41 // Converts the bigint to a string. The returned string is prepended by | 35 |
| 36 // Converts the bigint to a HEX string. The returned string is prepended by |
| 42 // a "0x" (after the optional minus-sign). | 37 // a "0x" (after the optional minus-sign). |
| 43 static const char* ToHexCString(const BIGNUM* bn, | 38 static const char* ToHexCString(intptr_t length, |
| 44 uword (*allocator)(intptr_t size)); | 39 bool is_negative, |
| 45 static const char* ToHexCString(const Bigint& bigint, | 40 void* data, |
| 46 uword (*allocator)(intptr_t size)); | 41 uword (*allocator)(intptr_t size)); |
| 47 | 42 |
| 48 // Converts the bigint to a string. | 43 static const char* ToHexCString(const Bigint& bigint, |
| 49 static const char* ToDecCString(const BIGNUM* bn, | |
| 50 uword (*allocator)(intptr_t size)); | |
| 51 static const char* ToDecCString(const Bigint& bigint, | |
| 52 uword (*allocator)(intptr_t size)); | 44 uword (*allocator)(intptr_t size)); |
| 53 | 45 |
| 54 static bool FitsIntoSmi(const Bigint& bigint); | 46 static bool FitsIntoSmi(const Bigint& bigint); |
| 55 static RawSmi* ToSmi(const Bigint& bigint); | 47 static RawSmi* ToSmi(const Bigint& bigint); |
| 56 | 48 |
| 57 static bool FitsIntoInt64(const Bigint& bigint); | 49 static bool FitsIntoMint(const Bigint& bigint); |
| 58 static int64_t ToInt64(const Bigint& bigint); | 50 static int64_t ToMint(const Bigint& bigint); |
| 59 | 51 |
| 60 static bool FitsIntoUint64(const Bigint& bigint); | 52 static bool FitsIntoUint64(const Bigint& bigint); |
| 61 static uint64_t ToUint64(const Bigint& bigint); | 53 static uint64_t ToUint64(const Bigint& bigint); |
| 62 static uint64_t AbsToUint64(const Bigint& bigint); | 54 static uint64_t AbsToUint64(const Bigint& bigint); |
| 63 | 55 |
| 64 static RawDouble* ToDouble(const Bigint& bigint); | 56 static RawDouble* ToDouble(const Bigint& bigint); |
| 65 | 57 |
| 66 static RawBigint* Add(const Bigint& a, const Bigint& b); | 58 static RawBigint* Add(const Bigint& a, const Bigint& b) { |
| 67 static RawBigint* Subtract(const Bigint& a, const Bigint& b); | 59 bool negate_b = false; |
| 60 return AddSubtract(a, b, negate_b); |
| 61 } |
| 62 static RawBigint* Subtract(const Bigint& a, const Bigint& b) { |
| 63 bool negate_b = true; |
| 64 return AddSubtract(a, b, negate_b); |
| 65 } |
| 68 static RawBigint* Multiply(const Bigint& a, const Bigint& b); | 66 static RawBigint* Multiply(const Bigint& a, const Bigint& b); |
| 69 // TODO(floitsch): what to do for divisions by zero. | 67 // TODO(floitsch): what to do for divisions by zero. |
| 70 static RawBigint* Divide(const Bigint& a, const Bigint& b); | 68 static RawBigint* Divide(const Bigint& a, const Bigint& b); |
| 71 static RawBigint* Modulo(const Bigint& a, const Bigint& b); | 69 static RawBigint* Modulo(const Bigint& a, const Bigint& b); |
| 72 static RawBigint* Remainder(const Bigint& a, const Bigint& b); | 70 static RawBigint* Remainder(const Bigint& a, const Bigint& b); |
| 73 | 71 |
| 74 static RawBigint* ShiftLeft(const Bigint& bigint, intptr_t amount); | 72 static RawBigint* ShiftLeft(const Bigint& bigint, intptr_t amount); |
| 75 static RawBigint* ShiftRight(const Bigint& bigint, intptr_t amount); | 73 static RawBigint* ShiftRight(const Bigint& bigint, intptr_t amount); |
| 76 static RawBigint* BitAnd(const Bigint& a, const Bigint& b); | 74 static RawBigint* BitAnd(const Bigint& a, const Bigint& b); |
| 77 static RawBigint* BitOr(const Bigint& a, const Bigint& b); | 75 static RawBigint* BitOr(const Bigint& a, const Bigint& b); |
| 78 static RawBigint* BitXor(const Bigint& a, const Bigint& b); | 76 static RawBigint* BitXor(const Bigint& a, const Bigint& b); |
| 79 static RawBigint* BitNot(const Bigint& bigint); | 77 static RawBigint* BitNot(const Bigint& bigint); |
| 80 static RawInteger* BitAndWithSmi(const Bigint& bigint, const Smi& smi); | |
| 81 static RawInteger* BitOrWithSmi(const Bigint& bigint, const Smi& smi); | |
| 82 static RawInteger* BitXorWithSmi(const Bigint& bigint, const Smi& smi); | |
| 83 | 78 |
| 84 static int Compare(const Bigint& a, const Bigint& b); | 79 static int Compare(const Bigint& a, const Bigint& b); |
| 85 | 80 |
| 81 static bool IsClamped(const Bigint& bigint) { |
| 82 intptr_t length = bigint.Length(); |
| 83 return (length == 0) || (bigint.GetChunkAt(length - 1) != 0); |
| 84 } |
| 86 | 85 |
| 87 private: | 86 private: |
| 88 static BIGNUM* TmpBN(); | 87 typedef Bigint::Chunk Chunk; |
| 89 static BN_CTX* TmpBNCtx(); | 88 typedef Bigint::DoubleChunk DoubleChunk; |
| 90 | 89 |
| 90 static const int kDigitBitSize = 28; |
| 91 static const Chunk kDigitMask = (static_cast<Chunk>(1) << kDigitBitSize) - 1; |
| 92 static const Chunk kDigitMaxValue = kDigitMask; |
| 93 static const int kChunkSize = sizeof(Chunk); |
| 94 static const int kChunkBitSize = kChunkSize * kBitsPerByte; |
| 95 |
| 96 static RawBigint* Zero() { return Bigint::Allocate(0); } |
| 91 static RawBigint* One() { | 97 static RawBigint* One() { |
| 92 Bigint& result = Bigint::Handle(NewFromInt64(1)); | 98 Bigint& result = Bigint::Handle(Bigint::Allocate(1)); |
| 99 result.SetChunkAt(0, 1); |
| 93 return result.raw(); | 100 return result.raw(); |
| 94 } | 101 } |
| 95 static RawBigint* BitTT(const Bigint& a, const Bigint& b, bool tt[4]); | 102 static RawBigint* MinusOne() { |
| 96 // The following function only works for bit-and and bit-or. | 103 Bigint& result = Bigint::Handle(One()); |
| 97 static RawSmi* BitOpWithSmi(Token::Kind kind, | 104 result.ToggleSign(); |
| 98 const Bigint& bigint, | 105 return result.raw(); |
| 99 const Smi& smi); | 106 } |
| 107 |
| 108 // Performs an addition or subtraction depending on the negate_b argument. |
| 109 static RawBigint* AddSubtract(const Bigint& a, |
| 110 const Bigint& b, |
| 111 bool negate_b); |
| 112 |
| 113 static int UnsignedCompare(const Bigint& a, const Bigint& b); |
| 114 static int UnsignedCompareNonClamped(const Bigint& a, const Bigint& b); |
| 115 static RawBigint* UnsignedAdd(const Bigint& a, const Bigint& b); |
| 116 static RawBigint* UnsignedSubtract(const Bigint& a, const Bigint& b); |
| 117 |
| 118 static RawBigint* MultiplyWithDigit(const Bigint& bigint, Chunk digit); |
| 119 static RawBigint* DigitsShiftLeft(const Bigint& bigint, intptr_t amount) { |
| 120 return ShiftLeft(bigint, amount * kDigitBitSize); |
| 121 } |
| 122 static void DivideRemainder(const Bigint& a, const Bigint& b, |
| 123 Bigint* quotient, Bigint* remainder); |
| 124 |
| 125 // Removes leading zero-chunks by adjusting the bigint's length. |
| 126 static void Clamp(const Bigint& bigint); |
| 127 |
| 128 static RawBigint* Copy(const Bigint& bigint); |
| 129 |
| 130 static int CountBits(Chunk digit); |
| 100 | 131 |
| 101 DISALLOW_IMPLICIT_CONSTRUCTORS(BigintOperations); | 132 DISALLOW_IMPLICIT_CONSTRUCTORS(BigintOperations); |
| 102 }; | 133 }; |
| 103 | 134 |
| 104 } // namespace dart | 135 } // namespace dart |
| 105 | 136 |
| 106 #endif // VM_BIGINT_OPERATIONS_H_ | 137 #endif // VM_BIGINT_OPERATIONS_H_ |
| OLD | NEW |