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