From c979aeaf26f31954935babd9ed63c3410b15396b 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_impl.h | 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 521626b1d77221..b24c160156c280 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -175,6 +175,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(); @@ -184,9 +188,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, @@ -213,15 +214,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, @@ -566,7 +568,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 efd8f17e9db5bb..fc2611444c1af4 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 082f86ff41d673..71d8f8569ba5f4 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -2224,7 +2224,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 3626b4b2ae5a3b..4a99a2027a35f8 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -1639,7 +1639,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 89cdf664907f9f..c20c9ee1c3f5c9 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -142,7 +142,7 @@ MaybeLocal ContextifyContext::CreateDataWrapper(Environment* env) { return MaybeLocal(); } - wrapper->SetAlignedPointerInInternalField(0, this); + wrapper->SetAlignedPointerInInternalField(ContextifyContext::kSlot, this); return wrapper; } @@ -229,7 +229,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()); @@ -328,7 +329,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 @@ -625,7 +627,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); @@ -1220,7 +1223,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 932a95e4a35727..9e6f76baaf3c1e 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -432,7 +432,8 @@ bool EntropySource(unsigned char* buffer, size_t length) { 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); @@ -3217,7 +3218,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", @@ -3450,7 +3452,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); @@ -4076,7 +4079,8 @@ Hmac::Hmac(Environment* env, 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); @@ -4201,7 +4205,8 @@ Hash::Hash(Environment* env, 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); @@ -4472,7 +4477,8 @@ Sign::Sign(Environment* env, 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); @@ -4796,7 +4802,8 @@ Verify::Verify(Environment* env, 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); @@ -5107,7 +5114,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); @@ -5446,7 +5454,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 a109aea7092148..259df8256f2e08 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -2277,7 +2277,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"); @@ -2290,7 +2291,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"); @@ -2305,7 +2307,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 @@ -2314,7 +2316,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); @@ -2331,7 +2333,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 0eebe2935e248b..655cd97a9532c1 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -3059,14 +3059,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()); @@ -3083,7 +3083,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"), @@ -3092,7 +3092,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_impl.h b/src/node_http_parser_impl.h index 23f2eaf66d1d27..e1a99db316a060 100644 --- a/src/node_http_parser_impl.h +++ b/src/node_http_parser_impl.h @@ -940,7 +940,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 2de1c824d206d2..d2f95ccb850bd8 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -962,7 +962,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 7140d6a14434e2..4b8bf2a8a7c913 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -645,7 +645,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 ab4dd69b823300..08dca0fe596198 100644 --- a/src/node_wasi.cc +++ b/src/node_wasi.cc @@ -1812,7 +1812,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 5cce8ffcb7b3b8..76744a9ef416f7 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 826b4cafe37573..acee02d218cdda 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -771,7 +771,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); @@ -792,7 +793,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 9c734c17d792f7..18f548cc31ad66 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -1215,7 +1215,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 e294c6464f2a11..3d1065c9922183 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 3f313aaeff3a44..516f57e40bfbe0 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 a1f70a58e4bb03..8b6a1cdea1bffd 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);