Skip to content

Commit

Permalink
src: refactor BaseObject methods
Browse files Browse the repository at this point in the history
- Wrap the initialization of the kSlot and kEmbedderType fields
  into a BaseObject::SetInternalFields() method.
- Move the tagging of kEmbedderType field into
  BaseObject::TagNodeObject()
- Add a variant of BaseObject::MakeLazilyInitializedJSTemplate()
  that only needs IsolateData.
This makes it easier to create BaseObject subclasses.
  • Loading branch information
joyeecheung committed Sep 26, 2022
1 parent 33f80a8 commit 4f56137
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
14 changes: 12 additions & 2 deletions src/base_object-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,24 @@ Environment* BaseObject::env() const {
return env_;
}

void BaseObject::TagNodeObject(v8::Local<v8::Object> object) {
DCHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount);
object->SetAlignedPointerInInternalField(BaseObject::kEmbedderType,
&kNodeEmbedderId);
}

void BaseObject::SetInternalFields(v8::Local<v8::Object> object, void* slot) {
TagNodeObject(object);
object->SetAlignedPointerInInternalField(BaseObject::kSlot, slot);
}

BaseObject* BaseObject::FromJSObject(v8::Local<v8::Value> value) {
v8::Local<v8::Object> obj = value.As<v8::Object>();
DCHECK_GE(obj->InternalFieldCount(), BaseObject::kSlot);
DCHECK_GE(obj->InternalFieldCount(), BaseObject::kInternalFieldCount);
return static_cast<BaseObject*>(
obj->GetAlignedPointerFromInternalField(BaseObject::kSlot));
}


template <typename T>
T* BaseObject::FromJSObject(v8::Local<v8::Value> object) {
return static_cast<T*>(FromJSObject(object));
Expand Down
5 changes: 5 additions & 0 deletions src/base_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ class BaseObject : public MemoryRetainer {
// was also passed to the `BaseObject()` constructor initially.
// This may return `nullptr` if the C++ object has not been constructed yet,
// e.g. when the JS object used `MakeLazilyInitializedJSTemplate`.
static inline void SetInternalFields(v8::Local<v8::Object> object,
void* slot);
static inline void TagNodeObject(v8::Local<v8::Object> object);
static void LazilyInitializedJSTemplateConstructor(
const v8::FunctionCallbackInfo<v8::Value>& args);
static inline BaseObject* FromJSObject(v8::Local<v8::Value> object);
Expand All @@ -91,6 +94,8 @@ class BaseObject : public MemoryRetainer {
// Utility to create a FunctionTemplate with one internal field (used for
// the `BaseObject*` pointer) and a constructor that initializes that field
// to `nullptr`.
static v8::Local<v8::FunctionTemplate> MakeLazilyInitializedJSTemplate(
IsolateData* isolate);
static v8::Local<v8::FunctionTemplate> MakeLazilyInitializedJSTemplate(
Environment* env);

Expand Down
21 changes: 10 additions & 11 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1897,10 +1897,7 @@ BaseObject::BaseObject(Environment* env, Local<Object> object)
: persistent_handle_(env->isolate(), object), env_(env) {
CHECK_EQ(false, object.IsEmpty());
CHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount);
object->SetAlignedPointerInInternalField(BaseObject::kEmbedderType,
&kNodeEmbedderId);
object->SetAlignedPointerInInternalField(BaseObject::kSlot,
static_cast<void*>(this));
SetInternalFields(object, static_cast<void*>(this));
env->AddCleanupHook(DeleteMe, static_cast<void*>(this));
env->modify_base_object_count(1);
}
Expand Down Expand Up @@ -1959,21 +1956,23 @@ uint16_t kNodeEmbedderId = 0x90de;
void BaseObject::LazilyInitializedJSTemplateConstructor(
const FunctionCallbackInfo<Value>& args) {
DCHECK(args.IsConstructCall());
CHECK_GE(args.This()->InternalFieldCount(), BaseObject::kInternalFieldCount);
args.This()->SetAlignedPointerInInternalField(BaseObject::kEmbedderType,
&kNodeEmbedderId);
args.This()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr);
SetInternalFields(args.This(), nullptr);
}

Local<FunctionTemplate> BaseObject::MakeLazilyInitializedJSTemplate(
Environment* env) {
IsolateData* isolate_data) {
Local<FunctionTemplate> t = NewFunctionTemplate(
env->isolate(), LazilyInitializedJSTemplateConstructor);
t->Inherit(BaseObject::GetConstructorTemplate(env));
isolate_data->isolate(), LazilyInitializedJSTemplateConstructor);
t->Inherit(BaseObject::GetConstructorTemplate(isolate_data));
t->InstanceTemplate()->SetInternalFieldCount(BaseObject::kInternalFieldCount);
return t;
}

Local<FunctionTemplate> BaseObject::MakeLazilyInitializedJSTemplate(
Environment* env) {
return MakeLazilyInitializedJSTemplate(env->isolate_data());
}

BaseObject::PointerData* BaseObject::pointer_data() {
if (!has_pointer_data()) {
PointerData* metadata = new PointerData();
Expand Down

0 comments on commit 4f56137

Please sign in to comment.