| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 | /********************************************************************* * NAN - Native Abstractions for Node.js * * Copyright (c) 2018 NAN contributors * * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md> ********************************************************************/#ifndef NAN_OBJECT_WRAP_H_#define NAN_OBJECT_WRAP_H_class ObjectWrap { public:  ObjectWrap() {    refs_ = 0;  }  virtual ~ObjectWrap() {    if (persistent().IsEmpty()) {      return;    }    persistent().ClearWeak();    persistent().Reset();  }  template <class T>  static inline T* Unwrap(v8::Local<v8::Object> object) {    assert(!object.IsEmpty());    assert(object->InternalFieldCount() > 0);    // Cast to ObjectWrap before casting to T.  A direct cast from void    // to T won't work right when T has more than one base class.    void* ptr = GetInternalFieldPointer(object, 0);    ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);    return static_cast<T*>(wrap);  }  inline v8::Local<v8::Object> handle() const {    return New(handle_);  }  inline Persistent<v8::Object>& persistent() {    return handle_;  } protected:  inline void Wrap(v8::Local<v8::Object> object) {    assert(persistent().IsEmpty());    assert(object->InternalFieldCount() > 0);    SetInternalFieldPointer(object, 0, this);    persistent().Reset(object);    MakeWeak();  }#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))  inline void MakeWeak() {    persistent().v8::PersistentBase<v8::Object>::SetWeak(        this, WeakCallback, v8::WeakCallbackType::kParameter);#if NODE_MAJOR_VERSION < 10    // FIXME(bnoordhuis) Probably superfluous in older Node.js versions too.    persistent().MarkIndependent();#endif  }#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION  inline void MakeWeak() {    persistent().v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback);    persistent().MarkIndependent();  }#else  inline void MakeWeak() {    persistent().persistent.MakeWeak(this, WeakCallback);    persistent().MarkIndependent();  }#endif  /* Ref() marks the object as being attached to an event loop.   * Refed objects will not be garbage collected, even if   * all references are lost.   */  virtual void Ref() {    assert(!persistent().IsEmpty());    persistent().ClearWeak();    refs_++;  }  /* Unref() marks an object as detached from the event loop.  This is its   * default state.  When an object with a "weak" reference changes from   * attached to detached state it will be freed. Be careful not to access   * the object after making this call as it might be gone!   * (A "weak reference" means an object that only has a   * persistent handle.)   *   * DO NOT CALL THIS FROM DESTRUCTOR   */  virtual void Unref() {    assert(!persistent().IsEmpty());    assert(!persistent().IsWeak());    assert(refs_ > 0);    if (--refs_ == 0)      MakeWeak();  }  int refs_;  // ro private:  NAN_DISALLOW_ASSIGN_COPY_MOVE(ObjectWrap)#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))  static void  WeakCallback(v8::WeakCallbackInfo<ObjectWrap> const& info) {    ObjectWrap* wrap = info.GetParameter();    assert(wrap->refs_ == 0);    wrap->handle_.Reset();    delete wrap;  }#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION  static void  WeakCallback(v8::WeakCallbackData<v8::Object, ObjectWrap> const& data) {    ObjectWrap* wrap = data.GetParameter();    assert(wrap->refs_ == 0);    assert(wrap->handle_.IsNearDeath());    wrap->handle_.Reset();    delete wrap;  }#else  static void WeakCallback(v8::Persistent<v8::Value> value, void *data) {    ObjectWrap *wrap = static_cast<ObjectWrap*>(data);    assert(wrap->refs_ == 0);    assert(wrap->handle_.IsNearDeath());    wrap->handle_.Reset();    delete wrap;  }#endif  Persistent<v8::Object> handle_;};#endif  // NAN_OBJECT_WRAP_H_
 |