Where Online Learning is simpler!
The C and C++ Include Header Files
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 #include "v8.h" 32 33 namespace node { 34 35 BaseObject::BaseObject(Environment* env, v8::Local<v8::Object> object) 36 : BaseObject(env->principal_realm(), object) { 37 // TODO(legendecas): Check the shorthand is only used in the principal realm 38 // while allowing to create a BaseObject in a vm context. 39 } 40 41 void BaseObject::Detach() { 42 CHECK_GT(pointer_data()->strong_ptr_count, 0); 43 pointer_data()->is_detached = true; 44 } 45 46 v8::Global<v8::Object>& BaseObject::persistent() { 47 return persistent_handle_; 48 } 49 50 51 v8::Local<v8::Object> BaseObject::object() const { 52 return PersistentToLocal::Default(env()->isolate(), persistent_handle_); 53 } 54 55 v8::Local<v8::Object> BaseObject::object(v8::Isolate* isolate) const { 56 v8::Local<v8::Object> handle = object(); 57 58 DCHECK_EQ(handle->GetCreationContextChecked()->GetIsolate(), isolate); 59 DCHECK_EQ(env()->isolate(), isolate); 60 61 return handle; 62 } 63 64 Environment* BaseObject::env() const { 65 return realm_->env(); 66 } 67 68 Realm* BaseObject::realm() const { 69 return realm_; 70 } 71 72 bool BaseObject::IsBaseObject(IsolateData* isolate_data, 73 v8::Local<v8::Object> obj) { 74 if (obj->InternalFieldCount() < BaseObject::kInternalFieldCount) { 75 return false; 76 } 77 78 uint16_t* ptr = static_cast<uint16_t*>( 79 obj->GetAlignedPointerFromInternalField(BaseObject::kEmbedderType)); 80 return ptr == isolate_data->embedder_id_for_non_cppgc(); 81 } 82 83 void BaseObject::TagBaseObject(IsolateData* isolate_data, 84 v8::Local<v8::Object> object) { 85 DCHECK_GE(object->InternalFieldCount(), BaseObject::kInternalFieldCount); 86 object->SetAlignedPointerInInternalField( 87 BaseObject::kEmbedderType, isolate_data->embedder_id_for_non_cppgc()); 88 } 89 90 void BaseObject::SetInternalFields(IsolateData* isolate_data, 91 v8::Local<v8::Object> object, 92 void* slot) { 93 TagBaseObject(isolate_data, object); 94 object->SetAlignedPointerInInternalField(BaseObject::kSlot, slot); 95 } 96 97 BaseObject* BaseObject::FromJSObject(v8::Local<v8::Value> value) { 98 v8::Local<v8::Object> obj = value.As<v8::Object>(); 99 DCHECK_GE(obj->InternalFieldCount(), BaseObject::kInternalFieldCount); 100 return static_cast<BaseObject*>( 101 obj->GetAlignedPointerFromInternalField(BaseObject::kSlot)); 102 } 103 104 template <typename T> 105 T* BaseObject::FromJSObject(v8::Local<v8::Value> object) { 106 return static_cast<T*>(FromJSObject(object)); 107 } 108 109 void BaseObject::OnGCCollect() { 110 delete this; 111 } 112 113 void BaseObject::ClearWeak() { 114 if (has_pointer_data()) 115 pointer_data()->wants_weak_jsobj = false; 116 117 persistent_handle_.ClearWeak(); 118 } 119 120 bool BaseObject::IsWeakOrDetached() const { 121 if (persistent_handle_.IsWeak()) return true; 122 123 if (!has_pointer_data()) return false; 124 const PointerData* pd = const_cast<BaseObject*>(this)->pointer_data(); 125 return pd->wants_weak_jsobj || pd->is_detached; 126 } 127 128 v8::EmbedderGraph::Node::Detachedness BaseObject::GetDetachedness() const { 129 return IsWeakOrDetached() ? v8::EmbedderGraph::Node::Detachedness::kDetached 130 : v8::EmbedderGraph::Node::Detachedness::kUnknown; 131 } 132 133 template <int Field> 134 void BaseObject::InternalFieldGet( 135 const v8::FunctionCallbackInfo<v8::Value>& args) { 136 args.GetReturnValue().Set( 137 args.This()->GetInternalField(Field).As<v8::Value>()); 138 } 139 140 template <int Field, bool (v8::Value::*typecheck)() const> 141 void BaseObject::InternalFieldSet( 142 const v8::FunctionCallbackInfo<v8::Value>& args) { 143 v8::Local<v8::Value> value = args[0]; 144 // This could be e.g. value->IsFunction(). 145 CHECK(((*value)->*typecheck)()); 146 args.This()->SetInternalField(Field, value); 147 } 148 149 bool BaseObject::has_pointer_data() const { 150 return pointer_data_ != nullptr; 151 } 152 153 template <typename T, bool kIsWeak> 154 BaseObject::PointerData* 155 BaseObjectPtrImpl<T, kIsWeak>::pointer_data() const { 156 if constexpr (kIsWeak) { 157 return data_.pointer_data; 158 } 159 if (get_base_object() == nullptr) { 160 return nullptr; 161 } 162 return get_base_object()->pointer_data(); 163 } 164 165 template <typename T, bool kIsWeak> 166 BaseObject* BaseObjectPtrImpl<T, kIsWeak>::get_base_object() const { 167 if constexpr (kIsWeak) { 168 if (pointer_data() == nullptr) { 169 return nullptr; 170 } 171 return pointer_data()->self; 172 } 173 return data_.target; 174 } 175 176 template <typename T, bool kIsWeak> 177 BaseObjectPtrImpl<T, kIsWeak>::~BaseObjectPtrImpl() { 178 if constexpr (kIsWeak) { 179 if (pointer_data() != nullptr && 180 --pointer_data()->weak_ptr_count == 0 && 181 pointer_data()->self == nullptr) { 182 delete pointer_data(); 183 } 184 } else if (get() != nullptr) { 185 get()->decrease_refcount(); 186 } 187 } 188 189 template <typename T, bool kIsWeak> 190 BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl() { 191 data_.target = nullptr; 192 } 193 194 template <typename T, bool kIsWeak> 195 BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(T* target) 196 : BaseObjectPtrImpl() { 197 if (target == nullptr) return; 198 if constexpr (kIsWeak) { 199 data_.pointer_data = target->pointer_data(); 200 CHECK_NOT_NULL(pointer_data()); 201 pointer_data()->weak_ptr_count++; 202 } else { 203 data_.target = target; 204 CHECK_NOT_NULL(pointer_data()); 205 get()->increase_refcount(); 206 } 207 } 208 209 template <typename T, bool kIsWeak> 210 template <typename U, bool kW> 211 BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl( 212 const BaseObjectPtrImpl<U, kW>& other) 213 : BaseObjectPtrImpl(other.get()) {} 214 215 template <typename T, bool kIsWeak> 216 BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(const BaseObjectPtrImpl& other) 217 : BaseObjectPtrImpl(other.get()) {} 218 219 template <typename T, bool kIsWeak> 220 template <typename U, bool kW> 221 BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=( 222 const BaseObjectPtrImpl<U, kW>& other) { 223 if (other.get() == get()) return *this; 224 this->~BaseObjectPtrImpl(); 225 return *new (this) BaseObjectPtrImpl(other); 226 } 227 228 template <typename T, bool kIsWeak> 229 BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=( 230 const BaseObjectPtrImpl& other) { 231 if (other.get() == get()) return *this; 232 this->~BaseObjectPtrImpl(); 233 return *new (this) BaseObjectPtrImpl(other); 234 } 235 236 template <typename T, bool kIsWeak> 237 BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(BaseObjectPtrImpl&& other) 238 : data_(other.data_) { 239 if constexpr (kIsWeak) 240 other.data_.target = nullptr; 241 else 242 other.data_.pointer_data = nullptr; 243 } 244 245 template <typename T, bool kIsWeak> 246 BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=( 247 BaseObjectPtrImpl&& other) { 248 if (&other == this) return *this; 249 this->~BaseObjectPtrImpl(); 250 return *new (this) BaseObjectPtrImpl(std::move(other)); 251 } 252 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 264 template <typename T, bool kIsWeak> 265 void BaseObjectPtrImpl<T, kIsWeak>::reset(T* ptr) { 266 *this = BaseObjectPtrImpl(ptr); 267 } 268 269 template <typename T, bool kIsWeak> 270 T* BaseObjectPtrImpl<T, kIsWeak>::get() const { 271 return static_cast<T*>(get_base_object()); 272 } 273 274 template <typename T, bool kIsWeak> 275 T& BaseObjectPtrImpl<T, kIsWeak>::operator*() const { 276 return *get(); 277 } 278 279 template <typename T, bool kIsWeak> 280 T* BaseObjectPtrImpl<T, kIsWeak>::operator->() const { 281 return get(); 282 } 283 284 template <typename T, bool kIsWeak> 285 BaseObjectPtrImpl<T, kIsWeak>::operator bool() const { 286 return get() != nullptr; 287 } 288 289 template <typename T, bool kIsWeak> 290 template <typename U, bool kW> 291 bool BaseObjectPtrImpl<T, kIsWeak>::operator ==( 292 const BaseObjectPtrImpl<U, kW>& other) const { 293 return get() == other.get(); 294 } 295 296 template <typename T, bool kIsWeak> 297 template <typename U, bool kW> 298 bool BaseObjectPtrImpl<T, kIsWeak>::operator !=( 299 const BaseObjectPtrImpl<U, kW>& other) const { 300 return get() != other.get(); 301 } 302 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 313 template <typename T, typename... Args> 314 BaseObjectPtr<T> MakeBaseObject(Args&&... args) { 315 return BaseObjectPtr<T>(new T(std::forward<Args>(args)...)); 316 } 317 template <typename T, typename... Args> 318 BaseObjectWeakPtr<T> MakeWeakBaseObject(Args&&... args) { 319 T* target = new T(std::forward<Args>(args)...); 320 target->MakeWeak(); 321 return BaseObjectWeakPtr<T>(target); 322 } 323 324 template <typename T, typename... Args> 325 BaseObjectPtr<T> MakeDetachedBaseObject(Args&&... args) { 326 BaseObjectPtr<T> target = MakeBaseObject<T>(std::forward<Args>(args)...); 327 target->Detach(); 328 return target; 329 } 330 331 } // namespace node 332 333 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 334 335 #endif // SRC_BASE_OBJECT_INL_H_