| Index: vm/object.h
|
| ===================================================================
|
| --- vm/object.h (revision 4707)
|
| +++ vm/object.h (working copy)
|
| @@ -2623,8 +2623,8 @@
|
|
|
| class Bigint : public Integer {
|
| public:
|
| - virtual bool IsZero() const;
|
| - virtual bool IsNegative() const;
|
| + virtual bool IsZero() const { return raw_ptr()->signed_length_ == 0; }
|
| + virtual bool IsNegative() const { return raw_ptr()->signed_length_ < 0; }
|
|
|
| virtual bool Equals(const Instance& other) const;
|
|
|
| @@ -2633,47 +2633,60 @@
|
|
|
| virtual int CompareWith(const Integer& other) const;
|
|
|
| - static intptr_t InstanceSize(const BIGNUM* bn) {
|
| - // Danger Will Robinson! Use of OpenSSL internals!
|
| - return RoundedAllocationSize(sizeof(RawBigint)
|
| - + sizeof(BN_ULONG) * bn->top);
|
| + static intptr_t InstanceSize(intptr_t length) {
|
| + ASSERT(length >= 0);
|
| + return RoundedAllocationSize(sizeof(RawBigint) + (length * sizeof(Chunk)));
|
| }
|
| - static intptr_t InstanceSize() {
|
| - ASSERT(sizeof(RawBigint) == OFFSET_OF(RawBigint, data_));
|
| - return 0;
|
| - }
|
| + static intptr_t InstanceSize() { return 0; }
|
|
|
| - static RawBigint* New(const BIGNUM* bn, Heap::Space space = Heap::kNew);
|
| -
|
| static RawBigint* New(const String& str, Heap::Space space = Heap::kNew);
|
| static RawBigint* New(int64_t value, Heap::Space space = Heap::kNew);
|
|
|
| private:
|
| - void SetSign(bool is_negative) const;
|
| + typedef uint32_t Chunk;
|
| + typedef uint64_t DoubleChunk;
|
| + static const int kChunkSize = sizeof(Chunk);
|
|
|
| - void ToggleSign() const {
|
| - BIGNUM* bn = MutableBNAddr();
|
| - // Danger Will Robinson! Use of OpenSSL internals!
|
| - // FIXME(benl): can be changed to use BN_set_negative() on more
|
| - // recent OpenSSL releases (> 1.0.0).
|
| - SetSign(!bn->neg);
|
| + Chunk GetChunkAt(intptr_t i) const {
|
| + return *ChunkAddr(i);
|
| }
|
|
|
| - BIGNUM* MutableBNAddr() const {
|
| - // Fix up internals as we may have been moved.
|
| - raw_ptr()->bn_.d = BNMemory();
|
| + void SetChunkAt(intptr_t i, Chunk newValue) const {
|
| + *ChunkAddr(i) = newValue;
|
| + }
|
|
|
| - return &raw_ptr()->bn_;
|
| + intptr_t Length() const {
|
| + intptr_t signed_length = raw_ptr()->signed_length_;
|
| + return Utils::Abs(signed_length);
|
| }
|
| - const BIGNUM* BNAddr() const { return MutableBNAddr(); }
|
| - BN_ULONG* BNMemory() const {
|
| - return &raw_ptr()->data_[0];
|
| +
|
| + // SetLength does not change the sign.
|
| + void SetLength(intptr_t length) const {
|
| + ASSERT(length >= 0);
|
| + bool is_negative = IsNegative();
|
| + raw_ptr()->signed_length_ = length;
|
| + if (is_negative) ToggleSign();
|
| }
|
|
|
| - int NumberOfBits() const { return BN_num_bits(BNAddr()); }
|
| - bool IsBitSet(intptr_t bit) const { return Bit(bit) == 1; }
|
| - int Bit(intptr_t bit) const { return BN_is_bit_set(BNAddr(), bit); }
|
| + void SetSign(bool is_negative) const {
|
| + if (is_negative != IsNegative()) {
|
| + ToggleSign();
|
| + }
|
| + }
|
|
|
| + void ToggleSign() const {
|
| + raw_ptr()->signed_length_ = -raw_ptr()->signed_length_;
|
| + }
|
| +
|
| + Chunk* ChunkAddr(intptr_t index) const {
|
| + ASSERT(0 <= index);
|
| + ASSERT(index < Length());
|
| + uword digits_start = reinterpret_cast<uword>(raw_ptr()) + sizeof(RawBigint);
|
| + return &(reinterpret_cast<Chunk*>(digits_start)[index]);
|
| + }
|
| +
|
| + static RawBigint* Allocate(intptr_t length, Heap::Space space = Heap::kNew);
|
| +
|
| HEAP_OBJECT_IMPLEMENTATION(Bigint, Integer);
|
| friend class Class;
|
| friend class BigintOperations;
|
|
|