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 #include "config.h" 32 #include "bindings/core/v8/DOMWrapperWorld.h" 33 34 #include "bindings/core/v8/DOMDataStore.h" 35 #include "bindings/core/v8/ScriptController.h" 36 #include "bindings/core/v8/V8Binding.h" 37 #include "bindings/core/v8/V8DOMActivityLogger.h" 38 #include "bindings/core/v8/V8DOMWrapper.h" 39 #include "bindings/core/v8/V8Window.h" 40 #include "bindings/core/v8/WindowProxy.h" 41 #include "bindings/core/v8/WrapperTypeInfo.h" 42 #include "core/dom/ExecutionContext.h" 43 #include "wtf/HashTraits.h" 44 #include "wtf/StdLibExtras.h" 45 46 namespace blink { 47 48 unsigned DOMWrapperWorld::isolatedWorldCount = 0; 49 DOMWrapperWorld* DOMWrapperWorld::worldOfInitializingWindow = 0; 50 51 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::create(int worldId, int extensionGroup) 52 { 53 return adoptRef(new DOMWrapperWorld(worldId, extensionGroup)); 54 } 55 56 DOMWrapperWorld::DOMWrapperWorld(int worldId, int extensionGroup) 57 : m_worldId(worldId) 58 , m_extensionGroup(extensionGroup) 59 , m_domDataStore(adoptPtr(new DOMDataStore(isMainWorld()))) 60 { 61 } 62 63 DOMWrapperWorld& DOMWrapperWorld::mainWorld() 64 { 65 ASSERT(isMainThread()); 66 DEFINE_STATIC_REF(DOMWrapperWorld, cachedMainWorld, (DOMWrapperWorld::create(MainWorldId, mainWorldExtensionGroup))); 67 return *cachedMainWorld; 68 } 69 70 DOMWrapperWorld& DOMWrapperWorld::privateScriptIsolatedWorld() 71 { 72 ASSERT(isMainThread()); 73 DEFINE_STATIC_LOCAL(RefPtr<DOMWrapperWorld>, cachedPrivateScriptIsolatedWorld, ()); 74 if (!cachedPrivateScriptIsolatedWorld) { 75 cachedPrivateScriptIsolatedWorld = DOMWrapperWorld::create(PrivateScriptIsolatedWorldId, privateScriptIsolatedWorldExtensionGroup); 76 isolatedWorldCount++; 77 } 78 return *cachedPrivateScriptIsolatedWorld; 79 } 80 81 typedef HashMap<int, DOMWrapperWorld*> WorldMap; 82 static WorldMap& isolatedWorldMap() 83 { 84 ASSERT(isMainThread()); 85 DEFINE_STATIC_LOCAL(WorldMap, map, ()); 86 return map; 87 } 88 89 void DOMWrapperWorld::allWorldsInMainThread(Vector<RefPtr<DOMWrapperWorld> >& worlds) 90 { 91 ASSERT(isMainThread()); 92 worlds.append(&mainWorld()); 93 WorldMap& isolatedWorlds = isolatedWorldMap(); 94 for (WorldMap::iterator it = isolatedWorlds.begin(); it != isolatedWorlds.end(); ++it) 95 worlds.append(it->value); 96 } 97 98 DOMWrapperWorld::~DOMWrapperWorld() 99 { 100 ASSERT(!isMainWorld()); 101 102 dispose(); 103 104 if (!isIsolatedWorld()) 105 return; 106 107 WorldMap& map = isolatedWorldMap(); 108 WorldMap::iterator it = map.find(m_worldId); 109 if (it == map.end()) { 110 ASSERT_NOT_REACHED(); 111 return; 112 } 113 ASSERT(it->value == this); 114 115 map.remove(it); 116 isolatedWorldCount--; 117 } 118 119 void DOMWrapperWorld::dispose() 120 { 121 m_domObjectHolders.clear(); 122 m_domDataStore.clear(); 123 } 124 125 #if ENABLE(ASSERT) 126 static bool isIsolatedWorldId(int worldId) 127 { 128 return MainWorldId < worldId && worldId < IsolatedWorldIdLimit; 129 } 130 #endif 131 132 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::ensureIsolatedWorld(int worldId, int extensionGroup) 133 { 134 ASSERT(isIsolatedWorldId(worldId)); 135 136 WorldMap& map = isolatedWorldMap(); 137 WorldMap::AddResult result = map.add(worldId, 0); 138 RefPtr<DOMWrapperWorld> world = result.storedValue->value; 139 if (world) { 140 ASSERT(world->worldId() == worldId); 141 ASSERT(world->extensionGroup() == extensionGroup); 142 return world.release(); 143 } 144 145 world = DOMWrapperWorld::create(worldId, extensionGroup); 146 result.storedValue->value = world.get(); 147 isolatedWorldCount++; 148 return world.release(); 149 } 150 151 typedef HashMap<int, RefPtr<SecurityOrigin> > IsolatedWorldSecurityOriginMap; 152 static IsolatedWorldSecurityOriginMap& isolatedWorldSecurityOrigins() 153 { 154 ASSERT(isMainThread()); 155 DEFINE_STATIC_LOCAL(IsolatedWorldSecurityOriginMap, map, ()); 156 return map; 157 } 158 159 SecurityOrigin* DOMWrapperWorld::isolatedWorldSecurityOrigin() 160 { 161 ASSERT(this->isIsolatedWorld()); 162 IsolatedWorldSecurityOriginMap& origins = isolatedWorldSecurityOrigins(); 163 IsolatedWorldSecurityOriginMap::iterator it = origins.find(worldId()); 164 return it == origins.end() ? 0 : it->value.get(); 165 } 166 167 void DOMWrapperWorld::setIsolatedWorldSecurityOrigin(int worldId, PassRefPtr<SecurityOrigin> securityOrigin) 168 { 169 ASSERT(isIsolatedWorldId(worldId)); 170 if (securityOrigin) 171 isolatedWorldSecurityOrigins().set(worldId, securityOrigin); 172 else 173 isolatedWorldSecurityOrigins().remove(worldId); 174 } 175 176 typedef HashMap<int, String > IsolatedWorldHumanReadableNameMap; 177 static IsolatedWorldHumanReadableNameMap& isolatedWorldHumanReadableNames() 178 { 179 ASSERT(isMainThread()); 180 DEFINE_STATIC_LOCAL(IsolatedWorldHumanReadableNameMap, map, ()); 181 return map; 182 } 183 184 String DOMWrapperWorld::isolatedWorldHumanReadableName() 185 { 186 ASSERT(this->isIsolatedWorld()); 187 return isolatedWorldHumanReadableNames().get(worldId()); 188 } 189 190 void DOMWrapperWorld::setIsolatedWorldHumanReadableName(int worldId, const String& humanReadableName) 191 { 192 ASSERT(isIsolatedWorldId(worldId)); 193 isolatedWorldHumanReadableNames().set(worldId, humanReadableName); 194 } 195 196 typedef HashMap<int, bool> IsolatedWorldContentSecurityPolicyMap; 197 static IsolatedWorldContentSecurityPolicyMap& isolatedWorldContentSecurityPolicies() 198 { 199 ASSERT(isMainThread()); 200 DEFINE_STATIC_LOCAL(IsolatedWorldContentSecurityPolicyMap, map, ()); 201 return map; 202 } 203 204 bool DOMWrapperWorld::isolatedWorldHasContentSecurityPolicy() 205 { 206 ASSERT(this->isIsolatedWorld()); 207 IsolatedWorldContentSecurityPolicyMap& policies = isolatedWorldContentSecurityPolicies(); 208 IsolatedWorldContentSecurityPolicyMap::iterator it = policies.find(worldId()); 209 return it == policies.end() ? false : it->value; 210 } 211 212 void DOMWrapperWorld::setIsolatedWorldContentSecurityPolicy(int worldId, const String& policy) 213 { 214 ASSERT(isIsolatedWorldId(worldId)); 215 if (!policy.isEmpty()) 216 isolatedWorldContentSecurityPolicies().set(worldId, true); 217 else 218 isolatedWorldContentSecurityPolicies().remove(worldId); 219 } 220 221 void DOMWrapperWorld::registerDOMObjectHolderInternal(PassOwnPtr<DOMObjectHolderBase> holderBase) 222 { 223 ASSERT(!m_domObjectHolders.contains(holderBase.get())); 224 holderBase->setWorld(this); 225 holderBase->setWeak(&DOMWrapperWorld::weakCallbackForDOMObjectHolder); 226 m_domObjectHolders.add(holderBase); 227 } 228 229 void DOMWrapperWorld::unregisterDOMObjectHolder(DOMObjectHolderBase* holderBase) 230 { 231 ASSERT(m_domObjectHolders.contains(holderBase)); 232 m_domObjectHolders.remove(holderBase); 233 } 234 235 void DOMWrapperWorld::weakCallbackForDOMObjectHolder(const v8::WeakCallbackData<v8::Value, DOMObjectHolderBase>& data) 236 { 237 DOMObjectHolderBase* holderBase = data.GetParameter(); 238 holderBase->world()->unregisterDOMObjectHolder(holderBase); 239 } 240 241 } // namespace blink 242