The C and C++ Include Header Files
/usr/include/nodejs/src/base_object-inl.h
$ cat -n /usr/include/nodejs/src/base_object-inl.h 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 #if (__GNUC__ >= 8) && !defined(__clang__) 32 #pragma GCC diagnostic push 33 #pragma GCC diagnostic ignored "-Wcast-function-type" 34 #endif 35 #include "v8.h" 36 #if (__GNUC__ >= 8) && !defined(__clang__) 37 #pragma GCC diagnostic pop 38 #endif 39 40 namespace node { 41 42 BaseObject::BaseObject(Environment* env, v8::Local
object) 43 : persistent_handle_(env->isolate(), object), env_(env) { 44 CHECK_EQ(false, object.IsEmpty()); 45 CHECK_GT(object->InternalFieldCount(), 0); 46 object->SetAlignedPointerInInternalField( 47 BaseObject::kSlot, 48 static_cast
(this)); 49 env->AddCleanupHook(DeleteMe, static_cast
(this)); 50 env->modify_base_object_count(1); 51 } 52 53 BaseObject::~BaseObject() { 54 env()->modify_base_object_count(-1); 55 env()->RemoveCleanupHook(DeleteMe, static_cast
(this)); 56 57 if (UNLIKELY(has_pointer_data())) { 58 PointerData* metadata = pointer_data(); 59 CHECK_EQ(metadata->strong_ptr_count, 0); 60 metadata->self = nullptr; 61 if (metadata->weak_ptr_count == 0) 62 delete metadata; 63 } 64 65 if (persistent_handle_.IsEmpty()) { 66 // This most likely happened because the weak callback below cleared it. 67 return; 68 } 69 70 { 71 v8::HandleScope handle_scope(env()->isolate()); 72 object()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr); 73 } 74 } 75 76 void BaseObject::Detach() { 77 CHECK_GT(pointer_data()->strong_ptr_count, 0); 78 pointer_data()->is_detached = true; 79 } 80 81 v8::Global
& BaseObject::persistent() { 82 return persistent_handle_; 83 } 84 85 86 v8::Local
BaseObject::object() const { 87 return PersistentToLocal::Default(env()->isolate(), persistent_handle_); 88 } 89 90 v8::Local
BaseObject::object(v8::Isolate* isolate) const { 91 v8::Local
handle = object(); 92 93 DCHECK_EQ(handle->CreationContext()->GetIsolate(), isolate); 94 DCHECK_EQ(env()->isolate(), isolate); 95 96 return handle; 97 } 98 99 Environment* BaseObject::env() const { 100 return env_; 101 } 102 103 BaseObject* BaseObject::FromJSObject(v8::Local
obj) { 104 CHECK_GT(obj->InternalFieldCount(), 0); 105 return static_cast
( 106 obj->GetAlignedPointerFromInternalField(BaseObject::kSlot)); 107 } 108 109 110 template
111 T* BaseObject::FromJSObject(v8::Local
object) { 112 return static_cast
(FromJSObject(object)); 113 } 114 115 116 void BaseObject::MakeWeak() { 117 if (has_pointer_data()) { 118 pointer_data()->wants_weak_jsobj = true; 119 if (pointer_data()->strong_ptr_count > 0) return; 120 } 121 122 persistent_handle_.SetWeak( 123 this, 124 [](const v8::WeakCallbackInfo
& data) { 125 BaseObject* obj = data.GetParameter(); 126 // Clear the persistent handle so that ~BaseObject() doesn't attempt 127 // to mess with internal fields, since the JS object may have 128 // transitioned into an invalid state. 129 // Refs: https://github.com/nodejs/node/issues/18897 130 obj->persistent_handle_.Reset(); 131 CHECK_IMPLIES(obj->has_pointer_data(), 132 obj->pointer_data()->strong_ptr_count == 0); 133 obj->OnGCCollect(); 134 }, v8::WeakCallbackType::kParameter); 135 } 136 137 void BaseObject::OnGCCollect() { 138 delete this; 139 } 140 141 void BaseObject::ClearWeak() { 142 if (has_pointer_data()) 143 pointer_data()->wants_weak_jsobj = false; 144 145 persistent_handle_.ClearWeak(); 146 } 147 148 149 v8::Local
150 BaseObject::MakeLazilyInitializedJSTemplate(Environment* env) { 151 auto constructor = [](const v8::FunctionCallbackInfo
& args) { 152 DCHECK(args.IsConstructCall()); 153 DCHECK_GT(args.This()->InternalFieldCount(), 0); 154 args.This()->SetAlignedPointerInInternalField(BaseObject::kSlot, nullptr); 155 }; 156 157 v8::Local
t = env->NewFunctionTemplate(constructor); 158 t->Inherit(BaseObject::GetConstructorTemplate(env)); 159 t->InstanceTemplate()->SetInternalFieldCount( 160 BaseObject::kInternalFieldCount); 161 return t; 162 } 163 164 template
165 void BaseObject::InternalFieldGet( 166 v8::Local
property, 167 const v8::PropertyCallbackInfo
& info) { 168 info.GetReturnValue().Set(info.This()->GetInternalField(Field)); 169 } 170 171 template
172 void BaseObject::InternalFieldSet(v8::Local
property, 173 v8::Local
value, 174 const v8::PropertyCallbackInfo
& info) { 175 // This could be e.g. value->IsFunction(). 176 CHECK(((*value)->*typecheck)()); 177 info.This()->SetInternalField(Field, value); 178 } 179 180 bool BaseObject::has_pointer_data() const { 181 return pointer_data_ != nullptr; 182 } 183 184 BaseObject::PointerData* BaseObject::pointer_data() { 185 if (!has_pointer_data()) { 186 PointerData* metadata = new PointerData(); 187 metadata->wants_weak_jsobj = persistent_handle_.IsWeak(); 188 metadata->self = this; 189 pointer_data_ = metadata; 190 } 191 CHECK(has_pointer_data()); 192 return pointer_data_; 193 } 194 195 void BaseObject::decrease_refcount() { 196 CHECK(has_pointer_data()); 197 PointerData* metadata = pointer_data(); 198 CHECK_GT(metadata->strong_ptr_count, 0); 199 unsigned int new_refcount = --metadata->strong_ptr_count; 200 if (new_refcount == 0) { 201 if (metadata->is_detached) { 202 delete this; 203 } else if (metadata->wants_weak_jsobj && !persistent_handle_.IsEmpty()) { 204 MakeWeak(); 205 } 206 } 207 } 208 209 void BaseObject::increase_refcount() { 210 unsigned int prev_refcount = pointer_data()->strong_ptr_count++; 211 if (prev_refcount == 0 && !persistent_handle_.IsEmpty()) 212 persistent_handle_.ClearWeak(); 213 } 214 215 template
216 BaseObject::PointerData* 217 BaseObjectPtrImpl
::pointer_data() const { 218 if (kIsWeak) { 219 return data_.pointer_data; 220 } 221 if (get_base_object() == nullptr) { 222 return nullptr; 223 } 224 return get_base_object()->pointer_data(); 225 } 226 227 template
228 BaseObject* BaseObjectPtrImpl
::get_base_object() const { 229 if (kIsWeak) { 230 if (pointer_data() == nullptr) { 231 return nullptr; 232 } 233 return pointer_data()->self; 234 } 235 return data_.target; 236 } 237 238 template
239 BaseObjectPtrImpl
::~BaseObjectPtrImpl() { 240 if (kIsWeak) { 241 if (pointer_data() != nullptr && 242 --pointer_data()->weak_ptr_count == 0 && 243 pointer_data()->self == nullptr) { 244 delete pointer_data(); 245 } 246 } else if (get() != nullptr) { 247 get()->decrease_refcount(); 248 } 249 } 250 251 template
252 BaseObjectPtrImpl
::BaseObjectPtrImpl() { 253 data_.target = nullptr; 254 } 255 256 template
257 BaseObjectPtrImpl
::BaseObjectPtrImpl(T* target) 258 : BaseObjectPtrImpl() { 259 if (target == nullptr) return; 260 if (kIsWeak) { 261 data_.pointer_data = target->pointer_data(); 262 CHECK_NOT_NULL(pointer_data()); 263 pointer_data()->weak_ptr_count++; 264 } else { 265 data_.target = target; 266 CHECK_NOT_NULL(pointer_data()); 267 get()->increase_refcount(); 268 } 269 } 270 271 template
272 template
273 BaseObjectPtrImpl
::BaseObjectPtrImpl( 274 const BaseObjectPtrImpl
& other) 275 : BaseObjectPtrImpl(other.get()) {} 276 277 template
278 BaseObjectPtrImpl
::BaseObjectPtrImpl(const BaseObjectPtrImpl& other) 279 : BaseObjectPtrImpl(other.get()) {} 280 281 template
282 template
283 BaseObjectPtrImpl
& BaseObjectPtrImpl
::operator=( 284 const BaseObjectPtrImpl
& other) { 285 if (other.get() == get()) return *this; 286 this->~BaseObjectPtrImpl(); 287 return *new (this) BaseObjectPtrImpl(other); 288 } 289 290 template
291 BaseObjectPtrImpl
& BaseObjectPtrImpl
::operator=( 292 const BaseObjectPtrImpl& other) { 293 if (other.get() == get()) return *this; 294 this->~BaseObjectPtrImpl(); 295 return *new (this) BaseObjectPtrImpl(other); 296 } 297 298 template
299 BaseObjectPtrImpl
::BaseObjectPtrImpl(BaseObjectPtrImpl&& other) 300 : data_(other.data_) { 301 if (kIsWeak) 302 other.data_.target = nullptr; 303 else 304 other.data_.pointer_data = nullptr; 305 } 306 307 template
308 BaseObjectPtrImpl
& BaseObjectPtrImpl
::operator=( 309 BaseObjectPtrImpl&& other) { 310 if (&other == this) return *this; 311 this->~BaseObjectPtrImpl(); 312 return *new (this) BaseObjectPtrImpl(std::move(other)); 313 } 314 315 template
316 void BaseObjectPtrImpl
::reset(T* ptr) { 317 *this = BaseObjectPtrImpl(ptr); 318 } 319 320 template
321 T* BaseObjectPtrImpl
::get() const { 322 return static_cast
(get_base_object()); 323 } 324 325 template
326 T& BaseObjectPtrImpl
::operator*() const { 327 return *get(); 328 } 329 330 template
331 T* BaseObjectPtrImpl
::operator->() const { 332 return get(); 333 } 334 335 template
336 BaseObjectPtrImpl
::operator bool() const { 337 return get() != nullptr; 338 } 339 340 template
341 template
342 bool BaseObjectPtrImpl
::operator ==( 343 const BaseObjectPtrImpl
& other) const { 344 return get() == other.get(); 345 } 346 347 template
348 template
349 bool BaseObjectPtrImpl
::operator !=( 350 const BaseObjectPtrImpl
& other) const { 351 return get() != other.get(); 352 } 353 354 template
355 BaseObjectPtr
MakeBaseObject(Args&&... args) { 356 return BaseObjectPtr
(new T(std::forward
(args)...)); 357 } 358 359 template
360 BaseObjectPtr
MakeDetachedBaseObject(Args&&... args) { 361 BaseObjectPtr
target = MakeBaseObject
(std::forward
(args)...); 362 target->Detach(); 363 return target; 364 } 365 366 } // namespace node 367 368 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 369 370 #endif // SRC_BASE_OBJECT_INL_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™