Use SetPointerInInternalField
[platform/upstream/nodejs.git] / src / node_object_wrap.h
1 #ifndef object_wrap_h
2 #define object_wrap_h
3
4 #include <v8.h>
5 #include <assert.h>
6
7 namespace node {
8
9 class ObjectWrap {
10  public:
11   ObjectWrap ( ) {
12     refs_ = 0;
13   }
14
15   virtual ~ObjectWrap ( ) {
16     if (!handle_.IsEmpty()) {
17       assert(handle_.IsNearDeath());
18       handle_->SetInternalField(0, v8::Undefined());
19       handle_.Dispose();
20       handle_.Clear();
21     }
22   }
23
24   template <class T>
25   static inline T* Unwrap (v8::Handle<v8::Object> handle)
26   {
27     assert(!handle.IsEmpty());
28     assert(handle->InternalFieldCount() > 0);
29     return static_cast<T*>(handle->GetPointerFromInternalField(0));
30   }
31
32   v8::Persistent<v8::Object> handle_; // ro
33
34  protected:
35   inline void Wrap (v8::Handle<v8::Object> handle)
36   {
37     assert(handle_.IsEmpty());
38     assert(handle->InternalFieldCount() > 0);
39     handle_ = v8::Persistent<v8::Object>::New(handle);
40     handle_->SetPointerInInternalField(0, this);
41     MakeWeak();
42   }
43
44   inline void MakeWeak (void)
45   {
46     handle_.MakeWeak(this, WeakCallback);
47   }
48
49   /* Ref() marks the object as being attached to an event loop.
50    * Refed objects will not be garbage collected, even if
51    * all references are lost.
52    */
53   virtual void Ref() {
54     assert(!handle_.IsEmpty());
55     refs_++;
56     handle_.ClearWeak();
57   }
58
59   /* Unref() marks an object as detached from the event loop.  This is its
60    * default state.  When an object with a "weak" reference changes from
61    * attached to detached state it will be freed. Be careful not to access
62    * the object after making this call as it might be gone!
63    * (A "weak reference" means an object that only has a
64    * persistant handle.)
65    *
66    * DO NOT CALL THIS FROM DESTRUCTOR
67    */
68   virtual void Unref() {
69     assert(!handle_.IsEmpty());
70     assert(!handle_.IsWeak());
71     assert(refs_ > 0);
72     if (--refs_ == 0) { MakeWeak(); }
73   }
74
75   int refs_; // ro
76
77  private:
78   static void WeakCallback (v8::Persistent<v8::Value> value, void *data)
79   {
80     ObjectWrap *obj = static_cast<ObjectWrap*>(data);
81     assert(value == obj->handle_);
82     assert(!obj->refs_);
83     if (value.IsNearDeath()) delete obj;
84   }
85 };
86
87 } // namespace node
88 #endif // object_wrap_h