1 // Copyright 2014 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 EXTENSIONS_RENDERER_SCOPED_PERSISTENT_H_ 6 #define EXTENSIONS_RENDERER_SCOPED_PERSISTENT_H_ 7 8 #include "base/logging.h" 9 #include "v8/include/v8.h" 10 11 namespace extensions { 12 13 // A v8::Persistent handle to a V8 value which destroys and clears the 14 // underlying handle on destruction. 15 template <typename T> 16 class ScopedPersistent { 17 public: ScopedPersistent()18 ScopedPersistent() {} 19 ScopedPersistent(v8::Handle<T> handle)20 explicit ScopedPersistent(v8::Handle<T> handle) { reset(handle); } 21 ~ScopedPersistent()22 ~ScopedPersistent() { reset(); } 23 reset(v8::Handle<T> handle)24 void reset(v8::Handle<T> handle) { 25 if (!handle.IsEmpty()) 26 handle_.Reset(GetIsolate(handle), handle); 27 else 28 reset(); 29 } 30 reset()31 void reset() { handle_.Reset(); } 32 IsEmpty()33 bool IsEmpty() const { return handle_.IsEmpty(); } 34 NewHandle()35 v8::Handle<T> NewHandle() const { 36 if (handle_.IsEmpty()) 37 return v8::Local<T>(); 38 return v8::Local<T>::New(GetIsolate(handle_), handle_); 39 } 40 NewHandle(v8::Isolate * isolate)41 v8::Handle<T> NewHandle(v8::Isolate* isolate) const { 42 if (handle_.IsEmpty()) 43 return v8::Local<T>(); 44 return v8::Local<T>::New(isolate, handle_); 45 } 46 47 template <typename P> SetWeak(P * parameters,typename v8::WeakCallbackData<T,P>::Callback callback)48 void SetWeak(P* parameters, 49 typename v8::WeakCallbackData<T, P>::Callback callback) { 50 handle_.SetWeak(parameters, callback); 51 } 52 53 private: 54 template <typename U> GetIsolate(v8::Handle<U> object_handle)55 static v8::Isolate* GetIsolate(v8::Handle<U> object_handle) { 56 // Only works for v8::Object and its subclasses. Add specialisations for 57 // anything else. 58 if (!object_handle.IsEmpty()) 59 return GetIsolate(object_handle->CreationContext()); 60 return v8::Isolate::GetCurrent(); 61 } GetIsolate(v8::Handle<v8::Context> context_handle)62 static v8::Isolate* GetIsolate(v8::Handle<v8::Context> context_handle) { 63 if (!context_handle.IsEmpty()) 64 return context_handle->GetIsolate(); 65 return v8::Isolate::GetCurrent(); 66 } GetIsolate(v8::Handle<v8::ObjectTemplate> template_handle)67 static v8::Isolate* GetIsolate( 68 v8::Handle<v8::ObjectTemplate> template_handle) { 69 return v8::Isolate::GetCurrent(); 70 } 71 72 v8::Persistent<T> handle_; 73 74 DISALLOW_COPY_AND_ASSIGN(ScopedPersistent); 75 }; 76 77 } // namespace extensions 78 79 #endif // EXTENSIONS_RENDERER_SCOPED_PERSISTENT_H_ 80