V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
math-random.cc
1 // Copyright 2018 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/math-random.h"
6 
7 #include "src/assert-scope.h"
8 #include "src/base/utils/random-number-generator.h"
9 #include "src/contexts-inl.h"
10 #include "src/isolate.h"
11 #include "src/objects/fixed-array.h"
12 #include "src/objects/smi.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 void MathRandom::InitializeContext(Isolate* isolate,
18  Handle<Context> native_context) {
19  Handle<FixedDoubleArray> cache = Handle<FixedDoubleArray>::cast(
20  isolate->factory()->NewFixedDoubleArray(kCacheSize, TENURED));
21  for (int i = 0; i < kCacheSize; i++) cache->set(i, 0);
22  native_context->set_math_random_cache(*cache);
23  Handle<PodArray<State>> pod = PodArray<State>::New(isolate, 1, TENURED);
24  native_context->set_math_random_state(*pod);
25  ResetContext(*native_context);
26 }
27 
28 void MathRandom::ResetContext(Context native_context) {
29  native_context->set_math_random_index(Smi::zero());
30  State state = {0, 0};
31  PodArray<State>::cast(native_context->math_random_state())->set(0, state);
32 }
33 
34 Address MathRandom::RefillCache(Isolate* isolate, Address raw_native_context) {
35  Context native_context = Context::cast(ObjectPtr(raw_native_context));
36  DisallowHeapAllocation no_gc;
37  PodArray<State> pod =
38  PodArray<State>::cast(native_context->math_random_state());
39  State state = pod->get(0);
40  // Initialize state if not yet initialized. If a fixed random seed was
41  // requested, use it to reset our state the first time a script asks for
42  // random numbers in this context. This ensures the script sees a consistent
43  // sequence.
44  if (state.s0 == 0 && state.s1 == 0) {
45  uint64_t seed;
46  if (FLAG_random_seed != 0) {
47  seed = FLAG_random_seed;
48  } else {
49  isolate->random_number_generator()->NextBytes(&seed, sizeof(seed));
50  }
51  state.s0 = base::RandomNumberGenerator::MurmurHash3(seed);
52  state.s1 = base::RandomNumberGenerator::MurmurHash3(~seed);
53  CHECK(state.s0 != 0 || state.s1 != 0);
54  }
55 
56  FixedDoubleArray cache =
57  FixedDoubleArray::cast(native_context->math_random_cache());
58  // Create random numbers.
59  for (int i = 0; i < kCacheSize; i++) {
60  // Generate random numbers using xorshift128+.
61  base::RandomNumberGenerator::XorShift128(&state.s0, &state.s1);
62  cache->set(i, base::RandomNumberGenerator::ToDouble(state.s0));
63  }
64  pod->set(0, state);
65 
66  Smi new_index = Smi::FromInt(kCacheSize);
67  native_context->set_math_random_index(new_index);
68  return new_index.ptr();
69 }
70 
71 } // namespace internal
72 } // namespace v8
Definition: libplatform.h:13