GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: base_object-inl.h Lines: 108 114 94.7 %
Date: 2022-09-29 04:23:51 Branches: 25 42 59.5 %

Line Branch Exec Source
1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// "Software"), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
#ifndef SRC_BASE_OBJECT_INL_H_
23
#define SRC_BASE_OBJECT_INL_H_
24
25
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26
27
#include "base_object.h"
28
#include "env-inl.h"
29
#include "util.h"
30
31
#include "v8.h"
32
33
namespace node {
34
35
1462911
BaseObject::BaseObject(Environment* env, v8::Local<v8::Object> object)
36
1462911
    : BaseObject(env->principal_realm(), object) {}
37
38
// static
39
55511
v8::Local<v8::FunctionTemplate> BaseObject::GetConstructorTemplate(
40
    Environment* env) {
41
55511
  return BaseObject::GetConstructorTemplate(env->isolate_data());
42
}
43
44
258911
void BaseObject::Detach() {
45
258911
  CHECK_GT(pointer_data()->strong_ptr_count, 0);
46
258911
  pointer_data()->is_detached = true;
47
258911
}
48
49
389435
v8::Global<v8::Object>& BaseObject::persistent() {
50
389435
  return persistent_handle_;
51
}
52
53
54
2509371
v8::Local<v8::Object> BaseObject::object() const {
55
2509371
  return PersistentToLocal::Default(env()->isolate(), persistent_handle_);
56
}
57
58
137694
v8::Local<v8::Object> BaseObject::object(v8::Isolate* isolate) const {
59
137694
  v8::Local<v8::Object> handle = object();
60
61
  DCHECK_EQ(handle->GetCreationContext().ToLocalChecked()->GetIsolate(),
62
            isolate);
63
  DCHECK_EQ(env()->isolate(), isolate);
64
65
137694
  return handle;
66
}
67
68
13821340
Environment* BaseObject::env() const {
69
13821340
  return realm_->env();
70
}
71
72
3271060
Realm* BaseObject::realm() const {
73
3271060
  return realm_;
74
}
75
76
10047765
BaseObject* BaseObject::FromJSObject(v8::Local<v8::Value> value) {
77
10047765
  v8::Local<v8::Object> obj = value.As<v8::Object>();
78
  DCHECK_GE(obj->InternalFieldCount(), BaseObject::kSlot);
79
  return static_cast<BaseObject*>(
80
20095530
      obj->GetAlignedPointerFromInternalField(BaseObject::kSlot));
81
}
82
83
84
template <typename T>
85
785289
T* BaseObject::FromJSObject(v8::Local<v8::Value> object) {
86
785289
  return static_cast<T*>(FromJSObject(object));
87
}
88
89
1268561
void BaseObject::OnGCCollect() {
90
1268561
  delete this;
91
1268561
}
92
93
80859
void BaseObject::ClearWeak() {
94
80859
  if (has_pointer_data())
95
8125
    pointer_data()->wants_weak_jsobj = false;
96
97
80859
  persistent_handle_.ClearWeak();
98
80859
}
99
100
bool BaseObject::IsWeakOrDetached() const {
101
  if (persistent_handle_.IsWeak()) return true;
102
103
  if (!has_pointer_data()) return false;
104
  const PointerData* pd = const_cast<BaseObject*>(this)->pointer_data();
105
  return pd->wants_weak_jsobj || pd->is_detached;
106
}
107
108
template <int Field>
109
8
void BaseObject::InternalFieldGet(
110
    v8::Local<v8::String> property,
111
    const v8::PropertyCallbackInfo<v8::Value>& info) {
112
8
  info.GetReturnValue().Set(info.This()->GetInternalField(Field));
113
8
}
114
115
template <int Field, bool (v8::Value::* typecheck)() const>
116
100029
void BaseObject::InternalFieldSet(v8::Local<v8::String> property,
117
                                  v8::Local<v8::Value> value,
118
                                  const v8::PropertyCallbackInfo<void>& info) {
119
  // This could be e.g. value->IsFunction().
120
100029
  CHECK(((*value)->*typecheck)());
121
100029
  info.This()->SetInternalField(Field, value);
122
100029
}
123
124
11648821
bool BaseObject::has_pointer_data() const {
125
11648821
  return pointer_data_ != nullptr;
126
}
127
128
template <typename T, bool kIsWeak>
129
BaseObject::PointerData*
130
3920482
BaseObjectPtrImpl<T, kIsWeak>::pointer_data() const {
131
  if constexpr (kIsWeak) {
132
2310078
    return data_.pointer_data;
133
  }
134
1610404
  if (get_base_object() == nullptr) {
135
    return nullptr;
136
  }
137
1610404
  return get_base_object()->pointer_data();
138
}
139
140
template <typename T, bool kIsWeak>
141
18552399
BaseObject* BaseObjectPtrImpl<T, kIsWeak>::get_base_object() const {
142
  if constexpr (kIsWeak) {
143
1042624
    if (pointer_data() == nullptr) {
144
8
      return nullptr;
145
    }
146
1042616
    return pointer_data()->self;
147
  }
148
17509775
  return data_.target;
149
}
150
151
template <typename T, bool kIsWeak>
152
3788860
BaseObjectPtrImpl<T, kIsWeak>::~BaseObjectPtrImpl() {
153
  if constexpr (kIsWeak) {
154
50222
    if (pointer_data() != nullptr &&
155

74144
        --pointer_data()->weak_ptr_count == 0 &&
156
23922
        pointer_data()->self == nullptr) {
157
26
      delete pointer_data();
158
    }
159
3738638
  } else if (get() != nullptr) {
160
1526429
    get()->decrease_refcount();
161
  }
162
3788860
}
163
164
template <typename T, bool kIsWeak>
165
2997209
BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl() {
166
2997209
  data_.target = nullptr;
167
2997209
}
168
169
template <typename T, bool kIsWeak>
170
2331741
BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(T* target)
171
2331741
  : BaseObjectPtrImpl() {
172
2331741
  if (target == nullptr) return;
173
  if constexpr (kIsWeak) {
174
50228
    data_.pointer_data = target->pointer_data();
175
50228
    CHECK_NOT_NULL(pointer_data());
176
50228
    pointer_data()->weak_ptr_count++;
177
  } else {
178
1610404
    data_.target = target;
179
1610404
    CHECK_NOT_NULL(pointer_data());
180
1610404
    get()->increase_refcount();
181
  }
182
}
183
184
template <typename T, bool kIsWeak>
185
template <typename U, bool kW>
186
43497
BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(
187
    const BaseObjectPtrImpl<U, kW>& other)
188
43497
  : BaseObjectPtrImpl(other.get()) {}
189
190
template <typename T, bool kIsWeak>
191
860109
BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(const BaseObjectPtrImpl& other)
192
860109
  : BaseObjectPtrImpl(other.get()) {}
193
194
template <typename T, bool kIsWeak>
195
template <typename U, bool kW>
196
8
BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=(
197
    const BaseObjectPtrImpl<U, kW>& other) {
198
8
  if (other.get() == get()) return *this;
199
8
  this->~BaseObjectPtrImpl();
200
8
  return *new (this) BaseObjectPtrImpl(other);
201
}
202
203
template <typename T, bool kIsWeak>
204
2
BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=(
205
    const BaseObjectPtrImpl& other) {
206
2
  if (other.get() == get()) return *this;
207
2
  this->~BaseObjectPtrImpl();
208
2
  return *new (this) BaseObjectPtrImpl(other);
209
}
210
211
template <typename T, bool kIsWeak>
212
886778
BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(BaseObjectPtrImpl&& other)
213
886778
  : data_(other.data_) {
214
  if constexpr (kIsWeak)
215
4
    other.data_.target = nullptr;
216
  else
217
886774
    other.data_.pointer_data = nullptr;
218
886778
}
219
220
template <typename T, bool kIsWeak>
221
427881
BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=(
222
    BaseObjectPtrImpl&& other) {
223
427881
  if (&other == this) return *this;
224
427881
  this->~BaseObjectPtrImpl();
225
427881
  return *new (this) BaseObjectPtrImpl(std::move(other));
226
}
227
228
template <typename T, bool kIsWeak>
229
261422
void BaseObjectPtrImpl<T, kIsWeak>::reset(T* ptr) {
230
261422
  *this = BaseObjectPtrImpl(ptr);
231
261422
}
232
233
template <typename T, bool kIsWeak>
234
15518701
T* BaseObjectPtrImpl<T, kIsWeak>::get() const {
235
15518701
  return static_cast<T*>(get_base_object());
236
}
237
238
template <typename T, bool kIsWeak>
239
T& BaseObjectPtrImpl<T, kIsWeak>::operator*() const {
240
  return *get();
241
}
242
243
template <typename T, bool kIsWeak>
244
4853329
T* BaseObjectPtrImpl<T, kIsWeak>::operator->() const {
245
4853329
  return get();
246
}
247
248
template <typename T, bool kIsWeak>
249
1247987
BaseObjectPtrImpl<T, kIsWeak>::operator bool() const {
250
1247987
  return get() != nullptr;
251
}
252
253
template <typename T, bool kIsWeak>
254
template <typename U, bool kW>
255
11144
bool BaseObjectPtrImpl<T, kIsWeak>::operator ==(
256
    const BaseObjectPtrImpl<U, kW>& other) const {
257
11144
  return get() == other.get();
258
}
259
260
template <typename T, bool kIsWeak>
261
template <typename U, bool kW>
262
bool BaseObjectPtrImpl<T, kIsWeak>::operator !=(
263
    const BaseObjectPtrImpl<U, kW>& other) const {
264
  return get() != other.get();
265
}
266
267
template <typename T, typename... Args>
268
41206
BaseObjectPtr<T> MakeBaseObject(Args&&... args) {
269
41206
  return BaseObjectPtr<T>(new T(std::forward<Args>(args)...));
270
}
271
272
template <typename T, typename... Args>
273
27228
BaseObjectPtr<T> MakeDetachedBaseObject(Args&&... args) {
274
27228
  BaseObjectPtr<T> target = MakeBaseObject<T>(std::forward<Args>(args)...);
275
27228
  target->Detach();
276
27228
  return target;
277
}
278
279
}  // namespace node
280
281
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
282
283
#endif  // SRC_BASE_OBJECT_INL_H_