1 /** 2 * Copied from node_object_wrap.h 3 * see http://www.nodejs.org/ 4 * 5 * Node's license follows: 6 * 7 * Copyright 2009, 2010 Ryan Lienhart Dahl. All rights reserved. 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to 10 * deal in the Software without restriction, including without limitation the 11 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 * sell copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 * IN THE SOFTWARE. 25 */ 26 27 #ifndef MOCK_RIL_NODE_OBJECT_WRAP_H_ 28 #define MOCK_RIL_NODE_OBJECT_WRAP_H_ 29 30 #include <v8.h> 31 #include <assert.h> 32 33 class ObjectWrap { 34 public: 35 ObjectWrap ( ) { 36 refs_ = 0; 37 } 38 39 virtual ~ObjectWrap ( ) { 40 if (!handle_.IsEmpty()) { 41 assert(handle_.IsNearDeath()); 42 handle_->SetInternalField(0, v8::Undefined()); 43 handle_.Dispose(); 44 handle_.Clear(); 45 } 46 } 47 48 template <class T> 49 static inline T* Unwrap (v8::Handle<v8::Object> handle) 50 { 51 assert(!handle.IsEmpty()); 52 assert(handle->InternalFieldCount() > 0); 53 return static_cast<T*>(v8::Handle<v8::External>::Cast( 54 handle->GetInternalField(0))->Value()); 55 } 56 57 v8::Persistent<v8::Object> handle_; // ro 58 59 protected: 60 inline void Wrap (v8::Handle<v8::Object> handle) 61 { 62 assert(handle_.IsEmpty()); 63 assert(handle->InternalFieldCount() > 0); 64 handle_ = v8::Persistent<v8::Object>::New(handle); 65 handle_->SetInternalField(0, v8::External::New(this)); 66 MakeWeak(); 67 } 68 69 inline void MakeWeak (void) 70 { 71 handle_.MakeWeak(this, WeakCallback); 72 } 73 74 /* Ref() marks the object as being attached to an event loop. 75 * Refed objects will not be garbage collected, even if 76 * all references are lost. 77 */ 78 virtual void Ref() { 79 assert(!handle_.IsEmpty()); 80 refs_++; 81 handle_.ClearWeak(); 82 } 83 84 /* Unref() marks an object as detached from the event loop. This is its 85 * default state. When an object with a "weak" reference changes from 86 * attached to detached state it will be freed. Be careful not to access 87 * the object after making this call as it might be gone! 88 * (A "weak reference" means an object that only has a 89 * persistant handle.) 90 * 91 * DO NOT CALL THIS FROM DESTRUCTOR 92 */ 93 virtual void Unref() { 94 assert(!handle_.IsEmpty()); 95 assert(!handle_.IsWeak()); 96 assert(refs_ > 0); 97 if (--refs_ == 0) { MakeWeak(); } 98 } 99 100 int refs_; // ro 101 102 private: 103 static void WeakCallback (v8::Persistent<v8::Value> value, void *data) 104 { 105 ObjectWrap *obj = static_cast<ObjectWrap*>(data); 106 assert(value == obj->handle_); 107 assert(!obj->refs_); 108 if (value.IsNearDeath()) delete obj; 109 } 110 }; 111 112 #endif // MOCK_RIL_NODE_OBJECT_WRAP_H_ 113