You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							156 lines
						
					
					
						
							4.0 KiB
						
					
					
				
			
		
		
	
	
							156 lines
						
					
					
						
							4.0 KiB
						
					
					
				/********************************************************************* | 
						|
 * 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_
 | 
						|
 |