1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef GIN_HANDLE_H_ 6 #define GIN_HANDLE_H_ 7 8 #include "gin/converter.h" 9 10 namespace gin { 11 12 // You can use gin::Handle on the stack to retain a gin::Wrappable object. 13 // Currently we don't have a mechanism for retaining a gin::Wrappable object 14 // in the C++ heap because strong references from C++ to V8 can cause memory 15 // leaks. 16 template<typename T> 17 class Handle { 18 public: Handle()19 Handle() : object_(NULL) {} 20 Handle(v8::Handle<v8::Value> wrapper,T * object)21 Handle(v8::Handle<v8::Value> wrapper, T* object) 22 : wrapper_(wrapper), 23 object_(object) { 24 } 25 IsEmpty()26 bool IsEmpty() const { return !object_; } 27 Clear()28 void Clear() { 29 wrapper_.Clear(); 30 object_ = NULL; 31 } 32 33 T* operator->() const { return object_; } ToV8()34 v8::Handle<v8::Value> ToV8() const { return wrapper_; } get()35 T* get() const { return object_; } 36 37 private: 38 v8::Handle<v8::Value> wrapper_; 39 T* object_; 40 }; 41 42 template<typename T> 43 struct Converter<gin::Handle<T> > { 44 static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, 45 const gin::Handle<T>& val) { 46 return val.ToV8(); 47 } 48 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, 49 gin::Handle<T>* out) { 50 T* object = NULL; 51 if (!Converter<T*>::FromV8(isolate, val, &object)) { 52 return false; 53 } 54 *out = gin::Handle<T>(val, object); 55 return true; 56 } 57 }; 58 59 // This function is a convenient way to create a handle from a raw pointer 60 // without having to write out the type of the object explicitly. 61 template<typename T> 62 gin::Handle<T> CreateHandle(v8::Isolate* isolate, T* object) { 63 v8::Handle<v8::Object> wrapper = object->GetWrapper(isolate); 64 if (wrapper.IsEmpty()) 65 return gin::Handle<T>(); 66 return gin::Handle<T>(wrapper, object); 67 } 68 69 } // namespace gin 70 71 #endif // GIN_HANDLE_H_ 72