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     if (handle_.IsEmpty())
     38       return;
     39     handle_.Dispose();
     40     handle_.Clear();
     41   }
     42 
     43   v8::Handle<T> operator->() const {
     44     return get();
     45   }
     46 
     47   // TODO(dcarney): Remove this function
     48   // This is an unsafe access to the underlying handle
     49   v8::Handle<T> get() const {
     50     return *reinterpret_cast<v8::Handle<T>*>(
     51       const_cast<v8::Persistent<T>* >(&handle_));
     52   }
     53 
     54   v8::Handle<T> NewHandle() const {
     55     if (handle_.IsEmpty())
     56       return v8::Local<T>();
     57     return v8::Local<T>::New(GetIsolate(handle_), handle_);
     58   }
     59 
     60   template<typename P>
     61   void MakeWeak(P* parameters,
     62                 typename v8::WeakReferenceCallbacks<T, P>::Revivable callback) {
     63     handle_.MakeWeak(parameters, callback);
     64   }
     65 
     66  private:
     67   template <typename U>
     68   static v8::Isolate* GetIsolate(v8::Handle<U> object_handle) {
     69     // Only works for v8::Object and its subclasses. Add specialisations for
     70     // anything else.
     71     if (!object_handle.IsEmpty())
     72       return GetIsolate(object_handle->CreationContext());
     73     return v8::Isolate::GetCurrent();
     74   }
     75   static v8::Isolate* GetIsolate(v8::Handle<v8::Context> context_handle) {
     76     if (!context_handle.IsEmpty())
     77       return context_handle->GetIsolate();
     78     return v8::Isolate::GetCurrent();
     79   }
     80   static v8::Isolate* GetIsolate(
     81       v8::Handle<v8::ObjectTemplate> template_handle) {
     82     return v8::Isolate::GetCurrent();
     83   }
     84 
     85   v8::Persistent<T> handle_;
     86 
     87   DISALLOW_COPY_AND_ASSIGN(ScopedPersistent);
     88 };
     89 
     90 }  // namespace extensions
     91 
     92 #endif  // CHROME_RENDERER_EXTENSIONS_SCOPED_PERSISTENT_H_
     93