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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/become.h" | 10 #include "vm/become.h" |
(...skipping 8099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8110 LiteralToken::InstanceSize(), Heap::kOld); | 8110 LiteralToken::InstanceSize(), Heap::kOld); |
8111 return reinterpret_cast<RawLiteralToken*>(raw); | 8111 return reinterpret_cast<RawLiteralToken*>(raw); |
8112 } | 8112 } |
8113 | 8113 |
8114 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { | 8114 RawLiteralToken* LiteralToken::New(Token::Kind kind, const String& literal) { |
8115 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); | 8115 const LiteralToken& result = LiteralToken::Handle(LiteralToken::New()); |
8116 result.set_kind(kind); | 8116 result.set_kind(kind); |
8117 result.set_literal(literal); | 8117 result.set_literal(literal); |
8118 if (kind == Token::kINTEGER) { | 8118 if (kind == Token::kINTEGER) { |
8119 const Integer& value = Integer::Handle(Integer::NewCanonical(literal)); | 8119 const Integer& value = Integer::Handle(Integer::NewCanonical(literal)); |
| 8120 if (value.IsNull()) { |
| 8121 // Integer is out of range. |
| 8122 return LiteralToken::null(); |
| 8123 } |
8120 ASSERT(value.IsSmi() || value.IsOld()); | 8124 ASSERT(value.IsSmi() || value.IsOld()); |
8121 result.set_value(value); | 8125 result.set_value(value); |
8122 } else if (kind == Token::kDOUBLE) { | 8126 } else if (kind == Token::kDOUBLE) { |
8123 const Double& value = Double::Handle(Double::NewCanonical(literal)); | 8127 const Double& value = Double::Handle(Double::NewCanonical(literal)); |
8124 result.set_value(value); | 8128 result.set_value(value); |
8125 } else { | 8129 } else { |
8126 ASSERT(Token::NeedsLiteralToken(kind)); | 8130 ASSERT(Token::NeedsLiteralToken(kind)); |
8127 result.set_value(literal); | 8131 result.set_value(literal); |
8128 } | 8132 } |
8129 return result.raw(); | 8133 return result.raw(); |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8491 value_ = tokens_->GetOrNull(descriptor, &is_present); | 8495 value_ = tokens_->GetOrNull(descriptor, &is_present); |
8492 intptr_t index = -1; | 8496 intptr_t index = -1; |
8493 if (is_present) { | 8497 if (is_present) { |
8494 ASSERT(value_.IsSmi()); | 8498 ASSERT(value_.IsSmi()); |
8495 index = Smi::Cast(value_).Value(); | 8499 index = Smi::Cast(value_).Value(); |
8496 } else { | 8500 } else { |
8497 const intptr_t fresh_index = token_objects_.Length(); | 8501 const intptr_t fresh_index = token_objects_.Length(); |
8498 fresh_index_smi_ = Smi::New(fresh_index); | 8502 fresh_index_smi_ = Smi::New(fresh_index); |
8499 const LiteralToken& lit = LiteralToken::Handle( | 8503 const LiteralToken& lit = LiteralToken::Handle( |
8500 LiteralToken::New(descriptor.kind, *descriptor.literal)); | 8504 LiteralToken::New(descriptor.kind, *descriptor.literal)); |
| 8505 if (lit.IsNull()) { |
| 8506 // Convert token to an error. |
| 8507 ASSERT(descriptor.kind == Token::kINTEGER); |
| 8508 ASSERT(FLAG_limit_ints_to_64_bits); |
| 8509 Scanner::TokenDescriptor errorDesc = descriptor; |
| 8510 errorDesc.kind = Token::kERROR; |
| 8511 errorDesc.literal = &String::Handle(Symbols::NewFormatted( |
| 8512 Thread::Current(), "integer literal %s is out of range", |
| 8513 descriptor.literal->ToCString())); |
| 8514 AddLiteralToken(errorDesc); |
| 8515 return; |
| 8516 } |
8501 index = Smi::Value( | 8517 index = Smi::Value( |
8502 Smi::RawCast(tokens_->InsertOrGetValue(lit, fresh_index_smi_))); | 8518 Smi::RawCast(tokens_->InsertOrGetValue(lit, fresh_index_smi_))); |
8503 token_objects_.Add(lit); | 8519 token_objects_.Add(lit); |
8504 if (kPrintTokenObjects) { | 8520 if (kPrintTokenObjects) { |
8505 int iid = Isolate::Current()->main_port() % 1024; | 8521 int iid = Isolate::Current()->main_port() % 1024; |
8506 printf("lit %03x %p %p %p <%s>\n", iid, token_objects_.raw(), | 8522 printf("lit %03x %p %p %p <%s>\n", iid, token_objects_.raw(), |
8507 lit.literal(), lit.value(), | 8523 lit.literal(), lit.value(), |
8508 String::Handle(lit.literal()).ToCString()); | 8524 String::Handle(lit.literal()).ToCString()); |
8509 } | 8525 } |
8510 } | 8526 } |
(...skipping 9309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17820 // Integer is an interface. No instances of Integer should exist except null. | 17836 // Integer is an interface. No instances of Integer should exist except null. |
17821 ASSERT(IsNull()); | 17837 ASSERT(IsNull()); |
17822 return "NULL Integer"; | 17838 return "NULL Integer"; |
17823 } | 17839 } |
17824 | 17840 |
17825 RawInteger* Integer::New(const String& str, Heap::Space space) { | 17841 RawInteger* Integer::New(const String& str, Heap::Space space) { |
17826 // We are not supposed to have integers represented as two byte strings. | 17842 // We are not supposed to have integers represented as two byte strings. |
17827 ASSERT(str.IsOneByteString()); | 17843 ASSERT(str.IsOneByteString()); |
17828 int64_t value; | 17844 int64_t value; |
17829 if (!OS::StringToInt64(str.ToCString(), &value)) { | 17845 if (!OS::StringToInt64(str.ToCString(), &value)) { |
| 17846 if (FLAG_limit_ints_to_64_bits) { |
| 17847 // Out of range. |
| 17848 return Integer::null(); |
| 17849 } |
17830 const Bigint& big = | 17850 const Bigint& big = |
17831 Bigint::Handle(Bigint::NewFromCString(str.ToCString(), space)); | 17851 Bigint::Handle(Bigint::NewFromCString(str.ToCString(), space)); |
17832 ASSERT(!big.FitsIntoSmi()); | 17852 ASSERT(!big.FitsIntoSmi()); |
17833 ASSERT(!big.FitsIntoInt64()); | 17853 ASSERT(!big.FitsIntoInt64()); |
17834 if (!FLAG_limit_ints_to_64_bits) { | 17854 return big.raw(); |
17835 return big.raw(); | |
17836 } | |
17837 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | |
17838 value = big.AsTruncatedInt64Value(); | |
17839 } | 17855 } |
17840 return Integer::New(value, space); | 17856 return Integer::New(value, space); |
17841 } | 17857 } |
17842 | 17858 |
17843 RawInteger* Integer::NewCanonical(const String& str) { | 17859 RawInteger* Integer::NewCanonical(const String& str) { |
17844 // We are not supposed to have integers represented as two byte strings. | 17860 // We are not supposed to have integers represented as two byte strings. |
17845 ASSERT(str.IsOneByteString()); | 17861 ASSERT(str.IsOneByteString()); |
17846 int64_t value; | 17862 int64_t value; |
17847 if (!OS::StringToInt64(str.ToCString(), &value)) { | 17863 if (!OS::StringToInt64(str.ToCString(), &value)) { |
| 17864 if (FLAG_limit_ints_to_64_bits) { |
| 17865 // Out of range. |
| 17866 return Integer::null(); |
| 17867 } |
17848 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); | 17868 const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str)); |
17849 ASSERT(!big.FitsIntoSmi()); | 17869 ASSERT(!big.FitsIntoSmi()); |
17850 ASSERT(!big.FitsIntoInt64()); | 17870 ASSERT(!big.FitsIntoInt64()); |
17851 if (!FLAG_limit_ints_to_64_bits) { | 17871 return big.raw(); |
17852 return big.raw(); | |
17853 } | |
17854 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | |
17855 value = big.AsTruncatedInt64Value(); | |
17856 } | 17872 } |
17857 if (Smi::IsValid(value)) { | 17873 if (Smi::IsValid(value)) { |
17858 return Smi::New(static_cast<intptr_t>(value)); | 17874 return Smi::New(static_cast<intptr_t>(value)); |
17859 } | 17875 } |
17860 return Mint::NewCanonical(value); | 17876 return Mint::NewCanonical(value); |
17861 } | 17877 } |
17862 | 17878 |
17863 RawInteger* Integer::New(int64_t value, Heap::Space space) { | 17879 RawInteger* Integer::New(int64_t value, Heap::Space space) { |
17864 const bool is_smi = Smi::IsValid(value); | 17880 const bool is_smi = Smi::IsValid(value); |
17865 if (is_smi) { | 17881 if (is_smi) { |
17866 return Smi::New(static_cast<intptr_t>(value)); | 17882 return Smi::New(static_cast<intptr_t>(value)); |
17867 } | 17883 } |
17868 return Mint::New(value, space); | 17884 return Mint::New(value, space); |
17869 } | 17885 } |
17870 | 17886 |
17871 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { | 17887 RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { |
17872 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { | 17888 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { |
17873 if (FLAG_limit_ints_to_64_bits) { | 17889 if (FLAG_limit_ints_to_64_bits) { |
17874 // TODO(alexmarkov): Throw error in FLAG_limit_ints_to_64_bits mode. | 17890 // Out of range. |
17875 return Integer::New(static_cast<int64_t>(value), space); | 17891 return Integer::null(); |
17876 } else { | 17892 } else { |
17877 return Bigint::NewFromUint64(value, space); | 17893 return Bigint::NewFromUint64(value, space); |
17878 } | 17894 } |
17879 } else { | 17895 } else { |
17880 return Integer::New(value, space); | 17896 return Integer::New(value, space); |
17881 } | 17897 } |
17882 } | 17898 } |
17883 | 17899 |
17884 bool Integer::Equals(const Instance& other) const { | 17900 bool Integer::Equals(const Instance& other) const { |
17885 // Integer is an abstract class. | 17901 // Integer is an abstract class. |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18066 } else { | 18082 } else { |
18067 return Integer::New(remainder + right_value, space); | 18083 return Integer::New(remainder + right_value, space); |
18068 } | 18084 } |
18069 } | 18085 } |
18070 return Integer::New(remainder, space); | 18086 return Integer::New(remainder, space); |
18071 } | 18087 } |
18072 default: | 18088 default: |
18073 UNIMPLEMENTED(); | 18089 UNIMPLEMENTED(); |
18074 } | 18090 } |
18075 } | 18091 } |
18076 ASSERT(!FLAG_limit_ints_to_64_bits); | 18092 ASSERT(!Bigint::IsDisabled()); |
18077 return Integer::null(); // Notify caller that a bigint operation is required. | 18093 return Integer::null(); // Notify caller that a bigint operation is required. |
18078 } | 18094 } |
18079 | 18095 |
18080 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { | 18096 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { |
18081 return !op1.IsBigint() && !op2.IsBigint(); | 18097 return !op1.IsBigint() && !op2.IsBigint(); |
18082 } | 18098 } |
18083 | 18099 |
18084 RawInteger* Integer::BitOp(Token::Kind kind, | 18100 RawInteger* Integer::BitOp(Token::Kind kind, |
18085 const Integer& other, | 18101 const Integer& other, |
18086 Heap::Space space) const { | 18102 Heap::Space space) const { |
(...skipping 23 matching lines...) Expand all Loading... |
18110 case Token::kBIT_AND: | 18126 case Token::kBIT_AND: |
18111 return Integer::New(a & b, space); | 18127 return Integer::New(a & b, space); |
18112 case Token::kBIT_OR: | 18128 case Token::kBIT_OR: |
18113 return Integer::New(a | b, space); | 18129 return Integer::New(a | b, space); |
18114 case Token::kBIT_XOR: | 18130 case Token::kBIT_XOR: |
18115 return Integer::New(a ^ b, space); | 18131 return Integer::New(a ^ b, space); |
18116 default: | 18132 default: |
18117 UNIMPLEMENTED(); | 18133 UNIMPLEMENTED(); |
18118 } | 18134 } |
18119 } | 18135 } |
18120 ASSERT(!FLAG_limit_ints_to_64_bits); | 18136 ASSERT(!Bigint::IsDisabled()); |
18121 return Integer::null(); // Notify caller that a bigint operation is required. | 18137 return Integer::null(); // Notify caller that a bigint operation is required. |
18122 } | 18138 } |
18123 | 18139 |
18124 // TODO(srdjan): Clarify handling of negative right operand in a shift op. | 18140 // TODO(srdjan): Clarify handling of negative right operand in a shift op. |
18125 RawInteger* Smi::ShiftOp(Token::Kind kind, | 18141 RawInteger* Smi::ShiftOp(Token::Kind kind, |
18126 const Smi& other, | 18142 const Smi& other, |
18127 Heap::Space space) const { | 18143 Heap::Space space) const { |
18128 intptr_t result = 0; | 18144 intptr_t result = 0; |
18129 const intptr_t left_value = Value(); | 18145 const intptr_t left_value = Value(); |
18130 const intptr_t right_value = other.Value(); | 18146 const intptr_t right_value = other.Value(); |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18523 digits_ ^= digits_.CheckAndCanonicalize(thread, NULL); | 18539 digits_ ^= digits_.CheckAndCanonicalize(thread, NULL); |
18524 ASSERT(!digits_.IsNull()); | 18540 ASSERT(!digits_.IsNull()); |
18525 set_digits(digits_); | 18541 set_digits(digits_); |
18526 } else { | 18542 } else { |
18527 ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); | 18543 ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); |
18528 } | 18544 } |
18529 return true; | 18545 return true; |
18530 } | 18546 } |
18531 | 18547 |
18532 RawBigint* Bigint::New(Heap::Space space) { | 18548 RawBigint* Bigint::New(Heap::Space space) { |
18533 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 18549 ASSERT(!Bigint::IsDisabled()); |
18534 Thread* thread = Thread::Current(); | 18550 Thread* thread = Thread::Current(); |
18535 Zone* zone = thread->zone(); | 18551 Zone* zone = thread->zone(); |
18536 Isolate* isolate = thread->isolate(); | 18552 Isolate* isolate = thread->isolate(); |
18537 ASSERT(isolate->object_store()->bigint_class() != Class::null()); | 18553 ASSERT(isolate->object_store()->bigint_class() != Class::null()); |
18538 Bigint& result = Bigint::Handle(zone); | 18554 Bigint& result = Bigint::Handle(zone); |
18539 { | 18555 { |
18540 RawObject* raw = | 18556 RawObject* raw = |
18541 Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); | 18557 Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); |
18542 NoSafepointScope no_safepoint; | 18558 NoSafepointScope no_safepoint; |
18543 result ^= raw; | 18559 result ^= raw; |
18544 } | 18560 } |
18545 result.SetNeg(false); | 18561 result.SetNeg(false); |
18546 result.SetUsed(0); | 18562 result.SetUsed(0); |
18547 result.set_digits( | 18563 result.set_digits( |
18548 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); | 18564 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); |
18549 return result.raw(); | 18565 return result.raw(); |
18550 } | 18566 } |
18551 | 18567 |
18552 RawBigint* Bigint::New(bool neg, | 18568 RawBigint* Bigint::New(bool neg, |
18553 intptr_t used, | 18569 intptr_t used, |
18554 const TypedData& digits, | 18570 const TypedData& digits, |
18555 Heap::Space space) { | 18571 Heap::Space space) { |
18556 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | 18572 ASSERT(!Bigint::IsDisabled()); |
18557 ASSERT((used == 0) || | 18573 ASSERT((used == 0) || |
18558 (!digits.IsNull() && (digits.Length() >= (used + (used & 1))))); | 18574 (!digits.IsNull() && (digits.Length() >= (used + (used & 1))))); |
18559 Thread* thread = Thread::Current(); | 18575 Thread* thread = Thread::Current(); |
18560 Zone* zone = thread->zone(); | 18576 Zone* zone = thread->zone(); |
18561 Isolate* isolate = thread->isolate(); | 18577 Isolate* isolate = thread->isolate(); |
18562 ASSERT(isolate->object_store()->bigint_class() != Class::null()); | 18578 ASSERT(isolate->object_store()->bigint_class() != Class::null()); |
18563 Bigint& result = Bigint::Handle(zone); | 18579 Bigint& result = Bigint::Handle(zone); |
18564 { | 18580 { |
18565 RawObject* raw = | 18581 RawObject* raw = |
18566 Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); | 18582 Object::Allocate(Bigint::kClassId, Bigint::InstanceSize(), space); |
(...skipping 16 matching lines...) Expand all Loading... |
18583 neg = false; | 18599 neg = false; |
18584 result.set_digits( | 18600 result.set_digits( |
18585 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); | 18601 TypedData::Handle(zone, TypedData::EmptyUint32Array(thread))); |
18586 } | 18602 } |
18587 result.SetNeg(neg); | 18603 result.SetNeg(neg); |
18588 result.SetUsed(used); | 18604 result.SetUsed(used); |
18589 return result.raw(); | 18605 return result.raw(); |
18590 } | 18606 } |
18591 | 18607 |
18592 RawBigint* Bigint::NewFromInt64(int64_t value, Heap::Space space) { | 18608 RawBigint* Bigint::NewFromInt64(int64_t value, Heap::Space space) { |
18593 // Currently only used to convert Smi or Mint to hex String, therefore do | 18609 ASSERT(!Bigint::IsDisabled()); |
18594 // not throw RangeError if --limit-ints-to-64-bits. | |
18595 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | |
18596 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); | 18610 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); |
18597 bool neg; | 18611 bool neg; |
18598 uint64_t abs_value; | 18612 uint64_t abs_value; |
18599 if (value < 0) { | 18613 if (value < 0) { |
18600 neg = true; | 18614 neg = true; |
18601 abs_value = -value; | 18615 abs_value = -value; |
18602 } else { | 18616 } else { |
18603 neg = false; | 18617 neg = false; |
18604 abs_value = value; | 18618 abs_value = value; |
18605 } | 18619 } |
18606 SetDigitAt(digits, 0, static_cast<uint32_t>(abs_value)); | 18620 SetDigitAt(digits, 0, static_cast<uint32_t>(abs_value)); |
18607 SetDigitAt(digits, 1, static_cast<uint32_t>(abs_value >> 32)); | 18621 SetDigitAt(digits, 1, static_cast<uint32_t>(abs_value >> 32)); |
18608 return New(neg, 2, digits, space); | 18622 return New(neg, 2, digits, space); |
18609 } | 18623 } |
18610 | 18624 |
18611 RawBigint* Bigint::NewFromUint64(uint64_t value, Heap::Space space) { | 18625 RawBigint* Bigint::NewFromUint64(uint64_t value, Heap::Space space) { |
18612 // TODO(alexmarkov): Revise this assertion if this factory method is used | 18626 ASSERT(!Bigint::IsDisabled()); |
18613 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. | |
18614 ASSERT(!FLAG_limit_ints_to_64_bits); | |
18615 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); | 18627 const TypedData& digits = TypedData::Handle(NewDigits(2, space)); |
18616 SetDigitAt(digits, 0, static_cast<uint32_t>(value)); | 18628 SetDigitAt(digits, 0, static_cast<uint32_t>(value)); |
18617 SetDigitAt(digits, 1, static_cast<uint32_t>(value >> 32)); | 18629 SetDigitAt(digits, 1, static_cast<uint32_t>(value >> 32)); |
18618 return New(false, 2, digits, space); | 18630 return New(false, 2, digits, space); |
18619 } | 18631 } |
18620 | 18632 |
18621 RawBigint* Bigint::NewFromShiftedInt64(int64_t value, | 18633 RawBigint* Bigint::NewFromShiftedInt64(int64_t value, |
18622 intptr_t shift, | 18634 intptr_t shift, |
18623 Heap::Space space) { | 18635 Heap::Space space) { |
18624 // TODO(alexmarkov): Revise this assertion if this factory method is used | 18636 ASSERT(!Bigint::IsDisabled()); |
18625 // to explicitly allocate Bigint objects in --limit-ints-to-64-bits mode. | |
18626 ASSERT(!FLAG_limit_ints_to_64_bits); | |
18627 ASSERT(kBitsPerDigit == 32); | 18637 ASSERT(kBitsPerDigit == 32); |
18628 ASSERT(shift >= 0); | 18638 ASSERT(shift >= 0); |
18629 const intptr_t digit_shift = shift / kBitsPerDigit; | 18639 const intptr_t digit_shift = shift / kBitsPerDigit; |
18630 const intptr_t bit_shift = shift % kBitsPerDigit; | 18640 const intptr_t bit_shift = shift % kBitsPerDigit; |
18631 const intptr_t used = 3 + digit_shift; | 18641 const intptr_t used = 3 + digit_shift; |
18632 const TypedData& digits = TypedData::Handle(NewDigits(used, space)); | 18642 const TypedData& digits = TypedData::Handle(NewDigits(used, space)); |
18633 bool neg; | 18643 bool neg; |
18634 uint64_t abs_value; | 18644 uint64_t abs_value; |
18635 if (value < 0) { | 18645 if (value < 0) { |
18636 neg = true; | 18646 neg = true; |
(...skipping 10 matching lines...) Expand all Loading... |
18647 SetDigitAt(digits, 1 + digit_shift, | 18657 SetDigitAt(digits, 1 + digit_shift, |
18648 static_cast<uint32_t>(abs_value >> (32 - bit_shift))); | 18658 static_cast<uint32_t>(abs_value >> (32 - bit_shift))); |
18649 SetDigitAt(digits, 2 + digit_shift, | 18659 SetDigitAt(digits, 2 + digit_shift, |
18650 (bit_shift == 0) | 18660 (bit_shift == 0) |
18651 ? 0 | 18661 ? 0 |
18652 : static_cast<uint32_t>(abs_value >> (64 - bit_shift))); | 18662 : static_cast<uint32_t>(abs_value >> (64 - bit_shift))); |
18653 return New(neg, used, digits, space); | 18663 return New(neg, used, digits, space); |
18654 } | 18664 } |
18655 | 18665 |
18656 RawBigint* Bigint::NewFromCString(const char* str, Heap::Space space) { | 18666 RawBigint* Bigint::NewFromCString(const char* str, Heap::Space space) { |
18657 // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. | 18667 ASSERT(!Bigint::IsDisabled()); |
18658 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | |
18659 ASSERT(str != NULL); | 18668 ASSERT(str != NULL); |
18660 bool neg = false; | 18669 bool neg = false; |
18661 TypedData& digits = TypedData::Handle(); | 18670 TypedData& digits = TypedData::Handle(); |
18662 if (str[0] == '-') { | 18671 if (str[0] == '-') { |
18663 ASSERT(str[1] != '-'); | 18672 ASSERT(str[1] != '-'); |
18664 neg = true; | 18673 neg = true; |
18665 str++; | 18674 str++; |
18666 } | 18675 } |
18667 intptr_t used; | 18676 intptr_t used; |
18668 const intptr_t str_length = strlen(str); | 18677 const intptr_t str_length = strlen(str); |
18669 if ((str_length >= 2) && (str[0] == '0') && | 18678 if ((str_length >= 2) && (str[0] == '0') && |
18670 ((str[1] == 'x') || (str[1] == 'X'))) { | 18679 ((str[1] == 'x') || (str[1] == 'X'))) { |
18671 digits = NewDigitsFromHexCString(&str[2], &used, space); | 18680 digits = NewDigitsFromHexCString(&str[2], &used, space); |
18672 } else { | 18681 } else { |
18673 digits = NewDigitsFromDecCString(str, &used, space); | 18682 digits = NewDigitsFromDecCString(str, &used, space); |
18674 } | 18683 } |
18675 return New(neg, used, digits, space); | 18684 return New(neg, used, digits, space); |
18676 } | 18685 } |
18677 | 18686 |
18678 RawBigint* Bigint::NewCanonical(const String& str) { | 18687 RawBigint* Bigint::NewCanonical(const String& str) { |
18679 // Allow parser to scan Bigint literal, even with --limit-ints-to-64-bits. | 18688 ASSERT(!Bigint::IsDisabled()); |
18680 // TODO(alexmarkov): Throw error or assert in --limit-ints-to-64-bits mode. | |
18681 Thread* thread = Thread::Current(); | 18689 Thread* thread = Thread::Current(); |
18682 Zone* zone = thread->zone(); | 18690 Zone* zone = thread->zone(); |
18683 Isolate* isolate = thread->isolate(); | 18691 Isolate* isolate = thread->isolate(); |
18684 const Bigint& value = | 18692 const Bigint& value = |
18685 Bigint::Handle(zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); | 18693 Bigint::Handle(zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); |
18686 const Class& cls = | 18694 const Class& cls = |
18687 Class::Handle(zone, isolate->object_store()->bigint_class()); | 18695 Class::Handle(zone, isolate->object_store()->bigint_class()); |
18688 intptr_t index = 0; | 18696 intptr_t index = 0; |
18689 Bigint& canonical_value = Bigint::Handle(zone); | 18697 Bigint& canonical_value = Bigint::Handle(zone); |
18690 canonical_value ^= cls.LookupCanonicalBigint(zone, value, &index); | 18698 canonical_value ^= cls.LookupCanonicalBigint(zone, value, &index); |
(...skipping 3533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22224 } | 22232 } |
22225 return UserTag::null(); | 22233 return UserTag::null(); |
22226 } | 22234 } |
22227 | 22235 |
22228 const char* UserTag::ToCString() const { | 22236 const char* UserTag::ToCString() const { |
22229 const String& tag_label = String::Handle(label()); | 22237 const String& tag_label = String::Handle(label()); |
22230 return tag_label.ToCString(); | 22238 return tag_label.ToCString(); |
22231 } | 22239 } |
22232 | 22240 |
22233 } // namespace dart | 22241 } // namespace dart |
OLD | NEW |