Skip to content

Commit e00c1ec

Browse files
legendecasaduh95
authored andcommitted
src: add BaseObjectPtr nullptr operations
Allow comparing a `BaseObjectPtr` or implicitly construct a `BaseObjectPtr` with `nullptr`. PR-URL: #56585 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 648ad25 commit e00c1ec

8 files changed

+79
-13
lines changed

src/base_object-inl.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,17 @@ BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=(
250250
return *new (this) BaseObjectPtrImpl(std::move(other));
251251
}
252252

253+
template <typename T, bool kIsWeak>
254+
BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(std::nullptr_t)
255+
: BaseObjectPtrImpl() {}
256+
257+
template <typename T, bool kIsWeak>
258+
BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=(
259+
std::nullptr_t) {
260+
this->~BaseObjectPtrImpl();
261+
return *new (this) BaseObjectPtrImpl();
262+
}
263+
253264
template <typename T, bool kIsWeak>
254265
void BaseObjectPtrImpl<T, kIsWeak>::reset(T* ptr) {
255266
*this = BaseObjectPtrImpl(ptr);
@@ -289,6 +300,16 @@ bool BaseObjectPtrImpl<T, kIsWeak>::operator !=(
289300
return get() != other.get();
290301
}
291302

303+
template <typename T, bool kIsWeak>
304+
bool operator==(const BaseObjectPtrImpl<T, kIsWeak> ptr, const std::nullptr_t) {
305+
return ptr.get() == nullptr;
306+
}
307+
308+
template <typename T, bool kIsWeak>
309+
bool operator==(const std::nullptr_t, const BaseObjectPtrImpl<T, kIsWeak> ptr) {
310+
return ptr.get() == nullptr;
311+
}
312+
292313
template <typename T, typename... Args>
293314
BaseObjectPtr<T> MakeBaseObject(Args&&... args) {
294315
return BaseObjectPtr<T>(new T(std::forward<Args>(args)...));

src/base_object.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ class BaseObjectPtrImpl final {
274274
inline BaseObjectPtrImpl(BaseObjectPtrImpl&& other);
275275
inline BaseObjectPtrImpl& operator=(BaseObjectPtrImpl&& other);
276276

277+
inline BaseObjectPtrImpl(std::nullptr_t);
278+
inline BaseObjectPtrImpl& operator=(std::nullptr_t);
279+
277280
inline void reset(T* ptr = nullptr);
278281
inline T* get() const;
279282
inline T& operator*() const;
@@ -295,6 +298,13 @@ class BaseObjectPtrImpl final {
295298
inline BaseObject::PointerData* pointer_data() const;
296299
};
297300

301+
template <typename T, bool kIsWeak>
302+
inline static bool operator==(const BaseObjectPtrImpl<T, kIsWeak>,
303+
const std::nullptr_t);
304+
template <typename T, bool kIsWeak>
305+
inline static bool operator==(const std::nullptr_t,
306+
const BaseObjectPtrImpl<T, kIsWeak>);
307+
298308
template <typename T>
299309
using BaseObjectPtr = BaseObjectPtrImpl<T, false>;
300310
template <typename T>

src/histogram.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ BaseObjectPtr<HistogramBase> HistogramBase::Create(
224224
->InstanceTemplate()
225225
->NewInstance(env->context())
226226
.ToLocal(&obj)) {
227-
return BaseObjectPtr<HistogramBase>();
227+
return nullptr;
228228
}
229229

230230
return MakeBaseObject<HistogramBase>(env, obj, options);
@@ -238,7 +238,7 @@ BaseObjectPtr<HistogramBase> HistogramBase::Create(
238238
->InstanceTemplate()
239239
->NewInstance(env->context())
240240
.ToLocal(&obj)) {
241-
return BaseObjectPtr<HistogramBase>();
241+
return nullptr;
242242
}
243243
return MakeBaseObject<HistogramBase>(env, obj, std::move(histogram));
244244
}
@@ -392,7 +392,7 @@ BaseObjectPtr<IntervalHistogram> IntervalHistogram::Create(
392392
if (!GetConstructorTemplate(env)
393393
->InstanceTemplate()
394394
->NewInstance(env->context()).ToLocal(&obj)) {
395-
return BaseObjectPtr<IntervalHistogram>();
395+
return nullptr;
396396
}
397397

398398
return MakeBaseObject<IntervalHistogram>(

src/node_blob.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,10 @@ BaseObjectPtr<Blob> Blob::Create(Environment* env,
168168

169169
Local<Function> ctor;
170170
if (!GetConstructorTemplate(env)->GetFunction(env->context()).ToLocal(&ctor))
171-
return BaseObjectPtr<Blob>();
171+
return nullptr;
172172

173173
Local<Object> obj;
174-
if (!ctor->NewInstance(env->context()).ToLocal(&obj))
175-
return BaseObjectPtr<Blob>();
174+
if (!ctor->NewInstance(env->context()).ToLocal(&obj)) return nullptr;
176175

177176
return MakeBaseObject<Blob>(env, obj, data_queue);
178177
}
@@ -326,7 +325,7 @@ BaseObjectPtr<Blob::Reader> Blob::Reader::Create(Environment* env,
326325
->InstanceTemplate()
327326
->NewInstance(env->context())
328327
.ToLocal(&obj)) {
329-
return BaseObjectPtr<Blob::Reader>();
328+
return nullptr;
330329
}
331330

332331
return MakeBaseObject<Blob::Reader>(env, obj, std::move(blob));

src/node_http2.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ void Http2Session::Close(uint32_t code, bool socket_closed) {
867867
// but this is faster and does not fail if the stream is not found.
868868
BaseObjectPtr<Http2Stream> Http2Session::FindStream(int32_t id) {
869869
auto s = streams_.find(id);
870-
return s != streams_.end() ? s->second : BaseObjectPtr<Http2Stream>();
870+
return s != streams_.end() ? s->second : nullptr;
871871
}
872872

873873
bool Http2Session::CanAddStream() {

src/node_sockaddr.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ BaseObjectPtr<SocketAddressBlockListWrap> SocketAddressBlockListWrap::New(
553553
if (!env->blocklist_constructor_template()
554554
->InstanceTemplate()
555555
->NewInstance(env->context()).ToLocal(&obj)) {
556-
return BaseObjectPtr<SocketAddressBlockListWrap>();
556+
return nullptr;
557557
}
558558
BaseObjectPtr<SocketAddressBlockListWrap> wrap =
559559
MakeBaseObject<SocketAddressBlockListWrap>(env, obj);
@@ -568,7 +568,7 @@ BaseObjectPtr<SocketAddressBlockListWrap> SocketAddressBlockListWrap::New(
568568
if (!env->blocklist_constructor_template()
569569
->InstanceTemplate()
570570
->NewInstance(env->context()).ToLocal(&obj)) {
571-
return BaseObjectPtr<SocketAddressBlockListWrap>();
571+
return nullptr;
572572
}
573573
BaseObjectPtr<SocketAddressBlockListWrap> wrap =
574574
MakeBaseObject<SocketAddressBlockListWrap>(
@@ -775,7 +775,7 @@ BaseObjectPtr<SocketAddressBase> SocketAddressBase::Create(
775775
if (!GetConstructorTemplate(env)
776776
->InstanceTemplate()
777777
->NewInstance(env->context()).ToLocal(&obj)) {
778-
return BaseObjectPtr<SocketAddressBase>();
778+
return nullptr;
779779
}
780780

781781
return MakeBaseObject<SocketAddressBase>(env, obj, std::move(address));

src/node_sqlite.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,7 +2390,7 @@ BaseObjectPtr<StatementSync> StatementSync::Create(
23902390
->InstanceTemplate()
23912391
->NewInstance(env->context())
23922392
.ToLocal(&obj)) {
2393-
return BaseObjectPtr<StatementSync>();
2393+
return nullptr;
23942394
}
23952395

23962396
return MakeBaseObject<StatementSync>(env, obj, std::move(db), stmt);
@@ -2544,7 +2544,7 @@ BaseObjectPtr<Session> Session::Create(Environment* env,
25442544
->InstanceTemplate()
25452545
->NewInstance(env->context())
25462546
.ToLocal(&obj)) {
2547-
return BaseObjectPtr<Session>();
2547+
return nullptr;
25482548
}
25492549

25502550
return MakeBaseObject<Session>(env, obj, std::move(database), session);

test/cctest/test_base_object_ptr.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,42 @@ TEST_F(BaseObjectPtrTest, Moveable) {
155155
EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0);
156156
}
157157

158+
TEST_F(BaseObjectPtrTest, Nullptr) {
159+
const HandleScope handle_scope(isolate_);
160+
const Argv argv;
161+
Env env_{handle_scope, argv};
162+
Environment* env = *env_;
163+
Realm* realm = env->principal_realm();
164+
165+
BaseObjectPtr<DummyBaseObject> ptr = nullptr;
166+
EXPECT_EQ(nullptr, ptr);
167+
EXPECT_EQ(ptr, nullptr);
168+
EXPECT_EQ(nullptr, ptr.get());
169+
170+
// Implicit constructor.
171+
BaseObjectPtr<DummyBaseObject> ptr2 = []() -> BaseObjectPtr<DummyBaseObject> {
172+
return nullptr;
173+
}();
174+
EXPECT_EQ(nullptr, ptr2);
175+
EXPECT_EQ(ptr2, nullptr);
176+
EXPECT_EQ(nullptr, ptr2.get());
177+
178+
BaseObjectWeakPtr<DummyBaseObject> weak_ptr{ptr};
179+
EXPECT_EQ(nullptr, weak_ptr);
180+
EXPECT_EQ(weak_ptr, nullptr);
181+
EXPECT_EQ(nullptr, weak_ptr.get());
182+
ptr.reset();
183+
EXPECT_EQ(weak_ptr.get(), nullptr);
184+
185+
// No object creation with nullptr.
186+
EXPECT_EQ(realm->base_object_created_after_bootstrap(), 0);
187+
188+
BaseObjectPtr<DummyBaseObject> ptr4 = DummyBaseObject::NewDetached(env);
189+
EXPECT_NE(nullptr, ptr4);
190+
EXPECT_NE(ptr4, nullptr);
191+
EXPECT_EQ(realm->base_object_created_after_bootstrap(), 1);
192+
}
193+
158194
TEST_F(BaseObjectPtrTest, NestedClasses) {
159195
class ObjectWithPtr : public BaseObject {
160196
public:

0 commit comments

Comments
 (0)