OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/utils/random-number-generator.h" | 5 #include "src/utils/random-number-generator.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #include "src/flags.h" | 10 #include "src/flags.h" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 void RandomNumberGenerator::NextBytes(void* buffer, size_t buflen) { | 110 void RandomNumberGenerator::NextBytes(void* buffer, size_t buflen) { |
111 for (size_t n = 0; n < buflen; ++n) { | 111 for (size_t n = 0; n < buflen; ++n) { |
112 static_cast<uint8_t*>(buffer)[n] = static_cast<uint8_t>(Next(8)); | 112 static_cast<uint8_t*>(buffer)[n] = static_cast<uint8_t>(Next(8)); |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 | 116 |
117 int RandomNumberGenerator::Next(int bits) { | 117 int RandomNumberGenerator::Next(int bits) { |
118 ASSERT_LT(0, bits); | 118 ASSERT_LT(0, bits); |
119 ASSERT_GE(32, bits); | 119 ASSERT_GE(32, bits); |
120 int64_t seed = (seed_ * kMultiplier + kAddend) & kMask; | 120 // Do unsigned multiplication, which has the intended modulo semantics, while |
| 121 // signed multiplication would expose undefined behavior. |
| 122 uint64_t product = static_cast<uint64_t>(seed_) * kMultiplier; |
| 123 // Assigning a uint64_t to an int64_t is implementation defined, but this |
| 124 // should be OK. Use a static_cast to explicitly state that we know what we're |
| 125 // doing. (Famous last words...) |
| 126 int64_t seed = static_cast<int64_t>((product + kAddend) & kMask); |
121 seed_ = seed; | 127 seed_ = seed; |
122 return static_cast<int>(seed >> (48 - bits)); | 128 return static_cast<int>(seed >> (48 - bits)); |
123 } | 129 } |
124 | 130 |
125 | 131 |
126 void RandomNumberGenerator::SetSeed(int64_t seed) { | 132 void RandomNumberGenerator::SetSeed(int64_t seed) { |
127 seed_ = (seed ^ kMultiplier) & kMask; | 133 seed_ = (seed ^ kMultiplier) & kMask; |
128 } | 134 } |
129 | 135 |
130 } } // namespace v8::internal | 136 } } // namespace v8::internal |
OLD | NEW |