11cb0ef41Sopenharmony_ci#include "base_object-inl.h" 21cb0ef41Sopenharmony_ci#include "gtest/gtest.h" 31cb0ef41Sopenharmony_ci#include "node.h" 41cb0ef41Sopenharmony_ci#include "node_realm-inl.h" 51cb0ef41Sopenharmony_ci#include "node_test_fixture.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciusing node::BaseObject; 81cb0ef41Sopenharmony_ciusing node::BaseObjectPtr; 91cb0ef41Sopenharmony_ciusing node::BaseObjectWeakPtr; 101cb0ef41Sopenharmony_ciusing node::Environment; 111cb0ef41Sopenharmony_ciusing node::MakeBaseObject; 121cb0ef41Sopenharmony_ciusing node::MakeDetachedBaseObject; 131cb0ef41Sopenharmony_ciusing node::Realm; 141cb0ef41Sopenharmony_ciusing v8::HandleScope; 151cb0ef41Sopenharmony_ciusing v8::Isolate; 161cb0ef41Sopenharmony_ciusing v8::Local; 171cb0ef41Sopenharmony_ciusing v8::Object; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciclass BaseObjectPtrTest : public EnvironmentTestFixture {}; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ciclass DummyBaseObject : public BaseObject { 221cb0ef41Sopenharmony_ci public: 231cb0ef41Sopenharmony_ci DummyBaseObject(Environment* env, Local<Object> obj) : BaseObject(env, obj) {} 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci static Local<Object> MakeJSObject(Environment* env) { 261cb0ef41Sopenharmony_ci return BaseObject::MakeLazilyInitializedJSTemplate(env) 271cb0ef41Sopenharmony_ci ->GetFunction(env->context()).ToLocalChecked() 281cb0ef41Sopenharmony_ci ->NewInstance(env->context()).ToLocalChecked(); 291cb0ef41Sopenharmony_ci } 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci static BaseObjectPtr<DummyBaseObject> NewDetached(Environment* env) { 321cb0ef41Sopenharmony_ci Local<Object> obj = MakeJSObject(env); 331cb0ef41Sopenharmony_ci return MakeDetachedBaseObject<DummyBaseObject>(env, obj); 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci static BaseObjectPtr<DummyBaseObject> New(Environment* env) { 371cb0ef41Sopenharmony_ci Local<Object> obj = MakeJSObject(env); 381cb0ef41Sopenharmony_ci return MakeBaseObject<DummyBaseObject>(env, obj); 391cb0ef41Sopenharmony_ci } 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci SET_NO_MEMORY_INFO() 421cb0ef41Sopenharmony_ci SET_MEMORY_INFO_NAME(DummyBaseObject) 431cb0ef41Sopenharmony_ci SET_SELF_SIZE(DummyBaseObject) 441cb0ef41Sopenharmony_ci}; 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ciTEST_F(BaseObjectPtrTest, ScopedDetached) { 471cb0ef41Sopenharmony_ci const HandleScope handle_scope(isolate_); 481cb0ef41Sopenharmony_ci const Argv argv; 491cb0ef41Sopenharmony_ci Env env_{handle_scope, argv}; 501cb0ef41Sopenharmony_ci Environment* env = *env_; 511cb0ef41Sopenharmony_ci Realm* realm = env->principal_realm(); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0); 541cb0ef41Sopenharmony_ci { 551cb0ef41Sopenharmony_ci BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::NewDetached(env); 561cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1); 571cb0ef41Sopenharmony_ci } 581cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0); 591cb0ef41Sopenharmony_ci} 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_ciTEST_F(BaseObjectPtrTest, ScopedDetachedWithWeak) { 621cb0ef41Sopenharmony_ci const HandleScope handle_scope(isolate_); 631cb0ef41Sopenharmony_ci const Argv argv; 641cb0ef41Sopenharmony_ci Env env_{handle_scope, argv}; 651cb0ef41Sopenharmony_ci Environment* env = *env_; 661cb0ef41Sopenharmony_ci Realm* realm = env->principal_realm(); 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci BaseObjectWeakPtr<DummyBaseObject> weak_ptr; 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0); 711cb0ef41Sopenharmony_ci { 721cb0ef41Sopenharmony_ci BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::NewDetached(env); 731cb0ef41Sopenharmony_ci weak_ptr = ptr; 741cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1); 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr.get(), nullptr); 771cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0); 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ciTEST_F(BaseObjectPtrTest, Undetached) { 811cb0ef41Sopenharmony_ci const HandleScope handle_scope(isolate_); 821cb0ef41Sopenharmony_ci const Argv argv; 831cb0ef41Sopenharmony_ci Env env_{handle_scope, argv}; 841cb0ef41Sopenharmony_ci Environment* env = *env_; 851cb0ef41Sopenharmony_ci Realm* realm = env->principal_realm(); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci node::AddEnvironmentCleanupHook( 881cb0ef41Sopenharmony_ci isolate_, 891cb0ef41Sopenharmony_ci [](void* arg) { 901cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<Realm*>(arg)->base_object_count(), 0); 911cb0ef41Sopenharmony_ci }, 921cb0ef41Sopenharmony_ci realm); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::New(env); 951cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1); 961cb0ef41Sopenharmony_ci} 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ciTEST_F(BaseObjectPtrTest, GCWeak) { 991cb0ef41Sopenharmony_ci const HandleScope handle_scope(isolate_); 1001cb0ef41Sopenharmony_ci const Argv argv; 1011cb0ef41Sopenharmony_ci Env env_{handle_scope, argv}; 1021cb0ef41Sopenharmony_ci Environment* env = *env_; 1031cb0ef41Sopenharmony_ci Realm* realm = env->principal_realm(); 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci BaseObjectWeakPtr<DummyBaseObject> weak_ptr; 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci { 1081cb0ef41Sopenharmony_ci const HandleScope handle_scope(isolate_); 1091cb0ef41Sopenharmony_ci BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::New(env); 1101cb0ef41Sopenharmony_ci weak_ptr = ptr; 1111cb0ef41Sopenharmony_ci ptr->MakeWeak(); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1); 1141cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr.get(), ptr.get()); 1151cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr->persistent().IsWeak(), false); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci ptr.reset(); 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1); 1211cb0ef41Sopenharmony_ci EXPECT_NE(weak_ptr.get(), nullptr); 1221cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr->persistent().IsWeak(), true); 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci v8::V8::SetFlagsFromString("--expose-gc"); 1251cb0ef41Sopenharmony_ci isolate_->RequestGarbageCollectionForTesting(Isolate::kFullGarbageCollection); 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0); 1281cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr.get(), nullptr); 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciTEST_F(BaseObjectPtrTest, Moveable) { 1321cb0ef41Sopenharmony_ci const HandleScope handle_scope(isolate_); 1331cb0ef41Sopenharmony_ci const Argv argv; 1341cb0ef41Sopenharmony_ci Env env_{handle_scope, argv}; 1351cb0ef41Sopenharmony_ci Environment* env = *env_; 1361cb0ef41Sopenharmony_ci Realm* realm = env->principal_realm(); 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::NewDetached(env); 1391cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1); 1401cb0ef41Sopenharmony_ci BaseObjectWeakPtr<DummyBaseObject> weak_ptr { ptr }; 1411cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr.get(), ptr.get()); 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci BaseObjectPtr<DummyBaseObject> ptr2 = std::move(ptr); 1441cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr.get(), ptr2.get()); 1451cb0ef41Sopenharmony_ci EXPECT_EQ(ptr.get(), nullptr); 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci BaseObjectWeakPtr<DummyBaseObject> weak_ptr2 = std::move(weak_ptr); 1481cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr2.get(), ptr2.get()); 1491cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr.get(), nullptr); 1501cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1); 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci ptr2.reset(); 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci EXPECT_EQ(weak_ptr2.get(), nullptr); 1551cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0); 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ciTEST_F(BaseObjectPtrTest, NestedClasses) { 1591cb0ef41Sopenharmony_ci class ObjectWithPtr : public BaseObject { 1601cb0ef41Sopenharmony_ci public: 1611cb0ef41Sopenharmony_ci ObjectWithPtr(Environment* env, Local<Object> obj) : BaseObject(env, obj) {} 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci BaseObjectPtr<BaseObject> ptr1; 1641cb0ef41Sopenharmony_ci BaseObjectPtr<BaseObject> ptr2; 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci SET_NO_MEMORY_INFO() 1671cb0ef41Sopenharmony_ci SET_MEMORY_INFO_NAME(ObjectWithPtr) 1681cb0ef41Sopenharmony_ci SET_SELF_SIZE(ObjectWithPtr) 1691cb0ef41Sopenharmony_ci }; 1701cb0ef41Sopenharmony_ci 1711cb0ef41Sopenharmony_ci const HandleScope handle_scope(isolate_); 1721cb0ef41Sopenharmony_ci const Argv argv; 1731cb0ef41Sopenharmony_ci Env env_{handle_scope, argv}; 1741cb0ef41Sopenharmony_ci Environment* env = *env_; 1751cb0ef41Sopenharmony_ci Realm* realm = env->principal_realm(); 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci node::AddEnvironmentCleanupHook( 1781cb0ef41Sopenharmony_ci isolate_, 1791cb0ef41Sopenharmony_ci [](void* arg) { 1801cb0ef41Sopenharmony_ci EXPECT_EQ(static_cast<Realm*>(arg)->base_object_count(), 0); 1811cb0ef41Sopenharmony_ci }, 1821cb0ef41Sopenharmony_ci realm); 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci ObjectWithPtr* obj = 1851cb0ef41Sopenharmony_ci new ObjectWithPtr(env, DummyBaseObject::MakeJSObject(env)); 1861cb0ef41Sopenharmony_ci obj->ptr1 = DummyBaseObject::NewDetached(env); 1871cb0ef41Sopenharmony_ci obj->ptr2 = DummyBaseObject::New(env); 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci EXPECT_EQ(realm->base_object_created_after_bootstrap(), 3); 1901cb0ef41Sopenharmony_ci} 191