|  | // Copyright 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef GIN_HANDLE_H_ | 
|  | #define GIN_HANDLE_H_ | 
|  |  | 
|  | #include "gin/converter.h" | 
|  |  | 
|  | namespace gin { | 
|  |  | 
|  | // You can use gin::Handle on the stack to retain a gin::Wrappable object. | 
|  | // Currently we don't have a mechanism for retaining a gin::Wrappable object | 
|  | // in the C++ heap because strong references from C++ to V8 can cause memory | 
|  | // leaks. | 
|  | template<typename T> | 
|  | class Handle { | 
|  | public: | 
|  | Handle() : object_(NULL) {} | 
|  |  | 
|  | Handle(v8::Handle<v8::Value> wrapper, T* object) | 
|  | : wrapper_(wrapper), | 
|  | object_(object) { | 
|  | } | 
|  |  | 
|  | bool IsEmpty() const { return !object_; } | 
|  |  | 
|  | void Clear() { | 
|  | wrapper_.Clear(); | 
|  | object_ = NULL; | 
|  | } | 
|  |  | 
|  | T* operator->() const { return object_; } | 
|  | v8::Handle<v8::Value> ToV8() const { return wrapper_; } | 
|  | T* get() const { return object_; } | 
|  |  | 
|  | private: | 
|  | v8::Handle<v8::Value> wrapper_; | 
|  | T* object_; | 
|  | }; | 
|  |  | 
|  | template<typename T> | 
|  | struct Converter<gin::Handle<T> > { | 
|  | static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, | 
|  | const gin::Handle<T>& val) { | 
|  | return val.ToV8(); | 
|  | } | 
|  | static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, | 
|  | gin::Handle<T>* out) { | 
|  | T* object = NULL; | 
|  | if (!Converter<T*>::FromV8(isolate, val, &object)) { | 
|  | return false; | 
|  | } | 
|  | *out = gin::Handle<T>(val, object); | 
|  | return true; | 
|  | } | 
|  | }; | 
|  |  | 
|  | // This function is a convenient way to create a handle from a raw pointer | 
|  | // without having to write out the type of the object explicitly. | 
|  | template<typename T> | 
|  | gin::Handle<T> CreateHandle(v8::Isolate* isolate, T* object) { | 
|  | v8::Handle<v8::Object> wrapper = object->GetWrapper(isolate); | 
|  | if (wrapper.IsEmpty()) | 
|  | return gin::Handle<T>(); | 
|  | return gin::Handle<T>(wrapper, object); | 
|  | } | 
|  |  | 
|  | }  // namespace gin | 
|  |  | 
|  | #endif  // GIN_HANDLE_H_ |