OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 <ctype.h> // isspace. | 5 #include <ctype.h> // isspace. |
6 | 6 |
7 #include "vm/bootstrap_natives.h" | 7 #include "vm/bootstrap_natives.h" |
8 | 8 |
9 #include "vm/bigint_operations.h" | |
10 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
11 #include "vm/native_entry.h" | 10 #include "vm/native_entry.h" |
12 #include "vm/object.h" | 11 #include "vm/object.h" |
13 #include "vm/scanner.h" | 12 #include "vm/scanner.h" |
14 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
15 | 14 |
16 namespace dart { | 15 namespace dart { |
17 | 16 |
18 DEFINE_NATIVE_ENTRY(Math_sqrt, 1) { | 17 DEFINE_NATIVE_ENTRY(Math_sqrt, 1) { |
19 GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0)); | 18 GET_NON_NULL_NATIVE_ARGUMENT(Double, operand, arguments->NativeArgAt(0)); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 // hash = 0x5A17; | 145 // hash = 0x5A17; |
147 // } | 146 // } |
148 // var result = new Uint32List(2); | 147 // var result = new Uint32List(2); |
149 // result[kSTATE_LO] = seed & _MASK_32; | 148 // result[kSTATE_LO] = seed & _MASK_32; |
150 // result[kSTATE_HI] = seed >> 32; | 149 // result[kSTATE_HI] = seed >> 32; |
151 // return result; | 150 // return result; |
152 DEFINE_NATIVE_ENTRY(Random_setupSeed, 1) { | 151 DEFINE_NATIVE_ENTRY(Random_setupSeed, 1) { |
153 GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0)); | 152 GET_NON_NULL_NATIVE_ARGUMENT(Integer, seed_int, arguments->NativeArgAt(0)); |
154 uint64_t seed = 0; | 153 uint64_t seed = 0; |
155 if (seed_int.IsBigint()) { | 154 if (seed_int.IsBigint()) { |
156 const Bigint& mask64 = Bigint::Handle( | |
157 BigintOperations::NewFromUint64(0xffffffffffffffffLL)); | |
158 Bigint& big_seed = Bigint::Handle(); | 155 Bigint& big_seed = Bigint::Handle(); |
159 big_seed ^= seed_int.raw(); | 156 big_seed ^= seed_int.raw(); |
160 uint64_t negate_mask = 0; | 157 uint64_t negate_mask = 0; |
| 158 uint64_t borrow = 0; |
161 if (big_seed.IsNegative()) { | 159 if (big_seed.IsNegative()) { |
162 // Negate bits to make seed positive. | 160 // Negate bits to make seed positive. |
163 // Negate bits again (by xor with negate_mask) when extracted below, | 161 // Negate bits again (by xor with negate_mask) when extracted below, |
164 // to get original bits. | 162 // to get original bits. |
165 negate_mask = 0xffffffffffffffffLL; | 163 negate_mask = 0xffffffffffffffffLL; |
166 big_seed ^= BigintOperations::BitNot(big_seed); | 164 |
| 165 // Instead of computing ~big_seed here, we compute it on the fly below as |
| 166 // follows: ~(-big_seed) == ~(~(big_seed-1)) == big_seed-1 |
| 167 borrow = 1; |
167 } | 168 } |
168 Bigint& low64 = Bigint::Handle(); | 169 const intptr_t used = big_seed.Used(); |
| 170 intptr_t digit = 0; |
169 do { | 171 do { |
170 low64 = BigintOperations::BitAnd(big_seed, mask64); | 172 uint64_t low64 = ((digit + 1) < used) ? big_seed.DigitAt(digit + 1) : 0; |
171 ASSERT(BigintOperations::FitsIntoUint64(low64)); | 173 low64 <<= 32; |
172 uint64_t chunk = BigintOperations::ToUint64(low64) ^ negate_mask; | 174 low64 |= (digit < used) ? big_seed.DigitAt(digit) : 0; |
173 seed = (seed * 1037) ^ mix64(chunk); | 175 low64 -= borrow; |
174 big_seed = BigintOperations::ShiftRight(big_seed, 64); | 176 if ((borrow == 1) && (low64 != 0xffffffffffffffffLL)) { |
175 } while (!big_seed.IsZero()); | 177 borrow = 0; |
| 178 } |
| 179 low64 ^= negate_mask; |
| 180 seed = (seed * 1037) ^ mix64(low64); |
| 181 digit += 2; |
| 182 } while (digit < used); |
176 } else { | 183 } else { |
177 seed = mix64(static_cast<uint64_t>(seed_int.AsInt64Value())); | 184 seed = mix64(static_cast<uint64_t>(seed_int.AsInt64Value())); |
178 } | 185 } |
179 | 186 |
180 if (seed == 0) { | 187 if (seed == 0) { |
181 seed = 0x5a17; | 188 seed = 0x5a17; |
182 } | 189 } |
183 return CreateRandomState(isolate, seed); | 190 return CreateRandomState(isolate, seed); |
184 } | 191 } |
185 | 192 |
186 | 193 |
187 DEFINE_NATIVE_ENTRY(Random_initialSeed, 0) { | 194 DEFINE_NATIVE_ENTRY(Random_initialSeed, 0) { |
188 Random* rnd = isolate->random(); | 195 Random* rnd = isolate->random(); |
189 uint64_t seed = rnd->NextUInt32(); | 196 uint64_t seed = rnd->NextUInt32(); |
190 seed |= (static_cast<uint64_t>(rnd->NextUInt32()) << 32); | 197 seed |= (static_cast<uint64_t>(rnd->NextUInt32()) << 32); |
191 return CreateRandomState(isolate, seed); | 198 return CreateRandomState(isolate, seed); |
192 } | 199 } |
193 | 200 |
194 } // namespace dart | 201 } // namespace dart |
OLD | NEW |