diff --git a/runtime/builtins/builtins_math.cpp b/runtime/builtins/builtins_math.cpp index f58d08125e12de113ba884a456aee742a5e63b08..f76318f8f5b3d1ad004852042a0c5f571cd54425 100644 --- a/runtime/builtins/builtins_math.cpp +++ b/runtime/builtins/builtins_math.cpp @@ -565,11 +565,9 @@ JSTaggedValue BuiltinsMath::Random([[maybe_unused]] EcmaRuntimeCallInfo *argv) { ASSERT(argv); BUILTINS_API_TRACE(argv->GetThread(), Math, Random); - std::random_device rd; - std::default_random_engine engine(rd()); - std::uniform_real_distribution dis(0, std::random_device::max() - 1); // result range [0,1) - double result = dis(engine) / std::random_device::max(); + std::uniform_real_distribution dis(0.0, 1.0); + double result = dis(argv->GetThread()->GetEcmaVM()->GetRandomEngine()); return GetTaggedDouble(result); } diff --git a/runtime/ecma_vm.cpp b/runtime/ecma_vm.cpp index 526474811ba723671375b9fa9737bb7d07f3df30..d7875879626e4016ac93c735ebaedb555d87a070 100644 --- a/runtime/ecma_vm.cpp +++ b/runtime/ecma_vm.cpp @@ -171,6 +171,7 @@ EcmaVM::EcmaVM(JSRuntimeOptions options) : string_table_(new EcmaStringTable(thi rendezvous_ = allocator->New(this); notification_manager_ = allocator->New(runtime->GetInternalAllocator()); notification_manager_->SetRendezvous(rendezvous_); + InitializeRandomEngine(); LanguageContext ctx = Runtime::GetCurrent()->GetLanguageContext(panda_file::SourceLang::ECMASCRIPT); mm_ = CreateMM(ctx, Runtime::GetCurrent()->GetInternalAllocator(), options_); diff --git a/runtime/ecma_vm.h b/runtime/ecma_vm.h index 9e7c26d68873d727310d696e5d96756baf015bfc..a08f908cd7d5b99a0851bb93d982fe8e9b4053fe 100644 --- a/runtime/ecma_vm.h +++ b/runtime/ecma_vm.h @@ -16,6 +16,7 @@ #ifndef ECMASCRIPT_ECMA_VM_H #define ECMASCRIPT_ECMA_VM_H +#include #include #include "include/mem/panda_containers.h" @@ -467,6 +468,12 @@ public: return MEMBER_OFFSET(EcmaVM, global_env_); } + std::default_random_engine &GetRandomEngine() + { + ASSERT(random_engine_); + return *random_engine_; + } + protected: bool CheckEntrypointSignature([[maybe_unused]] Method *entrypoint) override { @@ -512,6 +519,13 @@ private: void LoadEcmaStdLib(); const panda_file::File *GetLastLoadedPandaFile(); + void InitializeRandomEngine() + { + ASSERT(!random_engine_); + std::random_device rd; + random_engine_.emplace(rd()); + } + NO_MOVE_SEMANTIC(EcmaVM); NO_COPY_SEMANTIC(EcmaVM); @@ -575,6 +589,8 @@ private: HostPromiseRejectionTracker host_promise_rejection_tracker_ {nullptr}; void *data_ {nullptr}; PandaList finalization_registries_; + // optional for lazy initialization + std::optional random_engine_; friend class ObjectFactory; friend class panda::JSNApi;