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