Home | History | Annotate | Download | only in v8
      1 /*
      2  * Copyright (C) 2009 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 DOMDataStore_h
     32 #define DOMDataStore_h
     33 
     34 #include "bindings/v8/DOMWrapperMap.h"
     35 #include "bindings/v8/DOMWrapperWorld.h"
     36 #include "bindings/v8/ScriptWrappable.h"
     37 #include "bindings/v8/WrapperTypeInfo.h"
     38 #include <v8.h>
     39 #include "wtf/Noncopyable.h"
     40 #include "wtf/StdLibExtras.h"
     41 
     42 namespace WebCore {
     43 
     44 class Node;
     45 
     46 class DOMDataStore {
     47     WTF_MAKE_NONCOPYABLE(DOMDataStore);
     48 public:
     49     explicit DOMDataStore(WrapperWorldType);
     50     ~DOMDataStore();
     51 
     52     static DOMDataStore* current(v8::Isolate*);
     53 
     54     template<typename V8T, typename T, typename CallbackInfo, typename Wrappable>
     55     static v8::Handle<v8::Object> getWrapperFast(T* object, const CallbackInfo& callbackInfo, Wrappable* holder)
     56     {
     57         // What we'd really like to check here is whether we're in the
     58         // main world or in an isolated world. The fastest way to do that
     59         // is to check that there is no isolated world and the 'object'
     60         // is an object that can exist in the main world. The second fastest
     61         // way is to check whether the wrappable's wrapper is the same as
     62         // the holder.
     63         if ((!DOMWrapperWorld::isolatedWorldsExist() && !canExistInWorker(object)) || holderContainsWrapper(callbackInfo, holder)) {
     64             if (ScriptWrappable::wrapperCanBeStoredInObject(object)) {
     65                 v8::Handle<v8::Object> result = ScriptWrappable::getUnsafeWrapperFromObject(object).deprecatedHandle();
     66                 // Security: always guard against malicious tampering.
     67                 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.IsEmpty() || result->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(object));
     68                 return result;
     69             }
     70             return mainWorldStore()->m_wrapperMap.get(V8T::toInternalPointer(object));
     71         }
     72         return current(callbackInfo.GetIsolate())->template get<V8T>(object);
     73     }
     74 
     75     template<typename V8T, typename T>
     76     static v8::Handle<v8::Object> getWrapper(T* object, v8::Isolate* isolate)
     77     {
     78         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && !canExistInWorker(object)) {
     79             if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) {
     80                 v8::Handle<v8::Object> result = ScriptWrappable::getUnsafeWrapperFromObject(object).deprecatedHandle();
     81                 // Security: always guard against malicious tampering.
     82                 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.IsEmpty() || result->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(object));
     83                 return result;
     84             }
     85         }
     86         return current(isolate)->template get<V8T>(object);
     87     }
     88 
     89     template<typename V8T, typename T>
     90     static v8::Handle<v8::Object> getWrapperForMainWorld(T* object)
     91     {
     92         if (ScriptWrappable::wrapperCanBeStoredInObject(object))
     93             return ScriptWrappable::getUnsafeWrapperFromObject(object).deprecatedHandle();
     94         return mainWorldStore()->template get<V8T>(object);
     95     }
     96 
     97     template<typename V8T, typename T>
     98     static void setWrapper(T* object, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, const WrapperConfiguration& configuration)
     99     {
    100         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && !canExistInWorker(object)) {
    101             if (LIKELY(!DOMWrapperWorld::isolatedWorldsExist())) {
    102                 ScriptWrappable::setWrapperInObject(object, wrapper, isolate, configuration);
    103                 return;
    104             }
    105         }
    106         return current(isolate)->template set<V8T>(object, wrapper, isolate, configuration);
    107     }
    108 
    109     template<typename V8T, typename T>
    110     inline v8::Handle<v8::Object> get(T* object)
    111     {
    112         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld)
    113             return ScriptWrappable::getUnsafeWrapperFromObject(object).deprecatedHandle();
    114         return m_wrapperMap.get(V8T::toInternalPointer(object));
    115     }
    116 
    117 private:
    118     template<typename V8T, typename T>
    119     inline void set(T* object, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, const WrapperConfiguration& configuration)
    120     {
    121         ASSERT(!!object);
    122         ASSERT(!wrapper.IsEmpty());
    123         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld) {
    124             ScriptWrappable::setWrapperInObject(object, wrapper, isolate, configuration);
    125             return;
    126         }
    127         m_wrapperMap.set(V8T::toInternalPointer(object), wrapper, configuration);
    128     }
    129 
    130     static DOMDataStore* mainWorldStore();
    131 
    132     static bool canExistInWorker(void*) { return true; }
    133     static bool canExistInWorker(Node*) { return false; }
    134 
    135     template<typename CallbackInfo>
    136     static bool holderContainsWrapper(const CallbackInfo&, void*)
    137     {
    138         return false;
    139     }
    140 
    141     template<typename CallbackInfo>
    142     static bool holderContainsWrapper(const CallbackInfo& callbackInfo, ScriptWrappable* wrappable)
    143     {
    144         // Verify our assumptions about the main world.
    145         ASSERT(wrappable->unsafePersistent().deprecatedHandle().IsEmpty() || callbackInfo.Holder() != wrappable->unsafePersistent().deprecatedHandle() || current(v8::Isolate::GetCurrent())->m_type == MainWorld);
    146         return callbackInfo.Holder() == wrappable->unsafePersistent().deprecatedHandle();
    147     }
    148 
    149     WrapperWorldType m_type;
    150     DOMWrapperMap<void> m_wrapperMap;
    151 };
    152 
    153 } // namespace WebCore
    154 
    155 #endif // DOMDataStore_h
    156