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 <jasnell@gmail.com>

PR-URL: https://github.com/nodejs/node/pull/31960
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
James M Snell
2020-02-25 14:37:33 -08:00
parent 68e36ade3d
commit 0fac393d26
40 changed files with 151 additions and 92 deletions

View File

@@ -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> 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> promise,
PromiseWrap* parent_wrap,
@@ -214,15 +215,16 @@ PromiseWrap* PromiseWrap::New(Environment* env,
void PromiseWrap::getIsChainedPromise(Local<String> property,
const PropertyCallbackInfo<Value>& info) {
info.GetReturnValue().Set(
info.Holder()->GetInternalField(kIsChainedPromiseField));
info.Holder()->GetInternalField(PromiseWrap::kIsChainedPromiseField));
}
static PromiseWrap* extractPromiseWrap(Local<Promise> promise) {
Local<Value> resource_object_value = promise->GetInternalField(0);
if (resource_object_value->IsObject()) {
return Unwrap<PromiseWrap>(resource_object_value.As<Object>());
}
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<Value> obj = promise->GetInternalField(0);
return obj->IsObject() ? Unwrap<PromiseWrap>(obj.As<Object>()) : nullptr;
}
static void PromiseHook(PromiseHookType type, Local<Promise> promise,
@@ -560,7 +562,7 @@ void AsyncWrap::Initialize(Local<Object> 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();

View File

@@ -43,7 +43,9 @@ BaseObject::BaseObject(Environment* env, v8::Local<v8::Object> object)
: persistent_handle_(env->isolate(), object), env_(env) {
CHECK_EQ(false, object.IsEmpty());
CHECK_GT(object->InternalFieldCount(), 0);
object->SetAlignedPointerInInternalField(0, static_cast<void*>(this));
object->SetAlignedPointerInInternalField(
BaseObject::kSlot,
static_cast<void*>(this));
env->AddCleanupHook(DeleteMe, static_cast<void*>(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<v8::Object> obj) {
CHECK_GT(obj->InternalFieldCount(), 0);
return static_cast<BaseObject*>(obj->GetAlignedPointerFromInternalField(0));
return static_cast<BaseObject*>(
obj->GetAlignedPointerFromInternalField(BaseObject::kSlot));
}
@@ -148,11 +151,12 @@ BaseObject::MakeLazilyInitializedJSTemplate(Environment* env) {
auto constructor = [](const v8::FunctionCallbackInfo<v8::Value>& args) {
DCHECK(args.IsConstructCall());
DCHECK_GT(args.This()->InternalFieldCount(), 0);
args.This()->SetAlignedPointerInInternalField(0, nullptr);
args.This()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr);
};
v8::Local<v8::FunctionTemplate> t = env->NewFunctionTemplate(constructor);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->InstanceTemplate()->SetInternalFieldCount(
BaseObject::kInternalFieldCount);
return t;
}

View File

@@ -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<v8::Object> object);

View File

@@ -2223,7 +2223,8 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> 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<QueryAnyWrap>);

View File

@@ -97,7 +97,8 @@ void FSEventWrap::Initialize(Local<Object> target,
auto fsevent_string = FIXED_ONE_BYTE_STRING(env->isolate(), "FSEvent");
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->InstanceTemplate()->SetInternalFieldCount(
FSEventWrap::kInternalFieldCount);
t->SetClassName(fsevent_string);
t->Inherit(AsyncWrap::GetConstructorTemplate(env));

View File

@@ -341,7 +341,7 @@ BaseObjectPtr<AsyncWrap> CreateHeapSnapshotStream(
Local<FunctionTemplate> os = FunctionTemplate::New(env->isolate());
os->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> ost = os->InstanceTemplate();
ost->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount);
ost->SetInternalFieldCount(StreamBase::kInternalFieldCount);
os->SetClassName(
FIXED_ONE_BYTE_STRING(env->isolate(), "HeapSnapshotStream"));
StreamBase::AddMethods(env, os);

View File

@@ -105,7 +105,8 @@ class JSBindingsConnection : public AsyncWrap {
Local<String> class_name = ConnectionType::GetClassName(env);
Local<FunctionTemplate> 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);

View File

@@ -204,7 +204,7 @@ void JSStream::Initialize(Local<Object> 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<WriteWrap>);

View File

@@ -1636,7 +1636,8 @@ void ModuleWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> 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);

View File

@@ -145,7 +145,7 @@ MaybeLocal<Object> ContextifyContext::CreateDataWrapper(Environment* env) {
return MaybeLocal<Object>();
}
wrapper->SetAlignedPointerInInternalField(0, this);
wrapper->SetAlignedPointerInInternalField(ContextifyContext::kSlot, this);
return wrapper;
}
@@ -232,7 +232,8 @@ MaybeLocal<Context> ContextifyContext::CreateV8Context(
void ContextifyContext::Init(Environment* env, Local<Object> target) {
Local<FunctionTemplate> 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 <typename T>
ContextifyContext* ContextifyContext::Get(const PropertyCallbackInfo<T>& args) {
Local<Value> data = args.Data();
return static_cast<ContextifyContext*>(
data.As<Object>()->GetAlignedPointerFromInternalField(0));
data.As<Object>()->GetAlignedPointerFromInternalField(
ContextifyContext::kSlot));
}
// static
@@ -628,7 +630,8 @@ void ContextifyScript::Init(Environment* env, Local<Object> target) {
FIXED_ONE_BYTE_STRING(env->isolate(), "ContextifyScript");
Local<FunctionTemplate> 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<Object> target,
{
Local<FunctionTemplate> 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());
}

View File

@@ -19,6 +19,7 @@ struct ContextOptions {
class ContextifyContext {
public:
enum InternalFields { kSlot, kInternalFieldCount };
ContextifyContext(Environment* env,
v8::Local<v8::Object> sandbox_obj,
const ContextOptions& options);

View File

@@ -464,7 +464,8 @@ static T* MallocOpenSSL(size_t count) {
void SecureContext::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->InstanceTemplate()->SetInternalFieldCount(
SecureContext::kInternalFieldCount);
Local<String> secureContextString =
FIXED_ONE_BYTE_STRING(env->isolate(), "SecureContext");
t->SetClassName(secureContextString);
@@ -3803,7 +3804,8 @@ EVP_PKEY* ManagedEVPPKey::get() const {
Local<Function> KeyObject::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> 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<Object> target) {
Local<FunctionTemplate> 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<v8::Object> wrap)
void Hmac::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> 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<v8::Object> wrap)
void Hash::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> 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<v8::Object> wrap) : SignBase(env, wrap) {
void Sign::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> 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<v8::Object> wrap) :
void Verify::Initialize(Environment* env, Local<Object> target) {
Local<FunctionTemplate> 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<Object> target) {
const PropertyAttribute attributes =
static_cast<PropertyAttribute>(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<Object> target) {
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->InstanceTemplate()->SetInternalFieldCount(ECDH::kInternalFieldCount);
env->SetProtoMethod(t, "generateKeys", GenerateKeys);
env->SetProtoMethod(t, "computeSecret", ComputeSecret);

View File

@@ -358,7 +358,7 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(dir, "read", DirHandle::Read);
env->SetProtoMethod(dir, "close", DirHandle::Close);
Local<ObjectTemplate> dirt = dir->InstanceTemplate();
dirt->SetInternalFieldCount(DirHandle::kDirHandleFieldCount);
dirt->SetInternalFieldCount(DirHandle::kInternalFieldCount);
Local<String> handleString =
FIXED_ONE_BYTE_STRING(isolate, "DirHandle");
dir->SetClassName(handleString);

View File

@@ -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;

View File

@@ -2290,7 +2290,8 @@ void Initialize(Local<Object> target,
// Create FunctionTemplate for FSReqCallback
Local<FunctionTemplate> fst = env->NewFunctionTemplate(NewFSReqCallback);
fst->InstanceTemplate()->SetInternalFieldCount(1);
fst->InstanceTemplate()->SetInternalFieldCount(
FSReqBase::kInternalFieldCount);
fst->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wrapString =
FIXED_ONE_BYTE_STRING(isolate, "FSReqCallback");
@@ -2303,7 +2304,8 @@ void Initialize(Local<Object> target,
// 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(1);
fh_rw->InstanceTemplate()->SetInternalFieldCount(
FSReqBase::kInternalFieldCount);
fh_rw->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> fhWrapString =
FIXED_ONE_BYTE_STRING(isolate, "FileHandleReqWrap");
@@ -2318,7 +2320,7 @@ void Initialize(Local<Object> target,
FIXED_ONE_BYTE_STRING(isolate, "FSReqPromise");
fpt->SetClassName(promiseString);
Local<ObjectTemplate> 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<Object> target,
env->SetProtoMethod(fd, "close", FileHandle::Close);
env->SetProtoMethod(fd, "releaseFD", FileHandle::ReleaseFD);
Local<ObjectTemplate> fdt = fd->InstanceTemplate();
fdt->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount);
fdt->SetInternalFieldCount(StreamBase::kInternalFieldCount);
Local<String> handleString =
FIXED_ONE_BYTE_STRING(isolate, "FileHandle");
fd->SetClassName(handleString);
@@ -2344,7 +2346,7 @@ void Initialize(Local<Object> target,
"FileHandleCloseReq"));
fdclose->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> fdcloset = fdclose->InstanceTemplate();
fdcloset->SetInternalFieldCount(1);
fdcloset->SetInternalFieldCount(FSReqBase::kInternalFieldCount);
env->set_fdclose_constructor_template(fdcloset);
Local<Symbol> use_promises_symbol =

View File

@@ -3025,14 +3025,14 @@ void Initialize(Local<Object> target,
ping->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Ping"));
ping->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> pingt = ping->InstanceTemplate();
pingt->SetInternalFieldCount(1);
pingt->SetInternalFieldCount(Http2Session::Http2Ping::kInternalFieldCount);
env->set_http2ping_constructor_template(pingt);
Local<FunctionTemplate> setting = FunctionTemplate::New(env->isolate());
setting->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Http2Setting"));
setting->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<ObjectTemplate> settingt = setting->InstanceTemplate();
settingt->SetInternalFieldCount(1);
settingt->SetInternalFieldCount(AsyncWrap::kInternalFieldCount);
env->set_http2settings_constructor_template(settingt);
Local<FunctionTemplate> stream = FunctionTemplate::New(env->isolate());
@@ -3049,7 +3049,7 @@ void Initialize(Local<Object> target,
stream->Inherit(AsyncWrap::GetConstructorTemplate(env));
StreamBase::AddMethods(env, stream);
Local<ObjectTemplate> 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<Object> target,
Local<FunctionTemplate> 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);

View File

@@ -873,7 +873,7 @@ void InitializeHttpParser(Local<Object> target,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> 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"),

View File

@@ -172,7 +172,7 @@ class ConverterObject : public BaseObject, Converter {
HandleScope scope(env->isolate());
Local<ObjectTemplate> t = ObjectTemplate::New(env->isolate());
t->SetInternalFieldCount(1);
t->SetInternalFieldCount(ConverterObject::kInternalFieldCount);
Local<Object> obj;
if (!t->NewInstance(env->context()).ToLocal(&obj)) return;

View File

@@ -935,7 +935,8 @@ Local<FunctionTemplate> GetMessagePortConstructorTemplate(Environment* env) {
{
Local<FunctionTemplate> 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);

View File

@@ -640,7 +640,8 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> 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);

View File

@@ -451,7 +451,8 @@ void Initialize(Local<Object> target,
Local<FunctionTemplate> 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<Object> target,
Local<FunctionTemplate> 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);

View File

@@ -47,7 +47,8 @@ void StatWatcher::Initialize(Environment* env, Local<Object> target) {
HandleScope scope(env->isolate());
Local<FunctionTemplate> t = env->NewFunctionTemplate(StatWatcher::New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->InstanceTemplate()->SetInternalFieldCount(
StatWatcher::kInternalFieldCount);
Local<String> statWatcherString =
FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher");
t->SetClassName(statWatcherString);

View File

@@ -129,7 +129,8 @@ void NodeCategorySet::Initialize(Local<Object> target,
Local<FunctionTemplate> 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);

View File

@@ -323,7 +323,8 @@ void Initialize(Local<Object> target,
FIXED_ONE_BYTE_STRING(env->isolate(), "WeakReference");
Local<FunctionTemplate> 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);

View File

@@ -1810,7 +1810,7 @@ static void Initialize(Local<Object> target,
Local<FunctionTemplate> 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);

View File

@@ -121,7 +121,8 @@ SignalPropagation SigintWatchdog::HandleSigint() {
void TraceSigintWatchdog::Init(Environment* env, Local<Object> target) {
Local<FunctionTemplate> constructor = env->NewFunctionTemplate(New);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->InstanceTemplate()->SetInternalFieldCount(
TraceSigintWatchdog::kInternalFieldCount);
Local<v8::String> js_sigint_watch_dog =
FIXED_ONE_BYTE_STRING(env->isolate(), "TraceSigintWatchdog");
constructor->SetClassName(js_sigint_watch_dog);

View File

@@ -776,7 +776,8 @@ void InitWorker(Local<Object> target,
{
Local<FunctionTemplate> 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<Object> target,
{
Local<FunctionTemplate> wst = FunctionTemplate::New(env->isolate());
wst->InstanceTemplate()->SetInternalFieldCount(1);
wst->InstanceTemplate()->SetInternalFieldCount(
WorkerHeapSnapshotTaker::kInternalFieldCount);
wst->Inherit(AsyncWrap::GetConstructorTemplate(env));
Local<String> wst_string =

View File

@@ -1216,7 +1216,8 @@ struct MakeClass {
static void Make(Environment* env, Local<Object> target, const char* name) {
Local<FunctionTemplate> 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<true>);

View File

@@ -74,7 +74,7 @@ void PipeWrap::Initialize(Local<Object> target,
Local<String> pipeString = FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe");
t->SetClassName(pipeString);
t->InstanceTemplate()
->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount);
->SetInternalFieldCount(StreamBase::kInternalFieldCount);
t->Inherit(LibuvStreamWrap::GetConstructorTemplate(env));

View File

@@ -52,7 +52,8 @@ class ProcessWrap : public HandleWrap {
void* priv) {
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> constructor = env->NewFunctionTemplate(New);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->InstanceTemplate()->SetInternalFieldCount(
ProcessWrap::kInternalFieldCount);
Local<String> processString =
FIXED_ONE_BYTE_STRING(env->isolate(), "Process");
constructor->SetClassName(processString);

View File

@@ -53,7 +53,8 @@ class SignalWrap : public HandleWrap {
void* priv) {
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> constructor = env->NewFunctionTemplate(New);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->InstanceTemplate()->SetInternalFieldCount(
SignalWrap::kInternalFieldCount);
Local<String> signalString =
FIXED_ONE_BYTE_STRING(env->isolate(), "Signal");
constructor->SetClassName(signalString);

View File

@@ -23,18 +23,22 @@ using v8::String;
using v8::Value;
inline void StreamReq::AttachToObject(v8::Local<v8::Object> 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<v8::Object> req_wrap_obj) {
return static_cast<StreamReq*>(
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<v8::Object> obj) {
obj->SetAlignedPointerInInternalField(kStreamBaseField, this);
obj->SetAlignedPointerInInternalField(
StreamBase::kStreamBaseField, this);
}
inline StreamBase* StreamBase::FromObject(v8::Local<v8::Object> obj) {
if (obj->GetAlignedPointerFromInternalField(0) == nullptr)
if (obj->GetAlignedPointerFromInternalField(StreamBase::kSlot) == nullptr)
return nullptr;
return static_cast<StreamBase*>(
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<v8::Object> obj) {
DCHECK_GT(obj->InternalFieldCount(), StreamReq::kStreamReqField);
obj->SetAlignedPointerInInternalField(0, nullptr); // BaseObject field.
obj->SetAlignedPointerInInternalField(StreamReq::kSlot, nullptr);
obj->SetAlignedPointerInInternalField(StreamReq::kStreamReqField, nullptr);
}

View File

@@ -340,7 +340,8 @@ MaybeLocal<Value> StreamBase::CallJSOnreadMethod(ssize_t nread,
AsyncWrap* wrap = GetAsyncWrap();
CHECK_NOT_NULL(wrap);
Local<Value> onread = wrap->object()->GetInternalField(kOnReadFunctionField);
Local<Value> onread = wrap->object()->GetInternalField(
StreamBase::kOnReadFunctionField);
CHECK(onread->IsFunction());
return wrap->MakeCallback(onread.As<Function>(), arraysize(argv), argv);
}
@@ -409,8 +410,11 @@ void StreamBase::AddMethods(Environment* env, Local<FunctionTemplate> t) {
True(env->isolate()));
t->PrototypeTemplate()->SetAccessor(
FIXED_ONE_BYTE_STRING(env->isolate(), "onread"),
BaseObject::InternalFieldGet<kOnReadFunctionField>,
BaseObject::InternalFieldSet<kOnReadFunctionField, &Value::IsFunction>);
BaseObject::InternalFieldGet<
StreamBase::kOnReadFunctionField>,
BaseObject::InternalFieldSet<
StreamBase::kOnReadFunctionField,
&Value::IsFunction>);
}
void StreamBase::GetFD(const FunctionCallbackInfo<Value>& args) {

View File

@@ -29,7 +29,14 @@ using JSMethodFunction = void(const v8::FunctionCallbackInfo<v8::Value>& 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<v8::Object> 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<v8::FunctionTemplate> target);

View File

@@ -298,7 +298,8 @@ void InitializeStreamPipe(Local<Object> 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())

View File

@@ -64,8 +64,7 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
};
Local<FunctionTemplate> sw =
FunctionTemplate::New(env->isolate(), is_construct_call_callback);
sw->InstanceTemplate()->SetInternalFieldCount(
StreamReq::kStreamReqField + 1 + 3);
sw->InstanceTemplate()->SetInternalFieldCount(StreamReq::kInternalFieldCount);
Local<String> wrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap");
sw->SetClassName(wrapString);
@@ -94,7 +93,8 @@ void LibuvStreamWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> ww =
FunctionTemplate::New(env->isolate(), is_construct_call_callback);
ww->InstanceTemplate()->SetInternalFieldCount(StreamReq::kStreamReqField + 1);
ww->InstanceTemplate()->SetInternalFieldCount(
StreamReq::kInternalFieldCount);
Local<String> writeWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap");
ww->SetClassName(writeWrapString);
@@ -136,7 +136,7 @@ Local<FunctionTemplate> LibuvStreamWrap::GetConstructorTemplate(
FIXED_ONE_BYTE_STRING(env->isolate(), "LibuvStreamWrap"));
tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
tmpl->InstanceTemplate()->SetInternalFieldCount(
StreamBase::kStreamBaseFieldCount);
StreamBase::kInternalFieldCount);
Local<FunctionTemplate> get_write_queue_size =
FunctionTemplate::New(env->isolate(),
GetWriteQueueSize,

View File

@@ -77,8 +77,7 @@ void TCPWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
Local<String> 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"),

View File

@@ -1269,8 +1269,7 @@ void TLSWrap::Initialize(Local<Object> target,
Local<String> tlsWrapString =
FIXED_ONE_BYTE_STRING(env->isolate(), "TLSWrap");
t->SetClassName(tlsWrapString);
t->InstanceTemplate()
->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount);
t->InstanceTemplate()->SetInternalFieldCount(StreamBase::kInternalFieldCount);
Local<FunctionTemplate> get_write_queue_size =
FunctionTemplate::New(env->isolate(),

View File

@@ -51,8 +51,7 @@ void TTYWrap::Initialize(Local<Object> target,
Local<FunctionTemplate> 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);

View File

@@ -91,7 +91,7 @@ void UDPWrap::Initialize(Local<Object> target,
Environment* env = Environment::GetCurrent(context);
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->InstanceTemplate()->SetInternalFieldCount(UDPWrap::kInternalFieldCount);
Local<String> udpString =
FIXED_ONE_BYTE_STRING(env->isolate(), "UDP");
t->SetClassName(udpString);