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.
		
		
		
		
		
			
		
			
				
					
					
						
							242 lines
						
					
					
						
							6.0 KiB
						
					
					
				
			
		
		
	
	
							242 lines
						
					
					
						
							6.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_PERSISTENT_PRE_12_INL_H_ | 
						|
#define NAN_PERSISTENT_PRE_12_INL_H_ | 
						|
 | 
						|
template<typename T> | 
						|
class PersistentBase { | 
						|
  v8::Persistent<T> persistent; | 
						|
  template<typename U> | 
						|
  friend v8::Local<U> New(const PersistentBase<U> &p); | 
						|
  template<typename U, typename M> | 
						|
  friend v8::Local<U> New(const Persistent<U, M> &p); | 
						|
  template<typename U> | 
						|
  friend v8::Local<U> New(const Global<U> &p); | 
						|
  template<typename S> friend class ReturnValue; | 
						|
 | 
						|
 public: | 
						|
  inline PersistentBase() : | 
						|
      persistent() {} | 
						|
 | 
						|
  inline void Reset() { | 
						|
    persistent.Dispose(); | 
						|
    persistent.Clear(); | 
						|
  } | 
						|
 | 
						|
  template<typename S> | 
						|
  inline void Reset(const v8::Local<S> &other) { | 
						|
    TYPE_CHECK(T, S); | 
						|
 | 
						|
    if (!persistent.IsEmpty()) { | 
						|
      persistent.Dispose(); | 
						|
    } | 
						|
 | 
						|
    if (other.IsEmpty()) { | 
						|
      persistent.Clear(); | 
						|
    } else { | 
						|
      persistent = v8::Persistent<T>::New(other); | 
						|
    } | 
						|
  } | 
						|
 | 
						|
  template<typename S> | 
						|
  inline void Reset(const PersistentBase<S> &other) { | 
						|
    TYPE_CHECK(T, S); | 
						|
 | 
						|
    if (!persistent.IsEmpty()) { | 
						|
      persistent.Dispose(); | 
						|
    } | 
						|
 | 
						|
    if (other.IsEmpty()) { | 
						|
      persistent.Clear(); | 
						|
    } else { | 
						|
      persistent = v8::Persistent<T>::New(other.persistent); | 
						|
    } | 
						|
  } | 
						|
 | 
						|
  inline bool IsEmpty() const { return persistent.IsEmpty(); } | 
						|
 | 
						|
  inline void Empty() { persistent.Clear(); } | 
						|
 | 
						|
  template<typename S> | 
						|
  inline bool operator==(const PersistentBase<S> &that) const { | 
						|
    return this->persistent == that.persistent; | 
						|
  } | 
						|
 | 
						|
  template<typename S> | 
						|
  inline bool operator==(const v8::Local<S> &that) const { | 
						|
    return this->persistent == that; | 
						|
  } | 
						|
 | 
						|
  template<typename S> | 
						|
  inline bool operator!=(const PersistentBase<S> &that) const { | 
						|
    return !operator==(that); | 
						|
  } | 
						|
 | 
						|
  template<typename S> | 
						|
  inline bool operator!=(const v8::Local<S> &that) const { | 
						|
    return !operator==(that); | 
						|
  } | 
						|
 | 
						|
  template<typename P> | 
						|
  inline void SetWeak( | 
						|
    P *parameter | 
						|
    , typename WeakCallbackInfo<P>::Callback callback | 
						|
    , WeakCallbackType type); | 
						|
 | 
						|
  inline void ClearWeak() { persistent.ClearWeak(); } | 
						|
 | 
						|
  inline void MarkIndependent() { persistent.MarkIndependent(); } | 
						|
 | 
						|
  inline bool IsIndependent() const { return persistent.IsIndependent(); } | 
						|
 | 
						|
  inline bool IsNearDeath() const { return persistent.IsNearDeath(); } | 
						|
 | 
						|
  inline bool IsWeak() const { return persistent.IsWeak(); } | 
						|
 | 
						|
 private: | 
						|
  inline explicit PersistentBase(v8::Persistent<T> that) : | 
						|
      persistent(that) { } | 
						|
  inline explicit PersistentBase(T *val) : persistent(val) {} | 
						|
  template<typename S, typename M> friend class Persistent; | 
						|
  template<typename S> friend class Global; | 
						|
  friend class ObjectWrap; | 
						|
}; | 
						|
 | 
						|
template<typename T> | 
						|
class NonCopyablePersistentTraits { | 
						|
 public: | 
						|
  typedef Persistent<T, NonCopyablePersistentTraits<T> > | 
						|
      NonCopyablePersistent; | 
						|
  static const bool kResetInDestructor = false; | 
						|
  template<typename S, typename M> | 
						|
  inline static void Copy(const Persistent<S, M> &source, | 
						|
                             NonCopyablePersistent *dest) { | 
						|
    Uncompilable<v8::Object>(); | 
						|
  } | 
						|
 | 
						|
  template<typename O> inline static void Uncompilable() { | 
						|
    TYPE_CHECK(O, v8::Primitive); | 
						|
  } | 
						|
}; | 
						|
 | 
						|
template<typename T> | 
						|
struct CopyablePersistentTraits { | 
						|
  typedef Persistent<T, CopyablePersistentTraits<T> > CopyablePersistent; | 
						|
  static const bool kResetInDestructor = true; | 
						|
  template<typename S, typename M> | 
						|
  static inline void Copy(const Persistent<S, M> &source, | 
						|
                             CopyablePersistent *dest) {} | 
						|
}; | 
						|
 | 
						|
template<typename T, typename M> class Persistent : | 
						|
    public PersistentBase<T> { | 
						|
 public: | 
						|
  inline Persistent() {} | 
						|
 | 
						|
  template<typename S> inline Persistent(v8::Handle<S> that) | 
						|
      : PersistentBase<T>(v8::Persistent<T>::New(that)) { | 
						|
    TYPE_CHECK(T, S); | 
						|
  } | 
						|
 | 
						|
  inline Persistent(const Persistent &that) : PersistentBase<T>() { | 
						|
    Copy(that); | 
						|
  } | 
						|
 | 
						|
  template<typename S, typename M2> | 
						|
  inline Persistent(const Persistent<S, M2> &that) : | 
						|
      PersistentBase<T>() { | 
						|
    Copy(that); | 
						|
  } | 
						|
 | 
						|
  inline Persistent &operator=(const Persistent &that) { | 
						|
    Copy(that); | 
						|
    return *this; | 
						|
  } | 
						|
 | 
						|
  template <class S, class M2> | 
						|
  inline Persistent &operator=(const Persistent<S, M2> &that) { | 
						|
    Copy(that); | 
						|
    return *this; | 
						|
  } | 
						|
 | 
						|
  inline ~Persistent() { | 
						|
    if (M::kResetInDestructor) this->Reset(); | 
						|
  } | 
						|
 | 
						|
 private: | 
						|
  inline T *operator*() const { return *PersistentBase<T>::persistent; } | 
						|
 | 
						|
  template<typename S, typename M2> | 
						|
  inline void Copy(const Persistent<S, M2> &that) { | 
						|
    TYPE_CHECK(T, S); | 
						|
 | 
						|
    this->Reset(); | 
						|
 | 
						|
    if (!that.IsEmpty()) { | 
						|
      this->persistent = v8::Persistent<T>::New(that.persistent); | 
						|
      M::Copy(that, this); | 
						|
    } | 
						|
  } | 
						|
}; | 
						|
 | 
						|
template<typename T> | 
						|
class Global : public PersistentBase<T> { | 
						|
  struct RValue { | 
						|
    inline explicit RValue(Global* obj) : object(obj) {} | 
						|
    Global* object; | 
						|
  }; | 
						|
 | 
						|
 public: | 
						|
  inline Global() : PersistentBase<T>(0) { } | 
						|
 | 
						|
  template <typename S> | 
						|
  inline Global(v8::Local<S> that)  // NOLINT(runtime/explicit) | 
						|
      : PersistentBase<T>(v8::Persistent<T>::New(that)) { | 
						|
    TYPE_CHECK(T, S); | 
						|
  } | 
						|
 | 
						|
  template <typename S> | 
						|
  inline Global(const PersistentBase<S> &that)  // NOLINT(runtime/explicit) | 
						|
    : PersistentBase<T>(that) { | 
						|
    TYPE_CHECK(T, S); | 
						|
  } | 
						|
  /** | 
						|
   * Move constructor. | 
						|
   */ | 
						|
  inline Global(RValue rvalue)  // NOLINT(runtime/explicit) | 
						|
    : PersistentBase<T>(rvalue.object->persistent) { | 
						|
    rvalue.object->Reset(); | 
						|
  } | 
						|
  inline ~Global() { this->Reset(); } | 
						|
  /** | 
						|
   * Move via assignment. | 
						|
   */ | 
						|
  template<typename S> | 
						|
  inline Global &operator=(Global<S> rhs) { | 
						|
    TYPE_CHECK(T, S); | 
						|
    this->Reset(rhs.persistent); | 
						|
    rhs.Reset(); | 
						|
    return *this; | 
						|
  } | 
						|
  /** | 
						|
   * Cast operator for moves. | 
						|
   */ | 
						|
  inline operator RValue() { return RValue(this); } | 
						|
  /** | 
						|
   * Pass allows returning uniques from functions, etc. | 
						|
   */ | 
						|
  Global Pass() { return Global(RValue(this)); } | 
						|
 | 
						|
 private: | 
						|
  Global(Global &); | 
						|
  void operator=(Global &); | 
						|
  template<typename S> friend class ReturnValue; | 
						|
}; | 
						|
 | 
						|
#endif  // NAN_PERSISTENT_PRE_12_INL_H_
 | 
						|
 |