/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v24.19.0
src/timers.cc
206 строк
7 KB
Renegade334
timers: fix binding fast call signatures
06 окт 2025, 17:17
Не верифицирован
06 окт 2025, 17:17
d728545
Код
Авторство
О чём код?
#include "timers.h" #include "env-inl.h" #include "node_debug.h" #include "node_external_reference.h" #include "util-inl.h" #include "v8.h" #include <cstdint> namespace node { namespace timers { using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Number; using v8::Object; using v8::ObjectTemplate; using v8::Value; void BindingData::SetupTimers(const FunctionCallbackInfo<Value>& args) { CHECK(args[0]->IsFunction()); CHECK(args[1]->IsFunction()); auto env = Environment::GetCurrent(args); env->set_immediate_callback_function(args[0].As<Function>()); env->set_timers_callback_function(args[1].As<Function>()); } void BindingData::SlowGetLibuvNow(const FunctionCallbackInfo<Value>& args) { double now = GetLibuvNowImpl(Realm::GetBindingData<BindingData>(args)); args.GetReturnValue().Set(Number::New(args.GetIsolate(), now)); } double BindingData::FastGetLibuvNow(Local<Value> receiver) { TRACK_V8_FAST_API_CALL("timers.getLibuvNow"); return GetLibuvNowImpl(FromJSObject<BindingData>(receiver)); } double BindingData::GetLibuvNowImpl(BindingData* data) { return static_cast<double>(data->env()->GetNowUint64()); } void BindingData::SlowScheduleTimer(const FunctionCallbackInfo<Value>& args) { int64_t duration; if (args[0] ->IntegerValue(args.GetIsolate()->GetCurrentContext()) .To(&duration)) { ScheduleTimerImpl(Realm::GetBindingData<BindingData>(args), duration); } } void BindingData::FastScheduleTimer(Local<Object> receiver, int64_t duration) { TRACK_V8_FAST_API_CALL("timers.scheduleTimer"); ScheduleTimerImpl(FromJSObject<BindingData>(receiver), duration); } void BindingData::ScheduleTimerImpl(BindingData* data, int64_t duration) { data->env()->ScheduleTimer(duration); } void BindingData::SlowToggleTimerRef( const v8::FunctionCallbackInfo<v8::Value>& args) { ToggleTimerRefImpl(Realm::GetBindingData<BindingData>(args), args[0]->IsTrue()); } void BindingData::FastToggleTimerRef(Local<Object> receiver, bool ref) { TRACK_V8_FAST_API_CALL("timers.toggleTimerRef"); ToggleTimerRefImpl(FromJSObject<BindingData>(receiver), ref); } void BindingData::ToggleTimerRefImpl(BindingData* data, bool ref) { data->env()->ToggleTimerRef(ref); } void BindingData::SlowToggleImmediateRef( const v8::FunctionCallbackInfo<v8::Value>& args) { ToggleImmediateRefImpl(Realm::GetBindingData<BindingData>(args), args[0]->IsTrue()); } void BindingData::FastToggleImmediateRef(Local<Object> receiver, bool ref) { TRACK_V8_FAST_API_CALL("timers.toggleImmediateRef"); ToggleImmediateRefImpl(FromJSObject<BindingData>(receiver), ref); } void BindingData::ToggleImmediateRefImpl(BindingData* data, bool ref) { data->env()->ToggleImmediateRef(ref); } BindingData::BindingData(Realm* realm, Local<Object> object) : SnapshotableObject(realm, object, type_int) {} bool BindingData::PrepareForSerialization(Local<Context> context, v8::SnapshotCreator* creator) { // Return true because we need to maintain the reference to the binding from // JS land. return true; } InternalFieldInfoBase* BindingData::Serialize(int index) { DCHECK_IS_SNAPSHOT_SLOT(index); InternalFieldInfo* info = InternalFieldInfoBase::New<InternalFieldInfo>(type()); return info; } void BindingData::Deserialize(Local<Context> context, Local<Object> holder, int index, InternalFieldInfoBase* info) { DCHECK_IS_SNAPSHOT_SLOT(index); v8::HandleScope scope(context->GetIsolate()); Realm* realm = Realm::GetCurrent(context); // Recreate the buffer in the constructor. BindingData* binding = realm->AddBindingData<BindingData>(holder); CHECK_NOT_NULL(binding); } v8::CFunction BindingData::fast_get_libuv_now_( v8::CFunction::Make(FastGetLibuvNow)); v8::CFunction BindingData::fast_schedule_timer_( v8::CFunction::Make(FastScheduleTimer)); v8::CFunction BindingData::fast_toggle_timer_ref_( v8::CFunction::Make(FastToggleTimerRef)); v8::CFunction BindingData::fast_toggle_immediate_ref_( v8::CFunction::Make(FastToggleImmediateRef)); void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data, Local<ObjectTemplate> target) { Isolate* isolate = isolate_data->isolate(); SetMethod(isolate, target, "setupTimers", SetupTimers); SetFastMethod( isolate, target, "getLibuvNow", SlowGetLibuvNow, &fast_get_libuv_now_); SetFastMethod(isolate, target, "scheduleTimer", SlowScheduleTimer, &fast_schedule_timer_); SetFastMethod(isolate, target, "toggleTimerRef", SlowToggleTimerRef, &fast_toggle_timer_ref_); SetFastMethod(isolate, target, "toggleImmediateRef", SlowToggleImmediateRef, &fast_toggle_immediate_ref_); } void BindingData::CreatePerContextProperties(Local<Object> target, Local<Value> unused, Local<Context> context, void* priv) { Realm* realm = Realm::GetCurrent(context); Environment* env = realm->env(); BindingData* const binding_data = realm->AddBindingData<BindingData>(target); if (binding_data == nullptr) return; // TODO(joyeecheung): move these into BindingData. target ->Set(context, FIXED_ONE_BYTE_STRING(realm->isolate(), "immediateInfo"), env->immediate_info()->fields().GetJSArray()) .Check(); target ->Set(context, FIXED_ONE_BYTE_STRING(realm->isolate(), "timeoutInfo"), env->timeout_info().GetJSArray()) .Check(); } void BindingData::RegisterTimerExternalReferences( ExternalReferenceRegistry* registry) { registry->Register(SetupTimers); registry->Register(SlowGetLibuvNow); registry->Register(fast_get_libuv_now_); registry->Register(SlowScheduleTimer); registry->Register(fast_schedule_timer_); registry->Register(SlowToggleTimerRef); registry->Register(fast_toggle_timer_ref_); registry->Register(SlowToggleImmediateRef); registry->Register(fast_toggle_immediate_ref_); } } // namespace timers } // namespace node NODE_BINDING_CONTEXT_AWARE_INTERNAL( timers, node::timers::BindingData::CreatePerContextProperties) NODE_BINDING_PER_ISOLATE_INIT( timers, node::timers::BindingData::CreatePerIsolateProperties) NODE_BINDING_EXTERNAL_REFERENCE( timers, node::timers::BindingData::RegisterTimerExternalReferences)