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 |
Ivan Posva
2012/02/28 01:38:34
Extra line?
siva
2012/02/28 18:22:18
Removed.
On 2012/02/28 01:38:34, Ivan Posva wrote
| |
25 | |
32 // The given string must be a nul-terminated string of hex-digits. It must | 26 // 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. | 27 // only contain hex-digits. No sign or leading "0x" is allowed. |
34 static RawBigint* FromHexCString(const char* str, | 28 static RawBigint* FromHexCString(const char* str, |
35 Heap::Space space = Heap::kNew); | 29 Heap::Space space = Heap::kNew); |
30 | |
36 // The given string must be a nul-terminated string of decimal digits. It | 31 // 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 | 32 // must only contain decimal digits (0-9). No sign is allowed. Leading |
38 // zeroes are ignored. | 33 // zeroes are ignored. |
39 static RawBigint* FromDecimalCString(const char* str, | 34 static RawBigint* FromDecimalCString(const char* str, |
40 Heap::Space space = Heap::kNew); | 35 Heap::Space space = Heap::kNew); |
41 // Converts the bigint to a string. The returned string is prepended by | 36 |
37 // Converts the bigint to a HEX string. The returned string is prepended by | |
42 // a "0x" (after the optional minus-sign). | 38 // a "0x" (after the optional minus-sign). |
43 static const char* ToHexCString(const BIGNUM* bn, | 39 static const char* ToHexCString(intptr_t length, |
44 uword (*allocator)(intptr_t size)); | 40 bool is_negative, |
45 static const char* ToHexCString(const Bigint& bigint, | 41 void* data, |
46 uword (*allocator)(intptr_t size)); | 42 uword (*allocator)(intptr_t size)); |
47 | 43 |
48 // Converts the bigint to a string. | 44 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)); | 45 uword (*allocator)(intptr_t size)); |
53 | 46 |
54 static bool FitsIntoSmi(const Bigint& bigint); | 47 static bool FitsIntoSmi(const Bigint& bigint); |
55 static RawSmi* ToSmi(const Bigint& bigint); | 48 static RawSmi* ToSmi(const Bigint& bigint); |
56 | 49 |
57 static bool FitsIntoInt64(const Bigint& bigint); | 50 static bool FitsIntoInt64(const Bigint& bigint); |
58 static int64_t ToInt64(const Bigint& bigint); | 51 static int64_t ToInt64(const Bigint& bigint); |
59 | 52 |
60 static bool FitsIntoUint64(const Bigint& bigint); | 53 static bool FitsIntoUint64(const Bigint& bigint); |
61 static uint64_t ToUint64(const Bigint& bigint); | 54 static uint64_t ToUint64(const Bigint& bigint); |
62 static uint64_t AbsToUint64(const Bigint& bigint); | 55 static uint64_t AbsToUint64(const Bigint& bigint); |
63 | 56 |
64 static RawDouble* ToDouble(const Bigint& bigint); | 57 static RawDouble* ToDouble(const Bigint& bigint); |
65 | 58 |
66 static RawBigint* Add(const Bigint& a, const Bigint& b); | 59 static RawBigint* Add(const Bigint& a, const Bigint& b) { |
67 static RawBigint* Subtract(const Bigint& a, const Bigint& b); | 60 bool negate_b = false; |
61 return AddSubtract(a, b, negate_b); | |
62 } | |
63 static RawBigint* Subtract(const Bigint& a, const Bigint& b) { | |
64 bool negate_b = true; | |
65 return AddSubtract(a, b, negate_b); | |
66 } | |
68 static RawBigint* Multiply(const Bigint& a, const Bigint& b); | 67 static RawBigint* Multiply(const Bigint& a, const Bigint& b); |
69 // TODO(floitsch): what to do for divisions by zero. | 68 // TODO(floitsch): what to do for divisions by zero. |
70 static RawBigint* Divide(const Bigint& a, const Bigint& b); | 69 static RawBigint* Divide(const Bigint& a, const Bigint& b); |
71 static RawBigint* Modulo(const Bigint& a, const Bigint& b); | 70 static RawBigint* Modulo(const Bigint& a, const Bigint& b); |
72 static RawBigint* Remainder(const Bigint& a, const Bigint& b); | 71 static RawBigint* Remainder(const Bigint& a, const Bigint& b); |
73 | 72 |
74 static RawBigint* ShiftLeft(const Bigint& bigint, intptr_t amount); | 73 static RawBigint* ShiftLeft(const Bigint& bigint, intptr_t amount); |
75 static RawBigint* ShiftRight(const Bigint& bigint, intptr_t amount); | 74 static RawBigint* ShiftRight(const Bigint& bigint, intptr_t amount); |
76 static RawBigint* BitAnd(const Bigint& a, const Bigint& b); | 75 static RawBigint* BitAnd(const Bigint& a, const Bigint& b); |
77 static RawBigint* BitOr(const Bigint& a, const Bigint& b); | 76 static RawBigint* BitOr(const Bigint& a, const Bigint& b); |
78 static RawBigint* BitXor(const Bigint& a, const Bigint& b); | 77 static RawBigint* BitXor(const Bigint& a, const Bigint& b); |
79 static RawBigint* BitNot(const Bigint& bigint); | 78 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 | 79 |
84 static int Compare(const Bigint& a, const Bigint& b); | 80 static int Compare(const Bigint& a, const Bigint& b); |
85 | 81 |
82 static bool IsClamped(const Bigint& bigint) { | |
83 intptr_t length = bigint.Length(); | |
84 return (length == 0) || (bigint.GetChunkAt(length - 1) != 0); | |
85 } | |
86 | 86 |
87 private: | 87 private: |
88 static BIGNUM* TmpBN(); | 88 typedef Bigint::Chunk Chunk; |
89 static BN_CTX* TmpBNCtx(); | 89 typedef Bigint::DoubleChunk DoubleChunk; |
90 | 90 |
91 static const int kDigitBitSize = 28; | |
92 static const Chunk kDigitMask = (static_cast<Chunk>(1) << kDigitBitSize) - 1; | |
93 static const Chunk kDigitMaxValue = kDigitMask; | |
94 static const int kChunkSize = sizeof(Chunk); | |
95 static const int kChunkBitSize = kChunkSize * kBitsPerByte; | |
96 | |
97 static RawBigint* Zero() { return Bigint::Allocate(0); } | |
91 static RawBigint* One() { | 98 static RawBigint* One() { |
92 Bigint& result = Bigint::Handle(NewFromInt64(1)); | 99 Bigint& result = Bigint::Handle(Bigint::Allocate(1)); |
100 result.SetChunkAt(0, 1); | |
93 return result.raw(); | 101 return result.raw(); |
94 } | 102 } |
95 static RawBigint* BitTT(const Bigint& a, const Bigint& b, bool tt[4]); | 103 static RawBigint* MinusOne() { |
96 // The following function only works for bit-and and bit-or. | 104 Bigint& result = Bigint::Handle(One()); |
97 static RawSmi* BitOpWithSmi(Token::Kind kind, | 105 result.ToggleSign(); |
98 const Bigint& bigint, | 106 return result.raw(); |
99 const Smi& smi); | 107 } |
108 | |
109 // Performs an addition or subtraction depending on the negate_b argument. | |
110 static RawBigint* AddSubtract(const Bigint& a, | |
111 const Bigint& b, | |
112 bool negate_b); | |
113 | |
114 static int UnsignedCompare(const Bigint& a, const Bigint& b); | |
115 static int UnsignedCompareNonClamped(const Bigint& a, const Bigint& b); | |
116 static RawBigint* UnsignedAdd(const Bigint& a, const Bigint& b); | |
117 static RawBigint* UnsignedSubtract(const Bigint& a, const Bigint& b); | |
118 | |
119 static RawBigint* MultiplyWithDigit(const Bigint& bigint, Chunk digit); | |
120 static RawBigint* DigitsShiftLeft(const Bigint& bigint, intptr_t amount) { | |
121 return ShiftLeft(bigint, amount * kDigitBitSize); | |
122 } | |
123 static void DivideRemainder(const Bigint& a, const Bigint& b, | |
124 Bigint* quotient, Bigint* remainder); | |
125 | |
126 // Removes leading zero-chunks by adjusting the bigint's length. | |
127 static void Clamp(const Bigint& bigint); | |
128 | |
129 static RawBigint* Copy(const Bigint& bigint); | |
130 | |
131 static int CountBits(Chunk digit); | |
100 | 132 |
101 DISALLOW_IMPLICIT_CONSTRUCTORS(BigintOperations); | 133 DISALLOW_IMPLICIT_CONSTRUCTORS(BigintOperations); |
102 }; | 134 }; |
103 | 135 |
104 } // namespace dart | 136 } // namespace dart |
105 | 137 |
106 #endif // VM_BIGINT_OPERATIONS_H_ | 138 #endif // VM_BIGINT_OPERATIONS_H_ |
OLD | NEW |