Subversion Repositories qbpwcf-lib(archive)

Rev

Rev 915 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 liveuser 1
/*********************************************************************
2
 * NAN - Native Abstractions for Node.js
3
 *
4
 * Copyright (c) 2016 NAN contributors
5
 *
6
 * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
7
 ********************************************************************/
8
 
9
#ifndef NAN_OBJECT_WRAP_H_
10
#define NAN_OBJECT_WRAP_H_
11
 
12
class ObjectWrap {
13
 public:
14
  ObjectWrap() {
15
    refs_ = 0;
16
  }
17
 
18
 
19
  virtual ~ObjectWrap() {
20
    if (persistent().IsEmpty()) {
21
      return;
22
    }
23
 
24
    assert(persistent().IsNearDeath());
25
    persistent().ClearWeak();
26
    persistent().Reset();
27
  }
28
 
29
 
30
  template <class T>
31
  static inline T* Unwrap(v8::Local<v8::Object> object) {
32
    assert(!object.IsEmpty());
33
    assert(object->InternalFieldCount() > 0);
34
    // Cast to ObjectWrap before casting to T.  A direct cast from void
35
    // to T won't work right when T has more than one base class.
36
    void* ptr = GetInternalFieldPointer(object, 0);
37
    ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
38
    return static_cast<T*>(wrap);
39
  }
40
 
41
 
42
  inline v8::Local<v8::Object> handle() const {
43
    return New(handle_);
44
  }
45
 
46
 
47
  inline Persistent<v8::Object>& persistent() {
48
    return handle_;
49
  }
50
 
51
 
52
 protected:
53
  inline void Wrap(v8::Local<v8::Object> object) {
54
    assert(persistent().IsEmpty());
55
    assert(object->InternalFieldCount() > 0);
56
    SetInternalFieldPointer(object, 0, this);
57
    persistent().Reset(object);
58
    MakeWeak();
59
  }
60
 
61
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
62
  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
63
 
64
  inline void MakeWeak() {
65
    persistent().v8::PersistentBase<v8::Object>::SetWeak(
66
        this, WeakCallback, v8::WeakCallbackType::kParameter);
67
    persistent().MarkIndependent();
68
  }
69
 
70
#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
71
 
72
  inline void MakeWeak() {
73
    persistent().v8::PersistentBase<v8::Object>::SetWeak(this, WeakCallback);
74
    persistent().MarkIndependent();
75
  }
76
 
77
#else
78
 
79
  inline void MakeWeak() {
80
    persistent().persistent.MakeWeak(this, WeakCallback);
81
    persistent().MarkIndependent();
82
  }
83
 
84
#endif
85
 
86
  /* Ref() marks the object as being attached to an event loop.
87
   * Refed objects will not be garbage collected, even if
88
   * all references are lost.
89
   */
90
  virtual void Ref() {
91
    assert(!persistent().IsEmpty());
92
    persistent().ClearWeak();
93
    refs_++;
94
  }
95
 
96
  /* Unref() marks an object as detached from the event loop.  This is its
97
   * default state.  When an object with a "weak" reference changes from
98
   * attached to detached state it will be freed. Be careful not to access
99
   * the object after making this call as it might be gone!
100
   * (A "weak reference" means an object that only has a
101
   * persistant handle.)
102
   *
103
   * DO NOT CALL THIS FROM DESTRUCTOR
104
   */
105
  virtual void Unref() {
106
    assert(!persistent().IsEmpty());
107
    assert(!persistent().IsWeak());
108
    assert(refs_ > 0);
109
    if (--refs_ == 0)
110
      MakeWeak();
111
  }
112
 
113
  int refs_;  // ro
114
 
115
 private:
116
  NAN_DISALLOW_ASSIGN_COPY_MOVE(ObjectWrap)
117
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
118
  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
119
 
120
  static void
121
  WeakCallback(v8::WeakCallbackInfo<ObjectWrap> const& info) {
122
    ObjectWrap* wrap = info.GetParameter();
123
    assert(wrap->refs_ == 0);
124
    assert(wrap->handle_.IsNearDeath());
125
    wrap->handle_.Reset();
126
    delete wrap;
127
  }
128
 
129
#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
130
 
131
  static void
132
  WeakCallback(v8::WeakCallbackData<v8::Object, ObjectWrap> const& data) {
133
    ObjectWrap* wrap = data.GetParameter();
134
    assert(wrap->refs_ == 0);
135
    assert(wrap->handle_.IsNearDeath());
136
    wrap->handle_.Reset();
137
    delete wrap;
138
  }
139
 
140
#else
141
 
142
  static void WeakCallback(v8::Persistent<v8::Value> value, void *data) {
143
    ObjectWrap *wrap = static_cast<ObjectWrap*>(data);
144
    assert(wrap->refs_ == 0);
145
    assert(wrap->handle_.IsNearDeath());
146
    wrap->handle_.Reset();
147
    delete wrap;
148
  }
149
 
150
#endif
151
  Persistent<v8::Object> handle_;
152
};
153
 
154
 
155
#endif  // NAN_OBJECT_WRAP_H_