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