%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/base_object.cc |
#include "base_object.h" #include "env-inl.h" #include "node_messaging.h" #include "node_realm-inl.h" namespace node { using v8::Context; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::HandleScope; using v8::Just; using v8::Local; using v8::Maybe; using v8::Object; using v8::Value; using v8::ValueDeserializer; using v8::WeakCallbackInfo; using v8::WeakCallbackType; BaseObject::BaseObject(Realm* realm, Local<Object> object) : persistent_handle_(realm->isolate(), object), realm_(realm) { CHECK_EQ(false, object.IsEmpty()); CHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount); SetInternalFields(realm->isolate_data(), object, static_cast<void*>(this)); realm->AddCleanupHook(DeleteMe, static_cast<void*>(this)); realm->modify_base_object_count(1); } BaseObject::~BaseObject() { realm()->modify_base_object_count(-1); realm()->RemoveCleanupHook(DeleteMe, static_cast<void*>(this)); if (UNLIKELY(has_pointer_data())) { PointerData* metadata = pointer_data(); CHECK_EQ(metadata->strong_ptr_count, 0); metadata->self = nullptr; if (metadata->weak_ptr_count == 0) delete metadata; } if (persistent_handle_.IsEmpty()) { // This most likely happened because the weak callback below cleared it. return; } { HandleScope handle_scope(realm()->isolate()); object()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr); } } void BaseObject::MakeWeak() { if (has_pointer_data()) { pointer_data()->wants_weak_jsobj = true; if (pointer_data()->strong_ptr_count > 0) return; } persistent_handle_.SetWeak( this, [](const WeakCallbackInfo<BaseObject>& data) { BaseObject* obj = data.GetParameter(); // Clear the persistent handle so that ~BaseObject() doesn't attempt // to mess with internal fields, since the JS object may have // transitioned into an invalid state. // Refs: https://github.com/nodejs/node/issues/18897 obj->persistent_handle_.Reset(); CHECK_IMPLIES(obj->has_pointer_data(), obj->pointer_data()->strong_ptr_count == 0); obj->OnGCCollect(); }, WeakCallbackType::kParameter); } void BaseObject::LazilyInitializedJSTemplateConstructor( const FunctionCallbackInfo<Value>& args) { DCHECK(args.IsConstructCall()); CHECK_GE(args.This()->InternalFieldCount(), BaseObject::kInternalFieldCount); Environment* env = Environment::GetCurrent(args); DCHECK_NOT_NULL(env); SetInternalFields(env->isolate_data(), args.This(), nullptr); } Local<FunctionTemplate> BaseObject::MakeLazilyInitializedJSTemplate( Environment* env) { return MakeLazilyInitializedJSTemplate(env->isolate_data()); } Local<FunctionTemplate> BaseObject::MakeLazilyInitializedJSTemplate( IsolateData* isolate_data) { Local<FunctionTemplate> t = NewFunctionTemplate( isolate_data->isolate(), LazilyInitializedJSTemplateConstructor); t->InstanceTemplate()->SetInternalFieldCount(BaseObject::kInternalFieldCount); return t; } BaseObject::TransferMode BaseObject::GetTransferMode() const { return TransferMode::kDisallowCloneAndTransfer; } std::unique_ptr<worker::TransferData> BaseObject::TransferForMessaging() { return {}; } std::unique_ptr<worker::TransferData> BaseObject::CloneForMessaging() const { return {}; } Maybe<std::vector<BaseObjectPtr<BaseObject>>> BaseObject::NestedTransferables() const { return Just(std::vector<BaseObjectPtr<BaseObject>>{}); } Maybe<bool> BaseObject::FinalizeTransferRead(Local<Context> context, ValueDeserializer* deserializer) { return Just(true); } BaseObject::PointerData* BaseObject::pointer_data() { if (!has_pointer_data()) { PointerData* metadata = new PointerData(); metadata->wants_weak_jsobj = persistent_handle_.IsWeak(); metadata->self = this; pointer_data_ = metadata; } CHECK(has_pointer_data()); return pointer_data_; } void BaseObject::decrease_refcount() { CHECK(has_pointer_data()); PointerData* metadata = pointer_data(); CHECK_GT(metadata->strong_ptr_count, 0); unsigned int new_refcount = --metadata->strong_ptr_count; if (new_refcount == 0) { if (metadata->is_detached) { OnGCCollect(); } else if (metadata->wants_weak_jsobj && !persistent_handle_.IsEmpty()) { MakeWeak(); } } } void BaseObject::increase_refcount() { unsigned int prev_refcount = pointer_data()->strong_ptr_count++; if (prev_refcount == 0 && !persistent_handle_.IsEmpty()) persistent_handle_.ClearWeak(); } void BaseObject::DeleteMe(void* data) { BaseObject* self = static_cast<BaseObject*>(data); if (self->has_pointer_data() && self->pointer_data()->strong_ptr_count > 0) { return self->Detach(); } delete self; } bool BaseObject::IsDoneInitializing() const { return true; } Local<Object> BaseObject::WrappedObject() const { return object(); } bool BaseObject::IsRootNode() const { return !persistent_handle_.IsWeak(); } bool BaseObject::IsNotIndicativeOfMemoryLeakAtExit() const { return IsWeakOrDetached(); } } // namespace node