Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-02 09:10:09

0001 // Copyright Joyent, Inc. and other Node contributors.
0002 //
0003 // Permission is hereby granted, free of charge, to any person obtaining a
0004 // copy of this software and associated documentation files (the
0005 // "Software"), to deal in the Software without restriction, including
0006 // without limitation the rights to use, copy, modify, merge, publish,
0007 // distribute, sublicense, and/or sell copies of the Software, and to permit
0008 // persons to whom the Software is furnished to do so, subject to the
0009 // following conditions:
0010 //
0011 // The above copyright notice and this permission notice shall be included
0012 // in all copies or substantial portions of the Software.
0013 //
0014 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0015 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0016 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
0017 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
0018 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0019 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0020 // USE OR OTHER DEALINGS IN THE SOFTWARE.
0021 
0022 #ifndef SRC_NODE_OBJECT_WRAP_H_
0023 #define SRC_NODE_OBJECT_WRAP_H_
0024 
0025 #include "v8.h"
0026 #include <cassert>
0027 
0028 
0029 namespace node {
0030 
0031 class ObjectWrap {
0032  public:
0033   ObjectWrap() {
0034     refs_ = 0;
0035   }
0036 
0037 
0038   virtual ~ObjectWrap() {
0039     if (persistent().IsEmpty())
0040       return;
0041     persistent().ClearWeak();
0042     persistent().Reset();
0043   }
0044 
0045 
0046   template <class T>
0047   static inline T* Unwrap(v8::Local<v8::Object> handle) {
0048     assert(!handle.IsEmpty());
0049     assert(handle->InternalFieldCount() > 0);
0050     // Cast to ObjectWrap before casting to T.  A direct cast from void
0051     // to T won't work right when T has more than one base class.
0052     void* ptr = handle->GetAlignedPointerFromInternalField(
0053         0, v8::kEmbedderDataTypeTagDefault);
0054     ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
0055     return static_cast<T*>(wrap);
0056   }
0057 
0058 
0059   inline v8::Local<v8::Object> handle() {
0060     return handle(v8::Isolate::GetCurrent());
0061   }
0062 
0063 
0064   inline v8::Local<v8::Object> handle(v8::Isolate* isolate) {
0065     return v8::Local<v8::Object>::New(isolate, persistent());
0066   }
0067 
0068 
0069   // NOLINTNEXTLINE(runtime/v8_persistent)
0070   inline v8::Persistent<v8::Object>& persistent() {
0071     return handle_;
0072   }
0073 
0074 
0075  protected:
0076   inline void Wrap(v8::Local<v8::Object> handle) {
0077     assert(persistent().IsEmpty());
0078     assert(handle->InternalFieldCount() > 0);
0079     handle->SetAlignedPointerInInternalField(
0080         0, this, v8::kEmbedderDataTypeTagDefault);
0081     persistent().Reset(v8::Isolate::GetCurrent(), handle);
0082     MakeWeak();
0083   }
0084 
0085 
0086   inline void MakeWeak() {
0087     persistent().SetWeak(this, WeakCallback, v8::WeakCallbackType::kParameter);
0088   }
0089 
0090   /* Ref() marks the object as being attached to an event loop.
0091    * Refed objects will not be garbage collected, even if
0092    * all references are lost.
0093    */
0094   virtual void Ref() {
0095     assert(!persistent().IsEmpty());
0096     persistent().ClearWeak();
0097     refs_++;
0098   }
0099 
0100   /* Unref() marks an object as detached from the event loop.  This is its
0101    * default state.  When an object with a "weak" reference changes from
0102    * attached to detached state it will be freed. Be careful not to access
0103    * the object after making this call as it might be gone!
0104    * (A "weak reference" means an object that only has a
0105    * persistent handle.)
0106    *
0107    * DO NOT CALL THIS FROM DESTRUCTOR
0108    */
0109   virtual void Unref() {
0110     assert(!persistent().IsEmpty());
0111     assert(!persistent().IsWeak());
0112     assert(refs_ > 0);
0113     if (--refs_ == 0)
0114       MakeWeak();
0115   }
0116 
0117   int refs_;  // ro
0118 
0119  private:
0120   static void WeakCallback(
0121       const v8::WeakCallbackInfo<ObjectWrap>& data) {
0122     ObjectWrap* wrap = data.GetParameter();
0123     assert(wrap->refs_ == 0);
0124     wrap->handle_.Reset();
0125     delete wrap;
0126   }
0127 
0128   // NOLINTNEXTLINE(runtime/v8_persistent)
0129   v8::Persistent<v8::Object> handle_;
0130 };
0131 
0132 }  // namespace node
0133 
0134 #endif  // SRC_NODE_OBJECT_WRAP_H_