// 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_