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 "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 5934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5945 // Integer is an interface. No instances of Integer should exist. | 5945 // Integer is an interface. No instances of Integer should exist. |
5946 UNREACHABLE(); | 5946 UNREACHABLE(); |
5947 return "Integer"; | 5947 return "Integer"; |
5948 } | 5948 } |
5949 | 5949 |
5950 | 5950 |
5951 RawInteger* Integer::New(const String& str) { | 5951 RawInteger* Integer::New(const String& str) { |
5952 const Bigint& big = Bigint::Handle(Bigint::New(str)); | 5952 const Bigint& big = Bigint::Handle(Bigint::New(str)); |
5953 if (BigintOperations::FitsIntoSmi(big)) { | 5953 if (BigintOperations::FitsIntoSmi(big)) { |
5954 return BigintOperations::ToSmi(big); | 5954 return BigintOperations::ToSmi(big); |
5955 } else if (BigintOperations::FitsIntoInt64(big)) { | 5955 } else if (BigintOperations::FitsIntoMint(big)) { |
5956 return Mint::New(BigintOperations::ToInt64(big)); | 5956 return Mint::New(BigintOperations::ToMint(big)); |
5957 } else { | 5957 } else { |
5958 return big.raw(); | 5958 return big.raw(); |
5959 } | 5959 } |
5960 } | 5960 } |
5961 | 5961 |
5962 | 5962 |
5963 RawInteger* Integer::New(int64_t value) { | 5963 RawInteger* Integer::New(int64_t value) { |
5964 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { | 5964 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { |
5965 return Smi::New(value); | 5965 return Smi::New(value); |
5966 } | 5966 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6163 return -1; | 6163 return -1; |
6164 } else if (a > b) { | 6164 } else if (a > b) { |
6165 return 1; | 6165 return 1; |
6166 } else { | 6166 } else { |
6167 return 0; | 6167 return 0; |
6168 } | 6168 } |
6169 } | 6169 } |
6170 if (other.IsBigint()) { | 6170 if (other.IsBigint()) { |
6171 Bigint& bigi = Bigint::Handle(); | 6171 Bigint& bigi = Bigint::Handle(); |
6172 bigi ^= other.raw(); | 6172 bigi ^= other.raw(); |
6173 ASSERT(!BigintOperations::FitsIntoInt64(bigi)); | 6173 ASSERT(!BigintOperations::FitsIntoMint(bigi)); |
6174 if (this->IsNegative() == other.IsNegative()) { | 6174 if (this->IsNegative() == other.IsNegative()) { |
6175 return this->IsNegative() ? 1 : -1; | 6175 return this->IsNegative() ? 1 : -1; |
6176 } | 6176 } |
6177 return this->IsNegative() ? -1 : 1; | 6177 return this->IsNegative() ? -1 : 1; |
6178 } | 6178 } |
6179 UNREACHABLE(); | 6179 UNREACHABLE(); |
6180 return 0; | 6180 return 0; |
6181 } | 6181 } |
6182 | 6182 |
6183 | 6183 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6322 return true; | 6322 return true; |
6323 } | 6323 } |
6324 | 6324 |
6325 if (!other.IsBigint() || other.IsNull()) { | 6325 if (!other.IsBigint() || other.IsNull()) { |
6326 return false; | 6326 return false; |
6327 } | 6327 } |
6328 | 6328 |
6329 Bigint& other_bgi = Bigint::Handle(); | 6329 Bigint& other_bgi = Bigint::Handle(); |
6330 other_bgi ^= other.raw(); | 6330 other_bgi ^= other.raw(); |
6331 | 6331 |
6332 return BN_cmp(BNAddr(), other_bgi.BNAddr()) == 0; | 6332 intptr_t len = this->Length(); |
| 6333 if (len != other_bgi.Length()) { |
| 6334 return false; |
| 6335 } |
| 6336 |
| 6337 for (intptr_t i = 0; i < len; i++) { |
| 6338 if (this->GetChunkAt(i) != other_bgi.GetChunkAt(i)) { |
| 6339 return false; |
| 6340 } |
| 6341 } |
| 6342 return true; |
6333 } | 6343 } |
6334 | 6344 |
6335 | 6345 |
6336 RawBigint* Bigint::New(const BIGNUM *bn, Heap::Space space) { | |
6337 Isolate* isolate = Isolate::Current(); | |
6338 const Class& cls = Class::Handle(isolate->object_store()->bigint_class()); | |
6339 Bigint& result = Bigint::Handle(); | |
6340 { | |
6341 RawObject* raw = Object::Allocate(cls, | |
6342 Bigint::InstanceSize(bn), | |
6343 space); | |
6344 NoGCScope no_gc; | |
6345 result ^= raw; | |
6346 // Danger Will Robinson! Use of OpenSSL internals! | |
6347 // Copy the OpenSSL BIGNUM to our own heap. Don't fix up our d | |
6348 // pointer, that'll get done for us. | |
6349 BIGNUM* our_bn = result.MutableBNAddr(); | |
6350 // memcpy would be sufficient. | |
6351 memmove(our_bn, bn, sizeof *bn); | |
6352 memmove(result.BNMemory(), bn->d, bn->top * sizeof(BN_ULONG)); | |
6353 // We only allocated/copied the active part. | |
6354 our_bn->dmax = our_bn->top; | |
6355 } | |
6356 | |
6357 return result.raw(); | |
6358 } | |
6359 | |
6360 | |
6361 RawBigint* Bigint::New(const String& str, Heap::Space space) { | 6346 RawBigint* Bigint::New(const String& str, Heap::Space space) { |
6362 return BigintOperations::NewFromCString(str.ToCString(), space); | 6347 return BigintOperations::NewFromCString(str.ToCString(), space); |
6363 } | 6348 } |
6364 | 6349 |
6365 | 6350 |
6366 RawBigint* Bigint::New(int64_t value, Heap::Space space) { | 6351 RawBigint* Bigint::New(int64_t value, Heap::Space space) { |
6367 return BigintOperations::NewFromInt64(value, space); | 6352 return BigintOperations::NewFromInt64(value, space); |
6368 } | 6353 } |
6369 | 6354 |
6370 | 6355 |
6371 double Bigint::AsDoubleValue() const { | 6356 double Bigint::AsDoubleValue() const { |
6372 return Double::Handle(BigintOperations::ToDouble(*this)).value(); | 6357 return Double::Handle(BigintOperations::ToDouble(*this)).value(); |
6373 } | 6358 } |
6374 | 6359 |
6375 | 6360 |
6376 int64_t Bigint::AsInt64Value() const { | 6361 int64_t Bigint::AsInt64Value() const { |
6377 if (!BigintOperations::FitsIntoInt64(*this)) { | 6362 if (!BigintOperations::FitsIntoMint(*this)) { |
6378 UNREACHABLE(); | 6363 UNREACHABLE(); |
6379 } | 6364 } |
6380 return BigintOperations::ToInt64(*this); | 6365 return BigintOperations::ToMint(*this); |
6381 } | 6366 } |
6382 | 6367 |
6383 | 6368 |
6384 // For positive values: Smi < Mint < Bigint. | 6369 // For positive values: Smi < Mint < Bigint. |
6385 int Bigint::CompareWith(const Integer& other) const { | 6370 int Bigint::CompareWith(const Integer& other) const { |
6386 ASSERT(!FitsIntoSmi(*this)); | 6371 ASSERT(!FitsIntoSmi(*this)); |
6387 ASSERT(!BigintOperations::FitsIntoInt64(*this)); | 6372 ASSERT(!BigintOperations::FitsIntoMint(*this)); |
6388 if (other.IsBigint()) { | 6373 if (other.IsBigint()) { |
6389 Bigint& big = Bigint::Handle(); | 6374 Bigint& big = Bigint::Handle(); |
6390 big ^= other.raw(); | 6375 big ^= other.raw(); |
6391 return BigintOperations::Compare(*this, big); | 6376 return BigintOperations::Compare(*this, big); |
6392 } | 6377 } |
6393 if (this->IsNegative() == other.IsNegative()) { | 6378 if (this->IsNegative() == other.IsNegative()) { |
6394 return this->IsNegative() ? -1 : 1; | 6379 return this->IsNegative() ? -1 : 1; |
6395 } | 6380 } |
6396 return this->IsNegative() ? -1 : 1; | 6381 return this->IsNegative() ? -1 : 1; |
6397 } | 6382 } |
6398 | 6383 |
6399 | 6384 |
| 6385 RawBigint* Bigint::Allocate(intptr_t length, Heap::Space space) { |
| 6386 ASSERT(length >= 0); |
| 6387 Isolate* isolate = Isolate::Current(); |
| 6388 const Class& cls = Class::Handle(isolate->object_store()->bigint_class()); |
| 6389 Bigint& result = Bigint::Handle(); |
| 6390 { |
| 6391 RawObject* raw = Object::Allocate(cls, Bigint::InstanceSize(length), space); |
| 6392 NoGCScope no_gc; |
| 6393 result ^= raw; |
| 6394 result.raw_ptr()->allocated_length_ = length; |
| 6395 result.raw_ptr()->signed_length_ = length; |
| 6396 } |
| 6397 return result.raw(); |
| 6398 } |
| 6399 |
| 6400 |
6400 static uword ZoneAllocator(intptr_t size) { | 6401 static uword ZoneAllocator(intptr_t size) { |
6401 Zone* zone = Isolate::Current()->current_zone(); | 6402 Zone* zone = Isolate::Current()->current_zone(); |
6402 return zone->Allocate(size); | 6403 return zone->Allocate(size); |
6403 } | 6404 } |
6404 | 6405 |
6405 | 6406 |
6406 const char* Bigint::ToCString() const { | 6407 const char* Bigint::ToCString() const { |
6407 return BigintOperations::ToDecCString(*this, &ZoneAllocator); | 6408 // TODO(florian): Add a BigintOperations::ToDecCString method and use that |
| 6409 // here. |
| 6410 return BigintOperations::ToHexCString(*this, &ZoneAllocator); |
6408 } | 6411 } |
6409 | 6412 |
6410 | 6413 |
6411 class StringHasher : ValueObject { | 6414 class StringHasher : ValueObject { |
6412 public: | 6415 public: |
6413 StringHasher() : hash_(0) {} | 6416 StringHasher() : hash_(0) {} |
6414 void Add(int32_t ch) { | 6417 void Add(int32_t ch) { |
6415 hash_ += ch; | 6418 hash_ += ch; |
6416 hash_ += hash_ << 10; | 6419 hash_ += hash_ << 10; |
6417 hash_ ^= hash_ >> 6; | 6420 hash_ ^= hash_ >> 6; |
(...skipping 1945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8363 result.set_num_args_tested(num_args_tested); | 8366 result.set_num_args_tested(num_args_tested); |
8364 // Number of array elements in one test entry (num_args_tested + 1) | 8367 // Number of array elements in one test entry (num_args_tested + 1) |
8365 intptr_t len = num_args_tested + 1; | 8368 intptr_t len = num_args_tested + 1; |
8366 // IC data array must be null terminated (sentinel entry). | 8369 // IC data array must be null terminated (sentinel entry). |
8367 Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | 8370 Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
8368 result.set_ic_data(ic_data); | 8371 result.set_ic_data(ic_data); |
8369 return result.raw(); | 8372 return result.raw(); |
8370 } | 8373 } |
8371 | 8374 |
8372 } // namespace dart | 8375 } // namespace dart |
OLD | NEW |