Home | History | Annotate | Download | only in extensions
      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 CHROME_RENDERER_EXTENSIONS_SCOPED_PERSISTENT_H_
      6 #define CHROME_RENDERER_EXTENSIONS_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:
     18   ScopedPersistent() {
     19   }
     20 
     21   explicit ScopedPersistent(v8::Handle<T> handle) {
     22     reset(handle);
     23   }
     24 
     25   ~ScopedPersistent() {
     26     reset();
     27   }
     28 
     29   void reset(v8::Handle<T> handle) {
     30     if (!handle.IsEmpty())
     31       handle_.Reset(GetIsolate(handle), handle);
     32     else
     33       reset();
     34   }
     35 
     36   void reset() {
     37     handle_.Reset();
     38   }
     39 
     40   bool IsEmpty() const {
     41     return handle_.IsEmpty();
     42   }
     43 
     44   v8::Handle<T> NewHandle() const {
     45     if (handle_.IsEmpty())
     46       return v8::Local<T>();
     47     return v8::Local<T>::New(GetIsolate(handle_), handle_);
     48   }
     49 
     50   v8::Handle<T> NewHandle(v8::Isolate* isolate) const {
     51     if (handle_.IsEmpty())
     52       return v8::Local<T>();
     53     return v8::Local<T>::New(isolate, handle_);
     54   }
     55 
     56   template <typename P>
     57   void SetWeak(P* parameters,
     58                typename v8::WeakCallbackData<T, P>::Callback callback) {
     59     handle_.SetWeak(parameters, callback);
     60   }
     61 
     62  private:
     63   template <typename U>
     64   static v8::Isolate* GetIsolate(v8::Handle<U> object_handle) {
     65     // Only works for v8::Object and its subclasses. Add specialisations for
     66     // anything else.
     67     if (!object_handle.IsEmpty())
     68       return GetIsolate(object_handle->CreationContext());
     69     return v8::Isolate::GetCurrent();
     70   }
     71   static v8::Isolate* GetIsolate(v8::Handle<v8::Context> context_handle) {
     72     if (!context_handle.IsEmpty())
     73       return context_handle->GetIsolate();
     74     return v8::Isolate::GetCurrent();
     75   }
     76   static v8::Isolate* GetIsolate(
     77       v8::Handle<v8::ObjectTemplate> template_handle) {
     78     return v8::Isolate::GetCurrent();
     79   }
     80 
     81   v8::Persistent<T> handle_;
     82 
     83   DISALLOW_COPY_AND_ASSIGN(ScopedPersistent);
     84 };
     85 
     86 }  // namespace extensions
     87 
     88 #endif  // CHROME_RENDERER_EXTENSIONS_SCOPED_PERSISTENT_H_
     89