From 0fac393d263fc7e2f4f054c9d4aab0c1c3cf00c8 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 25 Feb 2020 14:37:33 -0800 Subject: [PATCH] src: improve handling of internal field counting Change suggested by bnoordhuis. Improve handing of internal field counting by using enums. Helps protect against future possible breakage if field indexes are ever changed or added to. Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/31960 Reviewed-By: Anna Henningsen Reviewed-By: Franziska Hinkelmann Reviewed-By: Ben Noordhuis Reviewed-By: Matteo Collina --- src/async_wrap.cc | 22 ++++++++++++---------- src/base_object-inl.h | 14 +++++++++----- src/base_object.h | 2 ++ src/cares_wrap.cc | 3 ++- src/fs_event_wrap.cc | 3 ++- src/heap_utils.cc | 2 +- src/inspector_js_api.cc | 3 ++- src/js_stream.cc | 2 +- src/module_wrap.cc | 3 ++- src/node_contextify.cc | 14 +++++++++----- src/node_contextify.h | 1 + src/node_crypto.cc | 26 +++++++++++++++++--------- src/node_dir.cc | 2 +- src/node_dir.h | 2 -- src/node_file.cc | 12 +++++++----- src/node_http2.cc | 9 +++++---- src/node_http_parser.cc | 2 +- src/node_i18n.cc | 2 +- src/node_messaging.cc | 3 ++- src/node_perf.cc | 3 ++- src/node_serdes.cc | 6 ++++-- src/node_stat_watcher.cc | 3 ++- src/node_trace_events.cc | 3 ++- src/node_util.cc | 3 ++- src/node_wasi.cc | 2 +- src/node_watchdog.cc | 3 ++- src/node_worker.cc | 6 ++++-- src/node_zlib.cc | 3 ++- src/pipe_wrap.cc | 2 +- src/process_wrap.cc | 3 ++- src/signal_wrap.cc | 3 ++- src/stream_base-inl.h | 22 ++++++++++++++-------- src/stream_base.cc | 10 +++++++--- src/stream_base.h | 22 +++++++++++++++++----- src/stream_pipe.cc | 3 ++- src/stream_wrap.cc | 8 ++++---- src/tcp_wrap.cc | 3 +-- src/tls_wrap.cc | 3 +-- src/tty_wrap.cc | 3 +-- src/udp_wrap.cc | 2 +- 40 files changed, 151 insertions(+), 92 deletions(-) diff --git a/src/async_wrap.cc b/src/async_wrap.cc index 315d4177c8ca48..892e33c624bb88 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -176,6 +176,10 @@ void AsyncWrap::EmitAfter(Environment* env, double async_id) { class PromiseWrap : public AsyncWrap { public: + enum InternalFields { + kIsChainedPromiseField = AsyncWrap::kInternalFieldCount, + kInternalFieldCount + }; PromiseWrap(Environment* env, Local object, bool silent) : AsyncWrap(env, object, PROVIDER_PROMISE, kInvalidAsyncId, silent) { MakeWeak(); @@ -185,9 +189,6 @@ class PromiseWrap : public AsyncWrap { SET_MEMORY_INFO_NAME(PromiseWrap) SET_SELF_SIZE(PromiseWrap) - static constexpr int kIsChainedPromiseField = 1; - static constexpr int kInternalFieldCount = 2; - static PromiseWrap* New(Environment* env, Local promise, PromiseWrap* parent_wrap, @@ -214,15 +215,16 @@ PromiseWrap* PromiseWrap::New(Environment* env, void PromiseWrap::getIsChainedPromise(Local property, const PropertyCallbackInfo& info) { info.GetReturnValue().Set( - info.Holder()->GetInternalField(kIsChainedPromiseField)); + info.Holder()->GetInternalField(PromiseWrap::kIsChainedPromiseField)); } static PromiseWrap* extractPromiseWrap(Local promise) { - Local resource_object_value = promise->GetInternalField(0); - if (resource_object_value->IsObject()) { - return Unwrap(resource_object_value.As()); - } - return nullptr; + // This check is imperfect. If the internal field is set, it should + // be an object. If it's not, we just ignore it. Ideally v8 would + // have had GetInternalField returning a MaybeLocal but this works + // for now. + Local obj = promise->GetInternalField(0); + return obj->IsObject() ? Unwrap(obj.As()) : nullptr; } static void PromiseHook(PromiseHookType type, Local promise, @@ -560,7 +562,7 @@ void AsyncWrap::Initialize(Local target, function_template->SetClassName(class_name); function_template->Inherit(AsyncWrap::GetConstructorTemplate(env)); auto instance_template = function_template->InstanceTemplate(); - instance_template->SetInternalFieldCount(1); + instance_template->SetInternalFieldCount(AsyncWrap::kInternalFieldCount); auto function = function_template->GetFunction(env->context()).ToLocalChecked(); target->Set(env->context(), class_name, function).Check(); diff --git a/src/base_object-inl.h b/src/base_object-inl.h index 8b2b30021a8520..c9b4e1491fc947 100644 --- a/src/base_object-inl.h +++ b/src/base_object-inl.h @@ -43,7 +43,9 @@ BaseObject::BaseObject(Environment* env, v8::Local object) : persistent_handle_(env->isolate(), object), env_(env) { CHECK_EQ(false, object.IsEmpty()); CHECK_GT(object->InternalFieldCount(), 0); - object->SetAlignedPointerInInternalField(0, static_cast(this)); + object->SetAlignedPointerInInternalField( + BaseObject::kSlot, + static_cast(this)); env->AddCleanupHook(DeleteMe, static_cast(this)); env->modify_base_object_count(1); } @@ -67,7 +69,7 @@ BaseObject::~BaseObject() { { v8::HandleScope handle_scope(env()->isolate()); - object()->SetAlignedPointerInInternalField(0, nullptr); + object()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr); } } @@ -100,7 +102,8 @@ Environment* BaseObject::env() const { BaseObject* BaseObject::FromJSObject(v8::Local obj) { CHECK_GT(obj->InternalFieldCount(), 0); - return static_cast(obj->GetAlignedPointerFromInternalField(0)); + return static_cast( + obj->GetAlignedPointerFromInternalField(BaseObject::kSlot)); } @@ -148,11 +151,12 @@ BaseObject::MakeLazilyInitializedJSTemplate(Environment* env) { auto constructor = [](const v8::FunctionCallbackInfo& args) { DCHECK(args.IsConstructCall()); DCHECK_GT(args.This()->InternalFieldCount(), 0); - args.This()->SetAlignedPointerInInternalField(0, nullptr); + args.This()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr); }; v8::Local t = env->NewFunctionTemplate(constructor); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + BaseObject::kInternalFieldCount); return t; } diff --git a/src/base_object.h b/src/base_object.h index e7ef029995f1cf..2c67445c31fbb6 100644 --- a/src/base_object.h +++ b/src/base_object.h @@ -36,6 +36,8 @@ class BaseObjectPtrImpl; class BaseObject : public MemoryRetainer { public: + enum InternalFields { kSlot, kInternalFieldCount }; + // Associates this object with `object`. It uses the 0th internal field for // that, and in particular aborts if there is no such field. inline BaseObject(Environment* env, v8::Local object); diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 8eeaeddf8300d8..8abf662caa3142 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -2223,7 +2223,8 @@ void Initialize(Local target, Local channel_wrap = env->NewFunctionTemplate(ChannelWrap::New); - channel_wrap->InstanceTemplate()->SetInternalFieldCount(1); + channel_wrap->InstanceTemplate()->SetInternalFieldCount( + ChannelWrap::kInternalFieldCount); channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env)); env->SetProtoMethod(channel_wrap, "queryAny", Query); diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index d38556b1bf8011..858455bff2d42d 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -97,7 +97,8 @@ void FSEventWrap::Initialize(Local target, auto fsevent_string = FIXED_ONE_BYTE_STRING(env->isolate(), "FSEvent"); Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + FSEventWrap::kInternalFieldCount); t->SetClassName(fsevent_string); t->Inherit(AsyncWrap::GetConstructorTemplate(env)); diff --git a/src/heap_utils.cc b/src/heap_utils.cc index 68cd532c230830..c21ff8c80062a8 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -341,7 +341,7 @@ BaseObjectPtr CreateHeapSnapshotStream( Local os = FunctionTemplate::New(env->isolate()); os->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local ost = os->InstanceTemplate(); - ost->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + ost->SetInternalFieldCount(StreamBase::kInternalFieldCount); os->SetClassName( FIXED_ONE_BYTE_STRING(env->isolate(), "HeapSnapshotStream")); StreamBase::AddMethods(env, os); diff --git a/src/inspector_js_api.cc b/src/inspector_js_api.cc index 703c9ff598fdf2..ed3b36ad5ca80e 100644 --- a/src/inspector_js_api.cc +++ b/src/inspector_js_api.cc @@ -105,7 +105,8 @@ class JSBindingsConnection : public AsyncWrap { Local class_name = ConnectionType::GetClassName(env); Local tmpl = env->NewFunctionTemplate(JSBindingsConnection::New); - tmpl->InstanceTemplate()->SetInternalFieldCount(1); + tmpl->InstanceTemplate()->SetInternalFieldCount( + JSBindingsConnection::kInternalFieldCount); tmpl->SetClassName(class_name); tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env)); env->SetProtoMethod(tmpl, "dispatch", JSBindingsConnection::Dispatch); diff --git a/src/js_stream.cc b/src/js_stream.cc index 64941b1c4e4fb7..e4da0ce747e3a0 100644 --- a/src/js_stream.cc +++ b/src/js_stream.cc @@ -204,7 +204,7 @@ void JSStream::Initialize(Local target, FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream"); t->SetClassName(jsStreamString); t->InstanceTemplate() - ->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + ->SetInternalFieldCount(StreamBase::kInternalFieldCount); t->Inherit(AsyncWrap::GetConstructorTemplate(env)); env->SetProtoMethod(t, "finishWrite", Finish); diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 5d758bac620b54..2b1708088bf449 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -1636,7 +1636,8 @@ void ModuleWrap::Initialize(Local target, Local tpl = env->NewFunctionTemplate(New); tpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap")); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->InstanceTemplate()->SetInternalFieldCount( + ModuleWrap::kInternalFieldCount); env->SetProtoMethod(tpl, "link", Link); env->SetProtoMethod(tpl, "instantiate", Instantiate); diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 6de27188be6c7f..e6e2d123c04278 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -145,7 +145,7 @@ MaybeLocal ContextifyContext::CreateDataWrapper(Environment* env) { return MaybeLocal(); } - wrapper->SetAlignedPointerInInternalField(0, this); + wrapper->SetAlignedPointerInInternalField(ContextifyContext::kSlot, this); return wrapper; } @@ -232,7 +232,8 @@ MaybeLocal ContextifyContext::CreateV8Context( void ContextifyContext::Init(Environment* env, Local target) { Local function_template = FunctionTemplate::New(env->isolate()); - function_template->InstanceTemplate()->SetInternalFieldCount(1); + function_template->InstanceTemplate()->SetInternalFieldCount( + ContextifyContext::kInternalFieldCount); env->set_script_data_constructor_function( function_template->GetFunction(env->context()).ToLocalChecked()); @@ -331,7 +332,8 @@ template ContextifyContext* ContextifyContext::Get(const PropertyCallbackInfo& args) { Local data = args.Data(); return static_cast( - data.As()->GetAlignedPointerFromInternalField(0)); + data.As()->GetAlignedPointerFromInternalField( + ContextifyContext::kSlot)); } // static @@ -628,7 +630,8 @@ void ContextifyScript::Init(Environment* env, Local target) { FIXED_ONE_BYTE_STRING(env->isolate(), "ContextifyScript"); Local script_tmpl = env->NewFunctionTemplate(New); - script_tmpl->InstanceTemplate()->SetInternalFieldCount(1); + script_tmpl->InstanceTemplate()->SetInternalFieldCount( + ContextifyScript::kInternalFieldCount); script_tmpl->SetClassName(class_name); env->SetProtoMethod(script_tmpl, "createCachedData", CreateCachedData); env->SetProtoMethod(script_tmpl, "runInContext", RunInContext); @@ -1251,7 +1254,8 @@ void Initialize(Local target, { Local tpl = FunctionTemplate::New(env->isolate()); tpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "CompiledFnEntry")); - tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->InstanceTemplate()->SetInternalFieldCount( + CompiledFnEntry::kInternalFieldCount); env->set_compiled_fn_entry_template(tpl->InstanceTemplate()); } diff --git a/src/node_contextify.h b/src/node_contextify.h index cf1e8475075fcb..f04ea86f41abac 100644 --- a/src/node_contextify.h +++ b/src/node_contextify.h @@ -19,6 +19,7 @@ struct ContextOptions { class ContextifyContext { public: + enum InternalFields { kSlot, kInternalFieldCount }; ContextifyContext(Environment* env, v8::Local sandbox_obj, const ContextOptions& options); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 08982cfcfa1b29..0b48821cf6c8af 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -464,7 +464,8 @@ static T* MallocOpenSSL(size_t count) { void SecureContext::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + SecureContext::kInternalFieldCount); Local secureContextString = FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext"); t->SetClassName(secureContextString); @@ -3803,7 +3804,8 @@ EVP_PKEY* ManagedEVPPKey::get() const { Local KeyObject::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + KeyObject::kInternalFieldCount); env->SetProtoMethod(t, "init", Init); env->SetProtoMethodNoSideEffect(t, "getSymmetricKeySize", @@ -4036,7 +4038,8 @@ CipherBase::CipherBase(Environment* env, void CipherBase::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + CipherBase::kInternalFieldCount); env->SetProtoMethod(t, "init", Init); env->SetProtoMethod(t, "initiv", InitIv); @@ -4663,7 +4666,8 @@ Hmac::Hmac(Environment* env, v8::Local wrap) void Hmac::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + Hmac::kInternalFieldCount); env->SetProtoMethod(t, "init", HmacInit); env->SetProtoMethod(t, "update", HmacUpdate); @@ -4789,7 +4793,8 @@ Hash::Hash(Environment* env, v8::Local wrap) void Hash::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + Hash::kInternalFieldCount); env->SetProtoMethod(t, "update", HashUpdate); env->SetProtoMethod(t, "digest", HashDigest); @@ -5061,7 +5066,8 @@ Sign::Sign(Environment* env, v8::Local wrap) : SignBase(env, wrap) { void Sign::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + SignBase::kInternalFieldCount); env->SetProtoMethod(t, "init", SignInit); env->SetProtoMethod(t, "update", SignUpdate); @@ -5385,7 +5391,8 @@ Verify::Verify(Environment* env, v8::Local wrap) : void Verify::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + SignBase::kInternalFieldCount); env->SetProtoMethod(t, "init", VerifyInit); env->SetProtoMethod(t, "update", VerifyUpdate); @@ -5697,7 +5704,8 @@ void DiffieHellman::Initialize(Environment* env, Local target) { const PropertyAttribute attributes = static_cast(ReadOnly | DontDelete); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + DiffieHellman::kInternalFieldCount); env->SetProtoMethod(t, "generateKeys", GenerateKeys); env->SetProtoMethod(t, "computeSecret", ComputeSecret); @@ -6036,7 +6044,7 @@ void ECDH::Initialize(Environment* env, Local target) { Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount(ECDH::kInternalFieldCount); env->SetProtoMethod(t, "generateKeys", GenerateKeys); env->SetProtoMethod(t, "computeSecret", ComputeSecret); diff --git a/src/node_dir.cc b/src/node_dir.cc index ec53d8216bcba0..9923f042779f2e 100644 --- a/src/node_dir.cc +++ b/src/node_dir.cc @@ -358,7 +358,7 @@ void Initialize(Local target, env->SetProtoMethod(dir, "read", DirHandle::Read); env->SetProtoMethod(dir, "close", DirHandle::Close); Local dirt = dir->InstanceTemplate(); - dirt->SetInternalFieldCount(DirHandle::kDirHandleFieldCount); + dirt->SetInternalFieldCount(DirHandle::kInternalFieldCount); Local handleString = FIXED_ONE_BYTE_STRING(isolate, "DirHandle"); dir->SetClassName(handleString); diff --git a/src/node_dir.h b/src/node_dir.h index b55245d5b89a2e..5fcc36326b7ba2 100644 --- a/src/node_dir.h +++ b/src/node_dir.h @@ -12,8 +12,6 @@ namespace fs_dir { // Needed to propagate `uv_dir_t`. class DirHandle : public AsyncWrap { public: - static constexpr int kDirHandleFieldCount = 1; - static DirHandle* New(Environment* env, uv_dir_t* dir); ~DirHandle() override; diff --git a/src/node_file.cc b/src/node_file.cc index 4d4960fc583653..121fd35f573434 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -2290,7 +2290,8 @@ void Initialize(Local target, // Create FunctionTemplate for FSReqCallback Local fst = env->NewFunctionTemplate(NewFSReqCallback); - fst->InstanceTemplate()->SetInternalFieldCount(1); + fst->InstanceTemplate()->SetInternalFieldCount( + FSReqBase::kInternalFieldCount); fst->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local wrapString = FIXED_ONE_BYTE_STRING(isolate, "FSReqCallback"); @@ -2303,7 +2304,8 @@ void Initialize(Local target, // Create FunctionTemplate for FileHandleReadWrap. There’s no need // to do anything in the constructor, so we only store the instance template. Local fh_rw = FunctionTemplate::New(isolate); - fh_rw->InstanceTemplate()->SetInternalFieldCount(1); + fh_rw->InstanceTemplate()->SetInternalFieldCount( + FSReqBase::kInternalFieldCount); fh_rw->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local fhWrapString = FIXED_ONE_BYTE_STRING(isolate, "FileHandleReqWrap"); @@ -2318,7 +2320,7 @@ void Initialize(Local target, FIXED_ONE_BYTE_STRING(isolate, "FSReqPromise"); fpt->SetClassName(promiseString); Local fpo = fpt->InstanceTemplate(); - fpo->SetInternalFieldCount(1); + fpo->SetInternalFieldCount(FSReqBase::kInternalFieldCount); env->set_fsreqpromise_constructor_template(fpo); // Create FunctionTemplate for FileHandle @@ -2327,7 +2329,7 @@ void Initialize(Local target, env->SetProtoMethod(fd, "close", FileHandle::Close); env->SetProtoMethod(fd, "releaseFD", FileHandle::ReleaseFD); Local fdt = fd->InstanceTemplate(); - fdt->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + fdt->SetInternalFieldCount(StreamBase::kInternalFieldCount); Local handleString = FIXED_ONE_BYTE_STRING(isolate, "FileHandle"); fd->SetClassName(handleString); @@ -2344,7 +2346,7 @@ void Initialize(Local target, "FileHandleCloseReq")); fdclose->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local fdcloset = fdclose->InstanceTemplate(); - fdcloset->SetInternalFieldCount(1); + fdcloset->SetInternalFieldCount(FSReqBase::kInternalFieldCount); env->set_fdclose_constructor_template(fdcloset); Local use_promises_symbol = diff --git a/src/node_http2.cc b/src/node_http2.cc index c21adcfeb56e66..075d1b505e5328 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -3025,14 +3025,14 @@ void Initialize(Local target, ping->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Ping")); ping->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local pingt = ping->InstanceTemplate(); - pingt->SetInternalFieldCount(1); + pingt->SetInternalFieldCount(Http2Session::Http2Ping::kInternalFieldCount); env->set_http2ping_constructor_template(pingt); Local setting = FunctionTemplate::New(env->isolate()); setting->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Setting")); setting->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local settingt = setting->InstanceTemplate(); - settingt->SetInternalFieldCount(1); + settingt->SetInternalFieldCount(AsyncWrap::kInternalFieldCount); env->set_http2settings_constructor_template(settingt); Local stream = FunctionTemplate::New(env->isolate()); @@ -3049,7 +3049,7 @@ void Initialize(Local target, stream->Inherit(AsyncWrap::GetConstructorTemplate(env)); StreamBase::AddMethods(env, stream); Local streamt = stream->InstanceTemplate(); - streamt->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + streamt->SetInternalFieldCount(StreamBase::kInternalFieldCount); env->set_http2stream_constructor_template(streamt); target->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Stream"), @@ -3058,7 +3058,8 @@ void Initialize(Local target, Local session = env->NewFunctionTemplate(Http2Session::New); session->SetClassName(http2SessionClassName); - session->InstanceTemplate()->SetInternalFieldCount(1); + session->InstanceTemplate()->SetInternalFieldCount( + Http2Session::kInternalFieldCount); session->Inherit(AsyncWrap::GetConstructorTemplate(env)); env->SetProtoMethod(session, "origin", Http2Session::Origin); env->SetProtoMethod(session, "altsvc", Http2Session::AltSvc); diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 40ece82b625746..75d7e89a91c34f 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -873,7 +873,7 @@ void InitializeHttpParser(Local target, void* priv) { Environment* env = Environment::GetCurrent(context); Local t = env->NewFunctionTemplate(Parser::New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount(Parser::kInternalFieldCount); t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HTTPParser")); t->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "REQUEST"), diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 46c6ef39f861ec..a32ddf2066be5f 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -172,7 +172,7 @@ class ConverterObject : public BaseObject, Converter { HandleScope scope(env->isolate()); Local t = ObjectTemplate::New(env->isolate()); - t->SetInternalFieldCount(1); + t->SetInternalFieldCount(ConverterObject::kInternalFieldCount); Local obj; if (!t->NewInstance(env->context()).ToLocal(&obj)) return; diff --git a/src/node_messaging.cc b/src/node_messaging.cc index 248e0f041deb1d..c52a069874450a 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -935,7 +935,8 @@ Local GetMessagePortConstructorTemplate(Environment* env) { { Local m = env->NewFunctionTemplate(MessagePort::New); m->SetClassName(env->message_port_constructor_string()); - m->InstanceTemplate()->SetInternalFieldCount(1); + m->InstanceTemplate()->SetInternalFieldCount( + MessagePort::kInternalFieldCount); m->Inherit(HandleWrap::GetConstructorTemplate(env)); env->SetProtoMethod(m, "postMessage", MessagePort::PostMessage); diff --git a/src/node_perf.cc b/src/node_perf.cc index 68b015f33eda49..21766d3b89aa3b 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -640,7 +640,8 @@ void Initialize(Local target, Local eldh = env->NewFunctionTemplate(ELDHistogramNew); eldh->SetClassName(eldh_classname); - eldh->InstanceTemplate()->SetInternalFieldCount(1); + eldh->InstanceTemplate()->SetInternalFieldCount( + ELDHistogram::kInternalFieldCount); env->SetProtoMethod(eldh, "exceeds", ELDHistogramExceeds); env->SetProtoMethod(eldh, "min", ELDHistogramMin); env->SetProtoMethod(eldh, "max", ELDHistogramMax); diff --git a/src/node_serdes.cc b/src/node_serdes.cc index a2d185c4167a75..bcdcd19b261e88 100644 --- a/src/node_serdes.cc +++ b/src/node_serdes.cc @@ -451,7 +451,8 @@ void Initialize(Local target, Local ser = env->NewFunctionTemplate(SerializerContext::New); - ser->InstanceTemplate()->SetInternalFieldCount(1); + ser->InstanceTemplate()->SetInternalFieldCount( + SerializerContext::kInternalFieldCount); env->SetProtoMethod(ser, "writeHeader", SerializerContext::WriteHeader); env->SetProtoMethod(ser, "writeValue", SerializerContext::WriteValue); @@ -477,7 +478,8 @@ void Initialize(Local target, Local des = env->NewFunctionTemplate(DeserializerContext::New); - des->InstanceTemplate()->SetInternalFieldCount(1); + des->InstanceTemplate()->SetInternalFieldCount( + DeserializerContext::kInternalFieldCount); env->SetProtoMethod(des, "readHeader", DeserializerContext::ReadHeader); env->SetProtoMethod(des, "readValue", DeserializerContext::ReadValue); diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc index 0d67eceed54931..05c540bbff17cc 100644 --- a/src/node_stat_watcher.cc +++ b/src/node_stat_watcher.cc @@ -47,7 +47,8 @@ void StatWatcher::Initialize(Environment* env, Local target) { HandleScope scope(env->isolate()); Local t = env->NewFunctionTemplate(StatWatcher::New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount( + StatWatcher::kInternalFieldCount); Local statWatcherString = FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher"); t->SetClassName(statWatcherString); diff --git a/src/node_trace_events.cc b/src/node_trace_events.cc index f5852076b4ec68..9adee9e458ccc0 100644 --- a/src/node_trace_events.cc +++ b/src/node_trace_events.cc @@ -129,7 +129,8 @@ void NodeCategorySet::Initialize(Local target, Local category_set = env->NewFunctionTemplate(NodeCategorySet::New); - category_set->InstanceTemplate()->SetInternalFieldCount(1); + category_set->InstanceTemplate()->SetInternalFieldCount( + NodeCategorySet::kInternalFieldCount); env->SetProtoMethod(category_set, "enable", NodeCategorySet::Enable); env->SetProtoMethod(category_set, "disable", NodeCategorySet::Disable); diff --git a/src/node_util.cc b/src/node_util.cc index e0ef7d421ff24a..db9b8ec8d65f51 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -323,7 +323,8 @@ void Initialize(Local target, FIXED_ONE_BYTE_STRING(env->isolate(), "WeakReference"); Local weak_ref = env->NewFunctionTemplate(WeakReference::New); - weak_ref->InstanceTemplate()->SetInternalFieldCount(1); + weak_ref->InstanceTemplate()->SetInternalFieldCount( + WeakReference::kInternalFieldCount); weak_ref->SetClassName(weak_ref_string); env->SetProtoMethod(weak_ref, "get", WeakReference::Get); env->SetProtoMethod(weak_ref, "incRef", WeakReference::IncRef); diff --git a/src/node_wasi.cc b/src/node_wasi.cc index 20872c58d60fb7..ed8f6c4fa4cb67 100644 --- a/src/node_wasi.cc +++ b/src/node_wasi.cc @@ -1810,7 +1810,7 @@ static void Initialize(Local target, Local tmpl = env->NewFunctionTemplate(WASI::New); auto wasi_wrap_string = FIXED_ONE_BYTE_STRING(env->isolate(), "WASI"); - tmpl->InstanceTemplate()->SetInternalFieldCount(1); + tmpl->InstanceTemplate()->SetInternalFieldCount(WASI::kInternalFieldCount); tmpl->SetClassName(wasi_wrap_string); env->SetProtoMethod(tmpl, "args_get", WASI::ArgsGet); diff --git a/src/node_watchdog.cc b/src/node_watchdog.cc index 4cc75c3160473a..29f0bc18c0d7b0 100644 --- a/src/node_watchdog.cc +++ b/src/node_watchdog.cc @@ -121,7 +121,8 @@ SignalPropagation SigintWatchdog::HandleSigint() { void TraceSigintWatchdog::Init(Environment* env, Local target) { Local constructor = env->NewFunctionTemplate(New); - constructor->InstanceTemplate()->SetInternalFieldCount(1); + constructor->InstanceTemplate()->SetInternalFieldCount( + TraceSigintWatchdog::kInternalFieldCount); Local js_sigint_watch_dog = FIXED_ONE_BYTE_STRING(env->isolate(), "TraceSigintWatchdog"); constructor->SetClassName(js_sigint_watch_dog); diff --git a/src/node_worker.cc b/src/node_worker.cc index d6e0ebb36f4a65..1496b937d0c698 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -776,7 +776,8 @@ void InitWorker(Local target, { Local w = env->NewFunctionTemplate(Worker::New); - w->InstanceTemplate()->SetInternalFieldCount(1); + w->InstanceTemplate()->SetInternalFieldCount( + Worker::kInternalFieldCount); w->Inherit(AsyncWrap::GetConstructorTemplate(env)); env->SetProtoMethod(w, "startThread", Worker::StartThread); @@ -797,7 +798,8 @@ void InitWorker(Local target, { Local wst = FunctionTemplate::New(env->isolate()); - wst->InstanceTemplate()->SetInternalFieldCount(1); + wst->InstanceTemplate()->SetInternalFieldCount( + WorkerHeapSnapshotTaker::kInternalFieldCount); wst->Inherit(AsyncWrap::GetConstructorTemplate(env)); Local wst_string = diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 1b7fd788b959f9..eacd710143a1b2 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -1216,7 +1216,8 @@ struct MakeClass { static void Make(Environment* env, Local target, const char* name) { Local z = env->NewFunctionTemplate(Stream::New); - z->InstanceTemplate()->SetInternalFieldCount(1); + z->InstanceTemplate()->SetInternalFieldCount( + Stream::kInternalFieldCount); z->Inherit(AsyncWrap::GetConstructorTemplate(env)); env->SetProtoMethod(z, "write", Stream::template Write); diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index c2be4320387549..c4a5b7cd62e1b4 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -74,7 +74,7 @@ void PipeWrap::Initialize(Local target, Local pipeString = FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe"); t->SetClassName(pipeString); t->InstanceTemplate() - ->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + ->SetInternalFieldCount(StreamBase::kInternalFieldCount); t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env)); diff --git a/src/process_wrap.cc b/src/process_wrap.cc index a75f271d1c77b8..1e7de56c6d1581 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -52,7 +52,8 @@ class ProcessWrap : public HandleWrap { void* priv) { Environment* env = Environment::GetCurrent(context); Local constructor = env->NewFunctionTemplate(New); - constructor->InstanceTemplate()->SetInternalFieldCount(1); + constructor->InstanceTemplate()->SetInternalFieldCount( + ProcessWrap::kInternalFieldCount); Local processString = FIXED_ONE_BYTE_STRING(env->isolate(), "Process"); constructor->SetClassName(processString); diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc index bc2d9f1e355efd..2be7ac9834100b 100644 --- a/src/signal_wrap.cc +++ b/src/signal_wrap.cc @@ -53,7 +53,8 @@ class SignalWrap : public HandleWrap { void* priv) { Environment* env = Environment::GetCurrent(context); Local constructor = env->NewFunctionTemplate(New); - constructor->InstanceTemplate()->SetInternalFieldCount(1); + constructor->InstanceTemplate()->SetInternalFieldCount( + SignalWrap::kInternalFieldCount); Local signalString = FIXED_ONE_BYTE_STRING(env->isolate(), "Signal"); constructor->SetClassName(signalString); diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h index f89eb3a5287939..27a9a01c7c2170 100644 --- a/src/stream_base-inl.h +++ b/src/stream_base-inl.h @@ -23,18 +23,22 @@ using v8::String; using v8::Value; inline void StreamReq::AttachToObject(v8::Local req_wrap_obj) { - CHECK_EQ(req_wrap_obj->GetAlignedPointerFromInternalField(kStreamReqField), + CHECK_EQ(req_wrap_obj->GetAlignedPointerFromInternalField( + StreamReq::kStreamReqField), nullptr); - req_wrap_obj->SetAlignedPointerInInternalField(kStreamReqField, this); + req_wrap_obj->SetAlignedPointerInInternalField( + StreamReq::kStreamReqField, this); } inline StreamReq* StreamReq::FromObject(v8::Local req_wrap_obj) { return static_cast( - req_wrap_obj->GetAlignedPointerFromInternalField(kStreamReqField)); + req_wrap_obj->GetAlignedPointerFromInternalField( + StreamReq::kStreamReqField)); } inline void StreamReq::Dispose() { - object()->SetAlignedPointerInInternalField(kStreamReqField, nullptr); + object()->SetAlignedPointerInInternalField( + StreamReq::kStreamReqField, nullptr); delete this; } @@ -261,15 +265,17 @@ inline WriteWrap* StreamBase::CreateWriteWrap( } inline void StreamBase::AttachToObject(v8::Local obj) { - obj->SetAlignedPointerInInternalField(kStreamBaseField, this); + obj->SetAlignedPointerInInternalField( + StreamBase::kStreamBaseField, this); } inline StreamBase* StreamBase::FromObject(v8::Local obj) { - if (obj->GetAlignedPointerFromInternalField(0) == nullptr) + if (obj->GetAlignedPointerFromInternalField(StreamBase::kSlot) == nullptr) return nullptr; return static_cast( - obj->GetAlignedPointerFromInternalField(kStreamBaseField)); + obj->GetAlignedPointerFromInternalField( + StreamBase::kStreamBaseField)); } @@ -304,7 +310,7 @@ inline void StreamReq::Done(int status, const char* error_str) { inline void StreamReq::ResetObject(v8::Local obj) { DCHECK_GT(obj->InternalFieldCount(), StreamReq::kStreamReqField); - obj->SetAlignedPointerInInternalField(0, nullptr); // BaseObject field. + obj->SetAlignedPointerInInternalField(StreamReq::kSlot, nullptr); obj->SetAlignedPointerInInternalField(StreamReq::kStreamReqField, nullptr); } diff --git a/src/stream_base.cc b/src/stream_base.cc index eaccfc995c745f..28a3bf65fc0178 100644 --- a/src/stream_base.cc +++ b/src/stream_base.cc @@ -340,7 +340,8 @@ MaybeLocal StreamBase::CallJSOnreadMethod(ssize_t nread, AsyncWrap* wrap = GetAsyncWrap(); CHECK_NOT_NULL(wrap); - Local onread = wrap->object()->GetInternalField(kOnReadFunctionField); + Local onread = wrap->object()->GetInternalField( + StreamBase::kOnReadFunctionField); CHECK(onread->IsFunction()); return wrap->MakeCallback(onread.As(), arraysize(argv), argv); } @@ -409,8 +410,11 @@ void StreamBase::AddMethods(Environment* env, Local t) { True(env->isolate())); t->PrototypeTemplate()->SetAccessor( FIXED_ONE_BYTE_STRING(env->isolate(), "onread"), - BaseObject::InternalFieldGet, - BaseObject::InternalFieldSet); + BaseObject::InternalFieldGet< + StreamBase::kOnReadFunctionField>, + BaseObject::InternalFieldSet< + StreamBase::kOnReadFunctionField, + &Value::IsFunction>); } void StreamBase::GetFD(const FunctionCallbackInfo& args) { diff --git a/src/stream_base.h b/src/stream_base.h index 3df9e99f6e438e..15b83ec91f6387 100644 --- a/src/stream_base.h +++ b/src/stream_base.h @@ -29,7 +29,14 @@ using JSMethodFunction = void(const v8::FunctionCallbackInfo& args); class StreamReq { public: - static constexpr int kStreamReqField = 1; + // The kSlot internal field here mirrors BaseObject::InternalFields::kSlot + // here because instances derived from StreamReq will also derive from + // BaseObject, and the slots are used for the identical purpose. + enum InternalFields { + kSlot = BaseObject::kSlot, + kStreamReqField = BaseObject::kInternalFieldCount, + kInternalFieldCount + }; explicit StreamReq(StreamBase* stream, v8::Local req_wrap_obj) : stream_(stream) { @@ -275,10 +282,15 @@ class StreamResource { class StreamBase : public StreamResource { public: - // 0 is reserved for the BaseObject pointer. - static constexpr int kStreamBaseField = 1; - static constexpr int kOnReadFunctionField = 2; - static constexpr int kStreamBaseFieldCount = 3; + // The kSlot field here mirrors that of BaseObject::InternalFields::kSlot + // because instances deriving from StreamBase generally also derived from + // BaseObject (it's possible for it not to, however). + enum InternalFields { + kSlot = BaseObject::kSlot, + kStreamBaseField = BaseObject::kInternalFieldCount, + kOnReadFunctionField, + kInternalFieldCount + }; static void AddMethods(Environment* env, v8::Local target); diff --git a/src/stream_pipe.cc b/src/stream_pipe.cc index 5f7514b1b84790..40b094ab5930a5 100644 --- a/src/stream_pipe.cc +++ b/src/stream_pipe.cc @@ -298,7 +298,8 @@ void InitializeStreamPipe(Local target, env->SetProtoMethod(pipe, "pendingWrites", StreamPipe::PendingWrites); pipe->Inherit(AsyncWrap::GetConstructorTemplate(env)); pipe->SetClassName(stream_pipe_string); - pipe->InstanceTemplate()->SetInternalFieldCount(1); + pipe->InstanceTemplate()->SetInternalFieldCount( + StreamPipe::kInternalFieldCount); target ->Set(context, stream_pipe_string, pipe->GetFunction(context).ToLocalChecked()) diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 21b775401e4571..7548516e477a36 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -64,8 +64,7 @@ void LibuvStreamWrap::Initialize(Local target, }; Local sw = FunctionTemplate::New(env->isolate(), is_construct_call_callback); - sw->InstanceTemplate()->SetInternalFieldCount( - StreamReq::kStreamReqField + 1 + 3); + sw->InstanceTemplate()->SetInternalFieldCount(StreamReq::kInternalFieldCount); Local wrapString = FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap"); sw->SetClassName(wrapString); @@ -94,7 +93,8 @@ void LibuvStreamWrap::Initialize(Local target, Local ww = FunctionTemplate::New(env->isolate(), is_construct_call_callback); - ww->InstanceTemplate()->SetInternalFieldCount(StreamReq::kStreamReqField + 1); + ww->InstanceTemplate()->SetInternalFieldCount( + StreamReq::kInternalFieldCount); Local writeWrapString = FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap"); ww->SetClassName(writeWrapString); @@ -136,7 +136,7 @@ Local LibuvStreamWrap::GetConstructorTemplate( FIXED_ONE_BYTE_STRING(env->isolate(), "LibuvStreamWrap")); tmpl->Inherit(HandleWrap::GetConstructorTemplate(env)); tmpl->InstanceTemplate()->SetInternalFieldCount( - StreamBase::kStreamBaseFieldCount); + StreamBase::kInternalFieldCount); Local get_write_queue_size = FunctionTemplate::New(env->isolate(), GetWriteQueueSize, diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 89c4e215bbe6ae..1aca3a5e6aeeee 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -77,8 +77,7 @@ void TCPWrap::Initialize(Local target, Local t = env->NewFunctionTemplate(New); Local tcpString = FIXED_ONE_BYTE_STRING(env->isolate(), "TCP"); t->SetClassName(tcpString); - t->InstanceTemplate() - ->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + t->InstanceTemplate()->SetInternalFieldCount(StreamBase::kInternalFieldCount); // Init properties t->InstanceTemplate()->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "reading"), diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 2f8da61f647f44..39dcf532a9fb7a 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -1269,8 +1269,7 @@ void TLSWrap::Initialize(Local target, Local tlsWrapString = FIXED_ONE_BYTE_STRING(env->isolate(), "TLSWrap"); t->SetClassName(tlsWrapString); - t->InstanceTemplate() - ->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + t->InstanceTemplate()->SetInternalFieldCount(StreamBase::kInternalFieldCount); Local get_write_queue_size = FunctionTemplate::New(env->isolate(), diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc index 7dface926e4349..8536fae3ed7383 100644 --- a/src/tty_wrap.cc +++ b/src/tty_wrap.cc @@ -51,8 +51,7 @@ void TTYWrap::Initialize(Local target, Local t = env->NewFunctionTemplate(New); t->SetClassName(ttyString); - t->InstanceTemplate() - ->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount); + t->InstanceTemplate()->SetInternalFieldCount(StreamBase::kInternalFieldCount); t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env)); env->SetProtoMethodNoSideEffect(t, "getWindowSize", TTYWrap::GetWindowSize); diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 4a66ce0a1f1018..fa5cf8da479644 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -91,7 +91,7 @@ void UDPWrap::Initialize(Local target, Environment* env = Environment::GetCurrent(context); Local t = env->NewFunctionTemplate(New); - t->InstanceTemplate()->SetInternalFieldCount(1); + t->InstanceTemplate()->SetInternalFieldCount(UDPWrap::kInternalFieldCount); Local udpString = FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"); t->SetClassName(udpString);