Home | History | Annotate | Download | only in v8
      1 /*
      2  * Copyright (C) 2013 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #ifndef UnsafePersistent_h
     32 #define UnsafePersistent_h
     33 
     34 #include "bindings/v8/WrapperTypeInfo.h"
     35 
     36 #include <v8.h>
     37 
     38 namespace WebCore {
     39 
     40 template<class KeyType> class DOMWrapperMap;
     41 
     42 // An unsafe way to pass Persistent handles around. Do not use unless you know
     43 // what you're doing. UnsafePersistent is only safe to use when we know that the
     44 // memory pointed by the it is not going away: 1) When GC cannot happen while
     45 // the UnsafePersistent is alive or 2) when there is a strong Persistent keeping
     46 // the memory alive while the UnsafePersistent is alive.
     47 template<typename T> class UnsafePersistent {
     48 public:
     49     UnsafePersistent() : m_value(0) { }
     50     explicit UnsafePersistent(T* value) : m_value(value) { }
     51     explicit UnsafePersistent(v8::Persistent<T>& handle)
     52     {
     53         m_value = handle.ClearAndLeak();
     54     }
     55 
     56     UnsafePersistent(v8::Isolate* isolate, v8::Handle<T>& handle)
     57     {
     58         v8::Persistent<T> persistent(isolate, handle);
     59         m_value = persistent.ClearAndLeak();
     60     }
     61 
     62     T* value() const
     63     {
     64         return m_value;
     65     }
     66 
     67     template<typename V8T, typename U>
     68     inline bool setReturnValueWithSecurityCheck(v8::ReturnValue<v8::Value> returnValue, U* object)
     69     {
     70         v8::Handle<v8::Object> result = deprecatedHandle();
     71         // Security: always guard against malicious tampering.
     72         RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.IsEmpty() || result->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(object));
     73         returnValue.Set(result);
     74         return !result.IsEmpty();
     75     }
     76 
     77     inline bool setReturnValue(v8::ReturnValue<v8::Value> returnValue)
     78     {
     79         returnValue.Set(deprecatedHandle());
     80         return !isEmpty();
     81     }
     82 
     83     // This is incredibly unsafe: the handle is valid only when this
     84     // UnsafePersistent is alive and valid (see class level comment).
     85     v8::Persistent<T>* persistent()
     86     {
     87         v8::Persistent<T>* handle = reinterpret_cast<v8::Persistent<T>*>(&m_value);
     88         return handle;
     89     }
     90 
     91     void setReferenceFrom(const v8::Persistent<v8::Object>& parent, v8::Isolate* isolate)
     92     {
     93         isolate->SetReference(parent, *persistent());
     94     }
     95 
     96     void dispose()
     97     {
     98         persistent()->Reset();
     99         m_value = 0;
    100     }
    101 
    102     void clear()
    103     {
    104         m_value = 0;
    105     }
    106 
    107     v8::Local<T> newLocal(v8::Isolate* isolate)
    108     {
    109         return v8::Local<T>::New(isolate, *persistent());
    110     }
    111 
    112     bool isEmpty() const
    113     {
    114         return !m_value;
    115     }
    116 
    117 private:
    118     v8::Handle<T> deprecatedHandle()
    119     {
    120         v8::Handle<T>* handle = reinterpret_cast<v8::Handle<T>*>(&m_value);
    121         return *handle;
    122     }
    123 
    124     T* m_value;
    125 };
    126 
    127 } // namespace WebCore
    128 
    129 #endif // UnsafePersistent_h
    130