| 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; | 
|  |