bootstrap: initialize per-isolate properties of bindings separately

This patch moves the initialization of per-isolate properties of
the bindings that are in the embedded snapshot separate from the
initialization of their per-context properties. This is necessary
for workers to share the isolate snapshot with the main thread
and deserialize these properties instead of creating them from
scratch.

PR-URL: https://github.com/nodejs/node/pull/47768
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
This commit is contained in:
Joyee Cheung 2023-04-28 18:30:47 +02:00 committed by Node.js GitHub Bot
parent 19366066e1
commit 5466bec2c5
22 changed files with 384 additions and 289 deletions

View File

@ -44,6 +44,7 @@ using v8::MaybeLocal;
using v8::Nothing;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::PropertyAttribute;
using v8::ReadOnly;
using v8::String;
@ -351,24 +352,31 @@ Local<FunctionTemplate> AsyncWrap::GetConstructorTemplate(
return tmpl;
}
void AsyncWrap::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
void AsyncWrap::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
SetMethod(isolate, target, "setupHooks", SetupHooks);
SetMethod(isolate, target, "setCallbackTrampoline", SetCallbackTrampoline);
SetMethod(isolate, target, "pushAsyncContext", PushAsyncContext);
SetMethod(isolate, target, "popAsyncContext", PopAsyncContext);
SetMethod(isolate, target, "executionAsyncResource", ExecutionAsyncResource);
SetMethod(isolate, target, "clearAsyncIdStack", ClearAsyncIdStack);
SetMethod(isolate, target, "queueDestroyAsyncId", QueueDestroyAsyncId);
SetMethod(isolate, target, "setPromiseHooks", SetPromiseHooks);
SetMethod(isolate, target, "registerDestroyHook", RegisterDestroyHook);
AsyncWrap::GetConstructorTemplate(isolate_data);
}
void AsyncWrap::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
HandleScope scope(isolate);
SetMethod(context, target, "setupHooks", SetupHooks);
SetMethod(context, target, "setCallbackTrampoline", SetCallbackTrampoline);
SetMethod(context, target, "pushAsyncContext", PushAsyncContext);
SetMethod(context, target, "popAsyncContext", PopAsyncContext);
SetMethod(context, target, "executionAsyncResource", ExecutionAsyncResource);
SetMethod(context, target, "clearAsyncIdStack", ClearAsyncIdStack);
SetMethod(context, target, "queueDestroyAsyncId", QueueDestroyAsyncId);
SetMethod(context, target, "setPromiseHooks", SetPromiseHooks);
SetMethod(context, target, "registerDestroyHook", RegisterDestroyHook);
PropertyAttribute ReadOnlyDontDelete =
static_cast<PropertyAttribute>(ReadOnly | DontDelete);
@ -625,7 +633,6 @@ void AsyncWrap::AsyncReset(Local<Object> resource, double execution_async_id,
async_id_, trigger_async_id_);
}
void AsyncWrap::EmitAsyncInit(Environment* env,
Local<Object> object,
Local<String> type,
@ -710,6 +717,9 @@ Local<Object> AsyncWrap::GetOwner(Environment* env, Local<Object> obj) {
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(async_wrap, node::AsyncWrap::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(async_wrap,
node::AsyncWrap::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(async_wrap,
node::AsyncWrap::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(async_wrap,
node::AsyncWrap::RegisterExternalReferences)

View File

@ -147,10 +147,12 @@ class AsyncWrap : public BaseObject {
Environment* env);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(
IsolateData* isolate_data, v8::Local<v8::FunctionTemplate> target);
static void GetAsyncId(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PushAsyncContext(const v8::FunctionCallbackInfo<v8::Value>& args);

View File

@ -16,10 +16,12 @@ using v8::ArrayBuffer;
using v8::BackingStore;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::MaybeLocal;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Uint8Array;
using v8::Value;
@ -216,20 +218,23 @@ void BindingData::ToUnicode(const v8::FunctionCallbackInfo<v8::Value>& args) {
String::NewFromUtf8(env->isolate(), out.c_str()).ToLocalChecked());
}
void BindingData::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
BindingData* const binding_data =
realm->AddBindingData<BindingData>(context, target);
if (binding_data == nullptr) return;
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
SetMethod(isolate, target, "encodeInto", EncodeInto);
SetMethodNoSideEffect(isolate, target, "encodeUtf8String", EncodeUtf8String);
SetMethodNoSideEffect(isolate, target, "decodeUTF8", DecodeUTF8);
SetMethodNoSideEffect(isolate, target, "toASCII", ToASCII);
SetMethodNoSideEffect(isolate, target, "toUnicode", ToUnicode);
}
SetMethod(context, target, "encodeInto", EncodeInto);
SetMethodNoSideEffect(context, target, "encodeUtf8String", EncodeUtf8String);
SetMethodNoSideEffect(context, target, "decodeUTF8", DecodeUTF8);
SetMethodNoSideEffect(context, target, "toASCII", ToASCII);
SetMethodNoSideEffect(context, target, "toUnicode", ToUnicode);
void BindingData::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BindingData>(context, target);
}
void BindingData::RegisterTimerExternalReferences(
@ -245,7 +250,11 @@ void BindingData::RegisterTimerExternalReferences(
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
encoding_binding, node::encoding_binding::BindingData::Initialize)
encoding_binding,
node::encoding_binding::BindingData::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(
encoding_binding,
node::encoding_binding::BindingData::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(
encoding_binding,
node::encoding_binding::BindingData::RegisterTimerExternalReferences)

View File

@ -35,10 +35,12 @@ class BindingData : public SnapshotableObject {
static void ToASCII(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ToUnicode(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> ctor);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void RegisterTimerExternalReferences(
ExternalReferenceRegistry* registry);

View File

@ -154,19 +154,24 @@ void HandleWrap::OnClose(uv_handle_t* handle) {
wrap->MakeCallback(env->handle_onclose_symbol(), 0, nullptr);
}
}
Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(Environment* env) {
Local<FunctionTemplate> tmpl = env->handle_wrap_ctor_template();
return GetConstructorTemplate(env->isolate_data());
}
Local<FunctionTemplate> HandleWrap::GetConstructorTemplate(
IsolateData* isolate_data) {
Local<FunctionTemplate> tmpl = isolate_data->handle_wrap_ctor_template();
if (tmpl.IsEmpty()) {
Isolate* isolate = env->isolate();
Isolate* isolate = isolate_data->isolate();
tmpl = NewFunctionTemplate(isolate, nullptr);
tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HandleWrap"));
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
tmpl->SetClassName(
FIXED_ONE_BYTE_STRING(isolate_data->isolate(), "HandleWrap"));
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
SetProtoMethod(isolate, tmpl, "close", HandleWrap::Close);
SetProtoMethodNoSideEffect(isolate, tmpl, "hasRef", HandleWrap::HasRef);
SetProtoMethod(isolate, tmpl, "ref", HandleWrap::Ref);
SetProtoMethod(isolate, tmpl, "unref", HandleWrap::Unref);
env->set_handle_wrap_ctor_template(tmpl);
isolate_data->set_handle_wrap_ctor_template(tmpl);
}
return tmpl;
}

View File

@ -76,6 +76,8 @@ class HandleWrap : public AsyncWrap {
virtual void Close(
v8::Local<v8::Value> close_callback = v8::Local<v8::Value>());
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
IsolateData* isolate_data);
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);

View File

@ -31,8 +31,16 @@ static_assert(static_cast<int>(NM_F_LINKED) ==
#endif
#define NODE_BINDINGS_WITH_PER_ISOLATE_INIT(V) \
V(async_wrap) \
V(blob) \
V(builtins) \
V(contextify) \
V(encoding_binding) \
V(fs) \
V(timers) \
V(process_methods) \
V(performance) \
V(url) \
V(worker) \
NODE_BUILTIN_ICU_BINDINGS(V)

View File

@ -29,6 +29,7 @@ using v8::Int32;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Uint32;
using v8::Undefined;
@ -107,23 +108,25 @@ void BlobFromFilePath(const FunctionCallbackInfo<Value>& args) {
}
} // namespace
void Blob::Initialize(
Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
void Blob::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
SetMethod(isolate, target, "createBlob", New);
SetMethod(isolate, target, "storeDataObject", StoreDataObject);
SetMethod(isolate, target, "getDataObject", GetDataObject);
SetMethod(isolate, target, "revokeObjectURL", RevokeObjectURL);
SetMethod(isolate, target, "concat", Concat);
SetMethod(isolate, target, "createBlobFromFilePath", BlobFromFilePath);
}
void Blob::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
BlobBindingData* const binding_data =
realm->AddBindingData<BlobBindingData>(context, target);
if (binding_data == nullptr) return;
SetMethod(context, target, "createBlob", New);
SetMethod(context, target, "storeDataObject", StoreDataObject);
SetMethod(context, target, "getDataObject", GetDataObject);
SetMethod(context, target, "revokeObjectURL", RevokeObjectURL);
SetMethod(context, target, "concat", Concat);
SetMethod(context, target, "createBlobFromFilePath", BlobFromFilePath);
realm->AddBindingData<BlobBindingData>(context, target);
}
Local<FunctionTemplate> Blob::GetConstructorTemplate(Environment* env) {
@ -562,5 +565,7 @@ void Blob::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(blob, node::Blob::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(blob,
node::Blob::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(blob, node::Blob::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(blob, node::Blob::RegisterExternalReferences)

View File

@ -26,11 +26,12 @@ class Blob : public BaseObject {
static void RegisterExternalReferences(
ExternalReferenceRegistry* registry);
static void Initialize(
v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> ctor);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetReader(const v8::FunctionCallbackInfo<v8::Value>& args);

View File

@ -114,7 +114,6 @@ BaseObjectPtr<ContextifyContext> ContextifyContext::New(
Local<Object> sandbox_obj,
const ContextOptions& options) {
HandleScope scope(env->isolate());
InitializeGlobalTemplates(env->isolate_data());
Local<ObjectTemplate> object_template = env->contextify_global_template();
DCHECK(!object_template.IsEmpty());
const SnapshotData* snapshot_data = env->isolate_data()->snapshot_data();
@ -169,9 +168,6 @@ ContextifyContext::~ContextifyContext() {
}
void ContextifyContext::InitializeGlobalTemplates(IsolateData* isolate_data) {
if (!isolate_data->contextify_global_template().IsEmpty()) {
return;
}
DCHECK(isolate_data->contextify_wrapper_template().IsEmpty());
Local<FunctionTemplate> global_func_template =
FunctionTemplate::New(isolate_data->isolate());
@ -322,11 +318,12 @@ BaseObjectPtr<ContextifyContext> ContextifyContext::New(
return result;
}
void ContextifyContext::Init(Environment* env, Local<Object> target) {
Local<Context> context = env->context();
SetMethod(context, target, "makeContext", MakeContext);
SetMethod(context, target, "isContext", IsContext);
SetMethod(context, target, "compileFunction", CompileFunction);
void ContextifyContext::CreatePerIsolateProperties(
IsolateData* isolate_data, Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate();
SetMethod(isolate, target, "makeContext", MakeContext);
SetMethod(isolate, target, "isContext", IsContext);
SetMethod(isolate, target, "compileFunction", CompileFunction);
}
void ContextifyContext::RegisterExternalReferences(
@ -735,11 +732,10 @@ void ContextifyContext::IndexedPropertyDeleterCallback(
args.GetReturnValue().Set(false);
}
void ContextifyScript::Init(Environment* env, Local<Object> target) {
Isolate* isolate = env->isolate();
HandleScope scope(env->isolate());
Local<String> class_name =
FIXED_ONE_BYTE_STRING(env->isolate(), "ContextifyScript");
void ContextifyScript::CreatePerIsolateProperties(
IsolateData* isolate_data, Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate();
Local<String> class_name = FIXED_ONE_BYTE_STRING(isolate, "ContextifyScript");
Local<FunctionTemplate> script_tmpl = NewFunctionTemplate(isolate, New);
script_tmpl->InstanceTemplate()->SetInternalFieldCount(
@ -748,11 +744,8 @@ void ContextifyScript::Init(Environment* env, Local<Object> target) {
SetProtoMethod(isolate, script_tmpl, "createCachedData", CreateCachedData);
SetProtoMethod(isolate, script_tmpl, "runInContext", RunInContext);
Local<Context> context = env->context();
target->Set(context, class_name,
script_tmpl->GetFunction(context).ToLocalChecked()).Check();
env->set_script_context_constructor_template(script_tmpl);
target->Set(isolate, "ContextifyScript", script_tmpl);
isolate_data->set_script_context_constructor_template(script_tmpl);
}
void ContextifyScript::RegisterExternalReferences(
@ -1382,15 +1375,15 @@ void MicrotaskQueueWrap::New(const FunctionCallbackInfo<Value>& args) {
new MicrotaskQueueWrap(Environment::GetCurrent(args), args.This());
}
void MicrotaskQueueWrap::Init(Environment* env, Local<Object> target) {
Isolate* isolate = env->isolate();
void MicrotaskQueueWrap::CreatePerIsolateProperties(
IsolateData* isolate_data, Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate();
HandleScope scope(isolate);
Local<Context> context = env->context();
Local<FunctionTemplate> tmpl = NewFunctionTemplate(isolate, New);
tmpl->InstanceTemplate()->SetInternalFieldCount(
ContextifyScript::kInternalFieldCount);
env->set_microtask_queue_ctor_template(tmpl);
SetConstructorFunction(context, target, "MicrotaskQueue", tmpl);
isolate_data->set_microtask_queue_ctor_template(tmpl);
SetConstructorFunction(isolate, target, "MicrotaskQueue", tmpl);
}
void MicrotaskQueueWrap::RegisterExternalReferences(
@ -1398,30 +1391,37 @@ void MicrotaskQueueWrap::RegisterExternalReferences(
registry->Register(New);
}
void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
ContextifyContext::Init(env, target);
ContextifyScript::Init(env, target);
MicrotaskQueueWrap::Init(env, target);
void CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
ContextifyContext::CreatePerIsolateProperties(isolate_data, target);
ContextifyScript::CreatePerIsolateProperties(isolate_data, target);
MicrotaskQueueWrap::CreatePerIsolateProperties(isolate_data, target);
SetMethod(context, target, "startSigintWatchdog", StartSigintWatchdog);
SetMethod(context, target, "stopSigintWatchdog", StopSigintWatchdog);
SetMethod(isolate, target, "startSigintWatchdog", StartSigintWatchdog);
SetMethod(isolate, target, "stopSigintWatchdog", StopSigintWatchdog);
// Used in tests.
SetMethodNoSideEffect(
context, target, "watchdogHasPendingSigint", WatchdogHasPendingSigint);
isolate, target, "watchdogHasPendingSigint", WatchdogHasPendingSigint);
{
Local<FunctionTemplate> tpl = FunctionTemplate::New(env->isolate());
tpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "CompiledFnEntry"));
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate);
tpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "CompiledFnEntry"));
tpl->InstanceTemplate()->SetInternalFieldCount(
CompiledFnEntry::kInternalFieldCount);
env->set_compiled_fn_entry_template(tpl->InstanceTemplate());
isolate_data->set_compiled_fn_entry_template(tpl->InstanceTemplate());
}
SetMethod(isolate, target, "measureMemory", MeasureMemory);
}
static void CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
Local<Object> constants = Object::New(env->isolate());
Local<Object> measure_memory = Object::New(env->isolate());
@ -1447,8 +1447,6 @@ void Initialize(Local<Object> target,
READONLY_PROPERTY(constants, "measureMemory", measure_memory);
target->Set(context, env->constants_string(), constants).Check();
SetMethod(context, target, "measureMemory", MeasureMemory);
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
@ -1464,6 +1462,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
} // namespace contextify
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(contextify, node::contextify::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
contextify, node::contextify::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(contextify,
node::contextify::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(contextify,
node::contextify::RegisterExternalReferences)

View File

@ -18,7 +18,8 @@ class MicrotaskQueueWrap : public BaseObject {
const std::shared_ptr<v8::MicrotaskQueue>& microtask_queue() const;
static void Init(Environment* env, v8::Local<v8::Object> target);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::ObjectTemplate> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
@ -58,7 +59,8 @@ class ContextifyContext : public BaseObject {
v8::Local<v8::ObjectTemplate> object_template,
const SnapshotData* snapshot_data,
v8::MicrotaskQueue* queue);
static void Init(Environment* env, v8::Local<v8::Object> target);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::ObjectTemplate> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
static ContextifyContext* ContextFromContextifiedSandbox(
@ -156,7 +158,8 @@ class ContextifyScript : public BaseObject {
ContextifyScript(Environment* env, v8::Local<v8::Object> object);
~ContextifyScript() override;
static void Init(Environment* env, v8::Local<v8::Object> target);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::ObjectTemplate> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static bool InstanceOf(Environment* env, const v8::Local<v8::Value>& args);

View File

@ -74,7 +74,6 @@ using v8::Object;
using v8::ObjectTemplate;
using v8::Promise;
using v8::String;
using v8::Symbol;
using v8::Undefined;
using v8::Value;
@ -2827,121 +2826,117 @@ InternalFieldInfoBase* BindingData::Serialize(int index) {
return info;
}
void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
Environment* env = realm->env();
Isolate* isolate = env->isolate();
BindingData* const binding_data =
realm->AddBindingData<BindingData>(context, target);
if (binding_data == nullptr) return;
static void CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
SetMethod(context, target, "access", Access);
SetMethod(context, target, "close", Close);
SetMethod(context, target, "open", Open);
SetMethod(context, target, "openFileHandle", OpenFileHandle);
SetMethod(context, target, "read", Read);
SetMethod(context, target, "readBuffers", ReadBuffers);
SetMethod(context, target, "fdatasync", Fdatasync);
SetMethod(context, target, "fsync", Fsync);
SetMethod(context, target, "rename", Rename);
SetMethod(context, target, "ftruncate", FTruncate);
SetMethod(context, target, "rmdir", RMDir);
SetMethod(context, target, "mkdir", MKDir);
SetMethod(context, target, "readdir", ReadDir);
SetMethod(context, target, "internalModuleReadJSON", InternalModuleReadJSON);
SetMethod(context, target, "internalModuleStat", InternalModuleStat);
SetMethod(context, target, "stat", Stat);
SetMethod(context, target, "lstat", LStat);
SetMethod(context, target, "fstat", FStat);
SetMethod(context, target, "statfs", StatFs);
SetMethod(context, target, "link", Link);
SetMethod(context, target, "symlink", Symlink);
SetMethod(context, target, "readlink", ReadLink);
SetMethod(context, target, "unlink", Unlink);
SetMethod(context, target, "writeBuffer", WriteBuffer);
SetMethod(context, target, "writeBuffers", WriteBuffers);
SetMethod(context, target, "writeString", WriteString);
SetMethod(context, target, "realpath", RealPath);
SetMethod(context, target, "copyFile", CopyFile);
SetMethod(isolate, target, "access", Access);
SetMethod(isolate, target, "close", Close);
SetMethod(isolate, target, "open", Open);
SetMethod(isolate, target, "openFileHandle", OpenFileHandle);
SetMethod(isolate, target, "read", Read);
SetMethod(isolate, target, "readBuffers", ReadBuffers);
SetMethod(isolate, target, "fdatasync", Fdatasync);
SetMethod(isolate, target, "fsync", Fsync);
SetMethod(isolate, target, "rename", Rename);
SetMethod(isolate, target, "ftruncate", FTruncate);
SetMethod(isolate, target, "rmdir", RMDir);
SetMethod(isolate, target, "mkdir", MKDir);
SetMethod(isolate, target, "readdir", ReadDir);
SetMethod(isolate, target, "internalModuleReadJSON", InternalModuleReadJSON);
SetMethod(isolate, target, "internalModuleStat", InternalModuleStat);
SetMethod(isolate, target, "stat", Stat);
SetMethod(isolate, target, "lstat", LStat);
SetMethod(isolate, target, "fstat", FStat);
SetMethod(isolate, target, "statfs", StatFs);
SetMethod(isolate, target, "link", Link);
SetMethod(isolate, target, "symlink", Symlink);
SetMethod(isolate, target, "readlink", ReadLink);
SetMethod(isolate, target, "unlink", Unlink);
SetMethod(isolate, target, "writeBuffer", WriteBuffer);
SetMethod(isolate, target, "writeBuffers", WriteBuffers);
SetMethod(isolate, target, "writeString", WriteString);
SetMethod(isolate, target, "realpath", RealPath);
SetMethod(isolate, target, "copyFile", CopyFile);
SetMethod(context, target, "chmod", Chmod);
SetMethod(context, target, "fchmod", FChmod);
SetMethod(isolate, target, "chmod", Chmod);
SetMethod(isolate, target, "fchmod", FChmod);
SetMethod(context, target, "chown", Chown);
SetMethod(context, target, "fchown", FChown);
SetMethod(context, target, "lchown", LChown);
SetMethod(isolate, target, "chown", Chown);
SetMethod(isolate, target, "fchown", FChown);
SetMethod(isolate, target, "lchown", LChown);
SetMethod(context, target, "utimes", UTimes);
SetMethod(context, target, "futimes", FUTimes);
SetMethod(context, target, "lutimes", LUTimes);
SetMethod(isolate, target, "utimes", UTimes);
SetMethod(isolate, target, "futimes", FUTimes);
SetMethod(isolate, target, "lutimes", LUTimes);
SetMethod(context, target, "mkdtemp", Mkdtemp);
SetMethod(isolate, target, "mkdtemp", Mkdtemp);
target
->Set(context,
FIXED_ONE_BYTE_STRING(isolate, "kFsStatsFieldsNumber"),
Integer::New(
isolate,
static_cast<int32_t>(FsStatsOffset::kFsStatsFieldsNumber)))
.Check();
StatWatcher::CreatePerIsolateProperties(isolate_data, ctor);
StatWatcher::Initialize(env, target);
target->Set(
FIXED_ONE_BYTE_STRING(isolate, "kFsStatsFieldsNumber"),
Integer::New(isolate,
static_cast<int32_t>(FsStatsOffset::kFsStatsFieldsNumber)));
// Create FunctionTemplate for FSReqCallback
Local<FunctionTemplate> fst = NewFunctionTemplate(isolate, NewFSReqCallback);
fst->InstanceTemplate()->SetInternalFieldCount(
FSReqBase::kInternalFieldCount);
fst->Inherit(AsyncWrap::GetConstructorTemplate(env));
SetConstructorFunction(context, target, "FSReqCallback", fst);
fst->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
SetConstructorFunction(isolate, target, "FSReqCallback", fst);
// Create FunctionTemplate for FileHandleReadWrap. Theres no need
// to do anything in the constructor, so we only store the instance template.
Local<FunctionTemplate> fh_rw = FunctionTemplate::New(isolate);
fh_rw->InstanceTemplate()->SetInternalFieldCount(
FSReqBase::kInternalFieldCount);
fh_rw->Inherit(AsyncWrap::GetConstructorTemplate(env));
fh_rw->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
Local<String> fhWrapString =
FIXED_ONE_BYTE_STRING(isolate, "FileHandleReqWrap");
fh_rw->SetClassName(fhWrapString);
env->set_filehandlereadwrap_template(
fst->InstanceTemplate());
isolate_data->set_filehandlereadwrap_template(fst->InstanceTemplate());
// Create Function Template for FSReqPromise
Local<FunctionTemplate> fpt = FunctionTemplate::New(isolate);
fpt->Inherit(AsyncWrap::GetConstructorTemplate(env));
fpt->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
Local<String> promiseString =
FIXED_ONE_BYTE_STRING(isolate, "FSReqPromise");
fpt->SetClassName(promiseString);
Local<ObjectTemplate> fpo = fpt->InstanceTemplate();
fpo->SetInternalFieldCount(FSReqBase::kInternalFieldCount);
env->set_fsreqpromise_constructor_template(fpo);
isolate_data->set_fsreqpromise_constructor_template(fpo);
// Create FunctionTemplate for FileHandle
Local<FunctionTemplate> fd = NewFunctionTemplate(isolate, FileHandle::New);
fd->Inherit(AsyncWrap::GetConstructorTemplate(env));
fd->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
SetProtoMethod(isolate, fd, "close", FileHandle::Close);
SetProtoMethod(isolate, fd, "releaseFD", FileHandle::ReleaseFD);
Local<ObjectTemplate> fdt = fd->InstanceTemplate();
fdt->SetInternalFieldCount(FileHandle::kInternalFieldCount);
StreamBase::AddMethods(env, fd);
SetConstructorFunction(context, target, "FileHandle", fd);
env->set_fd_constructor_template(fdt);
StreamBase::AddMethods(isolate_data, fd);
SetConstructorFunction(isolate, target, "FileHandle", fd);
isolate_data->set_fd_constructor_template(fdt);
// Create FunctionTemplate for FileHandle::CloseReq
Local<FunctionTemplate> fdclose = FunctionTemplate::New(isolate);
fdclose->SetClassName(FIXED_ONE_BYTE_STRING(isolate,
"FileHandleCloseReq"));
fdclose->Inherit(AsyncWrap::GetConstructorTemplate(env));
fdclose->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));
Local<ObjectTemplate> fdcloset = fdclose->InstanceTemplate();
fdcloset->SetInternalFieldCount(FSReqBase::kInternalFieldCount);
env->set_fdclose_constructor_template(fdcloset);
isolate_data->set_fdclose_constructor_template(fdcloset);
target->Set(context,
FIXED_ONE_BYTE_STRING(isolate, "kUsePromises"),
env->fs_use_promises_symbol()).Check();
target->Set(isolate, "kUsePromises", isolate_data->fs_use_promises_symbol());
}
static void CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BindingData>(context, target);
}
BindingData* FSReqBase::binding_data() {
@ -3004,5 +2999,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
} // end namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(fs, node::fs::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(fs, node::fs::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(fs, node::fs::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(fs, node::fs::RegisterExternalReferences)

View File

@ -48,7 +48,8 @@ void PatchProcessObject(const v8::FunctionCallbackInfo<v8::Value>& args);
namespace process {
class BindingData : public SnapshotableObject {
public:
void AddMethods();
static void AddMethods(v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
using InternalFieldInfo = InternalFieldInfoBase;

View File

@ -41,6 +41,7 @@ using v8::CFunction;
using v8::Context;
using v8::Float64Array;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::HeapStatistics;
using v8::Integer;
using v8::Isolate;
@ -49,6 +50,7 @@ using v8::Maybe;
using v8::NewStringType;
using v8::Number;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Uint32;
using v8::Value;
@ -478,11 +480,11 @@ BindingData::BindingData(Realm* realm, v8::Local<v8::Object> object)
v8::CFunction BindingData::fast_number_(v8::CFunction::Make(FastNumber));
v8::CFunction BindingData::fast_bigint_(v8::CFunction::Make(FastBigInt));
void BindingData::AddMethods() {
Local<Context> ctx = env()->context();
SetFastMethodNoSideEffect(ctx, object(), "hrtime", SlowNumber, &fast_number_);
void BindingData::AddMethods(Isolate* isolate, Local<ObjectTemplate> target) {
SetFastMethodNoSideEffect(
ctx, object(), "hrtimeBigInt", SlowBigInt, &fast_bigint_);
isolate, target, "hrtime", SlowNumber, &fast_number_);
SetFastMethodNoSideEffect(
isolate, target, "hrtimeBigInt", SlowBigInt, &fast_bigint_);
}
void BindingData::RegisterExternalReferences(
@ -569,44 +571,45 @@ void BindingData::Deserialize(Local<Context> context,
CHECK_NOT_NULL(binding);
}
static void Initialize(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>(context, target);
if (binding_data == nullptr) return;
binding_data->AddMethods();
static void CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
BindingData::AddMethods(isolate, target);
// define various internal methods
if (env->owns_process_state()) {
SetMethod(context, target, "_debugProcess", DebugProcess);
SetMethod(context, target, "abort", Abort);
SetMethod(context, target, "causeSegfault", CauseSegfault);
SetMethod(context, target, "chdir", Chdir);
}
SetMethod(isolate, target, "_debugProcess", DebugProcess);
SetMethod(isolate, target, "abort", Abort);
SetMethod(isolate, target, "causeSegfault", CauseSegfault);
SetMethod(isolate, target, "chdir", Chdir);
SetMethod(context, target, "umask", Umask);
SetMethod(context, target, "memoryUsage", MemoryUsage);
SetMethod(context, target, "constrainedMemory", GetConstrainedMemory);
SetMethod(context, target, "rss", Rss);
SetMethod(context, target, "cpuUsage", CPUUsage);
SetMethod(context, target, "resourceUsage", ResourceUsage);
SetMethod(isolate, target, "umask", Umask);
SetMethod(isolate, target, "memoryUsage", MemoryUsage);
SetMethod(isolate, target, "constrainedMemory", GetConstrainedMemory);
SetMethod(isolate, target, "rss", Rss);
SetMethod(isolate, target, "cpuUsage", CPUUsage);
SetMethod(isolate, target, "resourceUsage", ResourceUsage);
SetMethod(context, target, "_debugEnd", DebugEnd);
SetMethod(context, target, "_getActiveRequests", GetActiveRequests);
SetMethod(context, target, "_getActiveHandles", GetActiveHandles);
SetMethod(context, target, "getActiveResourcesInfo", GetActiveResourcesInfo);
SetMethod(context, target, "_kill", Kill);
SetMethod(context, target, "_rawDebug", RawDebug);
SetMethod(isolate, target, "_debugEnd", DebugEnd);
SetMethod(isolate, target, "_getActiveRequests", GetActiveRequests);
SetMethod(isolate, target, "_getActiveHandles", GetActiveHandles);
SetMethod(isolate, target, "getActiveResourcesInfo", GetActiveResourcesInfo);
SetMethod(isolate, target, "_kill", Kill);
SetMethod(isolate, target, "_rawDebug", RawDebug);
SetMethodNoSideEffect(context, target, "cwd", Cwd);
SetMethod(context, target, "dlopen", binding::DLOpen);
SetMethod(context, target, "reallyExit", ReallyExit);
SetMethodNoSideEffect(context, target, "uptime", Uptime);
SetMethod(context, target, "patchProcessObject", PatchProcessObject);
SetMethodNoSideEffect(isolate, target, "cwd", Cwd);
SetMethod(isolate, target, "dlopen", binding::DLOpen);
SetMethod(isolate, target, "reallyExit", ReallyExit);
SetMethodNoSideEffect(isolate, target, "uptime", Uptime);
SetMethod(isolate, target, "patchProcessObject", PatchProcessObject);
}
static void CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BindingData>(context, target);
}
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
@ -641,6 +644,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
} // namespace process
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(process_methods, node::process::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(process_methods,
node::process::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(process_methods,
node::process::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(process_methods,
node::process::RegisterExternalReferences)

View File

@ -40,21 +40,22 @@ using v8::Integer;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::Uint32;
using v8::Value;
void StatWatcher::Initialize(Environment* env, Local<Object> target) {
Isolate* isolate = env->isolate();
HandleScope scope(env->isolate());
void StatWatcher::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
Local<FunctionTemplate> t = NewFunctionTemplate(isolate, StatWatcher::New);
t->InstanceTemplate()->SetInternalFieldCount(
StatWatcher::kInternalFieldCount);
t->Inherit(HandleWrap::GetConstructorTemplate(env));
t->Inherit(HandleWrap::GetConstructorTemplate(isolate_data));
SetProtoMethod(isolate, t, "start", StatWatcher::Start);
SetConstructorFunction(env->context(), target, "StatWatcher", t);
SetConstructorFunction(isolate, target, "StatWatcher", t);
}
void StatWatcher::RegisterExternalReferences(

View File

@ -39,7 +39,8 @@ class ExternalReferenceRegistry;
class StatWatcher : public HandleWrap {
public:
static void Initialize(Environment* env, v8::Local<v8::Object> target);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> ctor);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
protected:

View File

@ -19,11 +19,13 @@ using v8::CFunction;
using v8::Context;
using v8::FastOneByteString;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::ObjectTemplate;
using v8::String;
using v8::Value;
@ -322,22 +324,25 @@ void BindingData::UpdateComponents(const ada::url_components& components,
"kURLComponentsLength should be up-to-date");
}
void BindingData::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
BindingData* const binding_data =
realm->AddBindingData<BindingData>(context, target);
if (binding_data == nullptr) return;
SetMethodNoSideEffect(context, target, "domainToASCII", DomainToASCII);
SetMethodNoSideEffect(context, target, "domainToUnicode", DomainToUnicode);
SetMethodNoSideEffect(context, target, "format", Format);
SetMethod(context, target, "parse", Parse);
SetMethod(context, target, "update", Update);
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
SetMethodNoSideEffect(isolate, target, "domainToASCII", DomainToASCII);
SetMethodNoSideEffect(isolate, target, "domainToUnicode", DomainToUnicode);
SetMethodNoSideEffect(isolate, target, "format", Format);
SetMethod(isolate, target, "parse", Parse);
SetMethod(isolate, target, "update", Update);
SetFastMethodNoSideEffect(
context, target, "canParse", CanParse, &fast_can_parse_);
isolate, target, "canParse", CanParse, &fast_can_parse_);
}
void BindingData::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BindingData>(context, target);
}
void BindingData::RegisterExternalReferences(
@ -365,6 +370,9 @@ std::string FromFilePath(const std::string_view file_path) {
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(url, node::url::BindingData::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
url, node::url::BindingData::CreatePerContextProperties)
NODE_BINDING_PER_ISOLATE_INIT(
url, node::url::BindingData::CreatePerIsolateProperties)
NODE_BINDING_EXTERNAL_REFERENCE(
url, node::url::BindingData::RegisterExternalReferences)

View File

@ -56,10 +56,12 @@ class BindingData : public SnapshotableObject {
static void Parse(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Update(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> ctor);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
private:

View File

@ -491,13 +491,12 @@ Local<Object> StreamBase::GetObject() {
return GetAsyncWrap()->object();
}
void StreamBase::AddMethod(Environment* env,
void StreamBase::AddMethod(Isolate* isolate,
Local<Signature> signature,
enum PropertyAttribute attributes,
Local<FunctionTemplate> t,
JSMethodFunction* stream_method,
Local<String> string) {
Isolate* isolate = env->isolate();
Local<FunctionTemplate> templ =
NewFunctionTemplate(isolate,
stream_method,
@ -509,19 +508,37 @@ void StreamBase::AddMethod(Environment* env,
}
void StreamBase::AddMethods(Environment* env, Local<FunctionTemplate> t) {
Isolate* isolate = env->isolate();
AddMethods(env->isolate_data(), t);
}
void StreamBase::AddMethods(IsolateData* isolate_data,
Local<FunctionTemplate> t) {
Isolate* isolate = isolate_data->isolate();
HandleScope scope(isolate);
enum PropertyAttribute attributes =
static_cast<PropertyAttribute>(ReadOnly | DontDelete | DontEnum);
Local<Signature> sig = Signature::New(isolate, t);
AddMethod(env, sig, attributes, t, GetFD, env->fd_string());
AddMethod(
env, sig, attributes, t, GetExternal, env->external_stream_string());
AddMethod(env, sig, attributes, t, GetBytesRead, env->bytes_read_string());
AddMethod(
env, sig, attributes, t, GetBytesWritten, env->bytes_written_string());
AddMethod(isolate, sig, attributes, t, GetFD, isolate_data->fd_string());
AddMethod(isolate,
sig,
attributes,
t,
GetExternal,
isolate_data->external_stream_string());
AddMethod(isolate,
sig,
attributes,
t,
GetBytesRead,
isolate_data->bytes_read_string());
AddMethod(isolate,
sig,
attributes,
t,
GetBytesWritten,
isolate_data->bytes_written_string());
SetProtoMethod(isolate, t, "readStart", JSMethod<&StreamBase::ReadStartJS>);
SetProtoMethod(isolate, t, "readStop", JSMethod<&StreamBase::ReadStopJS>);
SetProtoMethod(isolate, t, "shutdown", JSMethod<&StreamBase::Shutdown>);

View File

@ -313,6 +313,8 @@ class StreamBase : public StreamResource {
kInternalFieldCount
};
static void AddMethods(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> target);
static void AddMethods(Environment* env,
v8::Local<v8::FunctionTemplate> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
@ -409,7 +411,7 @@ class StreamBase : public StreamResource {
EmitToJSStreamListener default_listener_;
void SetWriteResult(const StreamWriteResult& res);
static void AddMethod(Environment* env,
static void AddMethod(v8::Isolate* isolate,
v8::Local<v8::Signature> sig,
enum v8::PropertyAttribute attributes,
v8::Local<v8::FunctionTemplate> t,

View File

@ -12,9 +12,12 @@ namespace timers {
using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
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) {
@ -119,35 +122,41 @@ v8::CFunction BindingData::fast_toggle_timer_ref_(
v8::CFunction BindingData::fast_toggle_immediate_ref_(
v8::CFunction::Make(FastToggleImmediateRef));
void BindingData::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
Local<FunctionTemplate> ctor) {
Isolate* isolate = isolate_data->isolate();
Local<ObjectTemplate> target = ctor->InstanceTemplate();
SetMethod(isolate, target, "setupTimers", SetupTimers);
SetFastMethod(
isolate, target, "getLibuvNow", SlowGetLibuvNow, &fast_get_libuv_now_);
SetFastMethod(isolate,
target,
"scheduleTimer",
SlowScheduleTimer,
&fast_schedule_timers_);
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>(context, target);
if (binding_data == nullptr) return;
SetMethod(context, target, "setupTimers", SetupTimers);
SetFastMethod(
context, target, "getLibuvNow", SlowGetLibuvNow, &fast_get_libuv_now_);
SetFastMethod(context,
target,
"scheduleTimer",
SlowScheduleTimer,
&fast_schedule_timers_);
SetFastMethod(context,
target,
"toggleTimerRef",
SlowToggleTimerRef,
&fast_toggle_timer_ref_);
SetFastMethod(context,
target,
"toggleImmediateRef",
SlowToggleImmediateRef,
&fast_toggle_immediate_ref_);
// TODO(joyeecheung): move these into BindingData.
target
->Set(context,
@ -187,7 +196,9 @@ void BindingData::RegisterTimerExternalReferences(
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(timers,
node::timers::BindingData::Initialize)
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)

View File

@ -45,10 +45,12 @@ class BindingData : public SnapshotableObject {
static void FastToggleImmediateRef(v8::Local<v8::Object> receiver, bool ref);
static void ToggleImmediateRefImpl(BindingData* data, bool ref);
static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void CreatePerIsolateProperties(IsolateData* isolate_data,
v8::Local<v8::FunctionTemplate> ctor);
static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
static void RegisterTimerExternalReferences(
ExternalReferenceRegistry* registry);