1 /* 2 * Copyright (C) 2012 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 V8PerContextData_h 32 #define V8PerContextData_h 33 34 #include "bindings/v8/CustomElementBinding.h" 35 #include "bindings/v8/ScopedPersistent.h" 36 #include "bindings/v8/UnsafePersistent.h" 37 #include "bindings/v8/V8DOMActivityLogger.h" 38 #include "bindings/v8/WrapperTypeInfo.h" 39 #include <v8.h> 40 #include "wtf/HashMap.h" 41 #include "wtf/PassOwnPtr.h" 42 #include "wtf/Vector.h" 43 #include "wtf/text/AtomicString.h" 44 #include "wtf/text/AtomicStringHash.h" 45 46 namespace WebCore { 47 48 class CustomElementDefinition; 49 struct V8NPObject; 50 typedef WTF::Vector<V8NPObject*> V8NPObjectVector; 51 typedef WTF::HashMap<int, V8NPObjectVector> V8NPObjectMap; 52 53 enum V8ContextEmbedderDataField { 54 v8ContextDebugIdIndex, 55 v8ContextPerContextDataIndex, 56 v8ContextIsolatedWorld, 57 // Rather than adding more embedder data fields to v8::Context, 58 // consider adding the data to V8PerContextData instead. 59 }; 60 61 class V8PerContextData { 62 public: 63 static PassOwnPtr<V8PerContextData> create(v8::Handle<v8::Context> context) 64 { 65 return adoptPtr(new V8PerContextData(context)); 66 } 67 68 ~V8PerContextData() 69 { 70 dispose(); 71 } 72 73 bool init(); 74 75 static V8PerContextData* from(v8::Handle<v8::Context> context) 76 { 77 return static_cast<V8PerContextData*>(context->GetAlignedPointerFromEmbedderData(v8ContextPerContextDataIndex)); 78 } 79 80 // To create JS Wrapper objects, we create a cache of a 'boiler plate' 81 // object, and then simply Clone that object each time we need a new one. 82 // This is faster than going through the full object creation process. 83 v8::Local<v8::Object> createWrapperFromCache(WrapperTypeInfo* type) 84 { 85 UnsafePersistent<v8::Object> boilerplate = m_wrapperBoilerplates.get(type); 86 return !boilerplate.isEmpty() ? boilerplate.newLocal(v8::Isolate::GetCurrent())->Clone() : createWrapperFromCacheSlowCase(type); 87 } 88 89 v8::Local<v8::Function> constructorForType(WrapperTypeInfo* type) 90 { 91 UnsafePersistent<v8::Function> function = m_constructorMap.get(type); 92 if (!function.isEmpty()) 93 return function.newLocal(v8::Isolate::GetCurrent()); 94 return constructorForTypeSlowCase(type); 95 } 96 97 V8NPObjectMap* v8NPObjectMap() 98 { 99 return &m_v8NPObjectMap; 100 } 101 102 V8DOMActivityLogger* activityLogger() 103 { 104 return m_activityLogger; 105 } 106 107 void setActivityLogger(V8DOMActivityLogger* logger) 108 { 109 m_activityLogger = logger; 110 } 111 112 void addCustomElementBinding(CustomElementDefinition*, PassOwnPtr<CustomElementBinding>); 113 void clearCustomElementBinding(CustomElementDefinition*); 114 CustomElementBinding* customElementBinding(CustomElementDefinition*); 115 116 private: 117 explicit V8PerContextData(v8::Handle<v8::Context> context) 118 : m_activityLogger(0) 119 , m_isolate(v8::Isolate::GetCurrent()) 120 , m_context(m_isolate, context) 121 , m_customElementBindings(adoptPtr(new CustomElementBindingMap())) 122 { 123 } 124 125 void dispose(); 126 127 v8::Local<v8::Object> createWrapperFromCacheSlowCase(WrapperTypeInfo*); 128 v8::Local<v8::Function> constructorForTypeSlowCase(WrapperTypeInfo*); 129 130 // For each possible type of wrapper, we keep a boilerplate object. 131 // The boilerplate is used to create additional wrappers of the same type. 132 typedef WTF::HashMap<WrapperTypeInfo*, UnsafePersistent<v8::Object> > WrapperBoilerplateMap; 133 WrapperBoilerplateMap m_wrapperBoilerplates; 134 135 typedef WTF::HashMap<WrapperTypeInfo*, UnsafePersistent<v8::Function> > ConstructorMap; 136 ConstructorMap m_constructorMap; 137 138 V8NPObjectMap m_v8NPObjectMap; 139 // We cache a pointer to the V8DOMActivityLogger associated with the world 140 // corresponding to this context. The ownership of the pointer is retained 141 // by the DOMActivityLoggerMap in DOMWrapperWorld. 142 V8DOMActivityLogger* m_activityLogger; 143 v8::Isolate* m_isolate; 144 v8::Persistent<v8::Context> m_context; 145 ScopedPersistent<v8::Value> m_errorPrototype; 146 147 typedef WTF::HashMap<CustomElementDefinition*, OwnPtr<CustomElementBinding> > CustomElementBindingMap; 148 OwnPtr<CustomElementBindingMap> m_customElementBindings; 149 }; 150 151 class V8PerContextDebugData { 152 public: 153 static bool setContextDebugData(v8::Handle<v8::Context>, const char* worldName, int debugId); 154 static int contextDebugId(v8::Handle<v8::Context>); 155 }; 156 157 } // namespace WebCore 158 159 #endif // V8PerContextData_h 160