Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(561)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp

Issue 2843603002: Move ScriptWrappable and dependencies to platform/bindings (Closed)
Patch Set: Rebase and try again Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "bindings/core/v8/DOMWrapperWorld.h"
32
33 #include <memory>
34
35 #include "bindings/core/v8/DOMDataStore.h"
36 #include "bindings/core/v8/ScriptFunction.h"
37 #include "platform/wtf/HashTraits.h"
38 #include "platform/wtf/PtrUtil.h"
39 #include "platform/wtf/StdLibExtras.h"
40
41 namespace blink {
42
43 unsigned DOMWrapperWorld::number_of_non_main_worlds_in_main_thread_ = 0;
44
45 // This does not contain the main world because the WorldMap needs
46 // non-default hashmap traits (WTF::UnsignedWithZeroKeyHashTraits) to contain
47 // it for the main world's id (0), and it may change the performance trends.
48 // (see https://crbug.com/704778#c6).
49 using WorldMap = HashMap<int, DOMWrapperWorld*>;
50 static WorldMap& GetWorldMap() {
51 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<WorldMap>, map,
52 new ThreadSpecific<WorldMap>);
53 return *map;
54 }
55
56 #if DCHECK_IS_ON()
57 static bool IsIsolatedWorldId(int world_id) {
58 return DOMWrapperWorld::kMainWorldId < world_id &&
59 world_id < DOMWrapperWorld::kIsolatedWorldIdLimit;
60 }
61 #endif
62
63 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::Create(v8::Isolate* isolate,
64 WorldType world_type) {
65 DCHECK_NE(WorldType::kIsolated, world_type);
66 return AdoptRef(new DOMWrapperWorld(isolate, world_type,
67 GenerateWorldIdForType(world_type)));
68 }
69
70 DOMWrapperWorld::DOMWrapperWorld(v8::Isolate* isolate,
71 WorldType world_type,
72 int world_id)
73 : world_type_(world_type),
74 world_id_(world_id),
75 dom_data_store_(
76 WTF::WrapUnique(new DOMDataStore(isolate, IsMainWorld()))) {
77 switch (world_type_) {
78 case WorldType::kMain:
79 // The main world is managed separately from worldMap(). See worldMap().
80 break;
81 case WorldType::kIsolated:
82 case WorldType::kGarbageCollector:
83 case WorldType::kRegExp:
84 case WorldType::kTesting:
85 case WorldType::kWorker: {
86 WorldMap& map = GetWorldMap();
87 DCHECK(!map.Contains(world_id_));
88 map.insert(world_id_, this);
89 if (IsMainThread())
90 number_of_non_main_worlds_in_main_thread_++;
91 break;
92 }
93 }
94 }
95
96 DOMWrapperWorld& DOMWrapperWorld::MainWorld() {
97 DCHECK(IsMainThread());
98 DEFINE_STATIC_REF(
99 DOMWrapperWorld, cached_main_world,
100 (DOMWrapperWorld::Create(v8::Isolate::GetCurrent(), WorldType::kMain)));
101 return *cached_main_world;
102 }
103
104 void DOMWrapperWorld::AllWorldsInCurrentThread(
105 Vector<RefPtr<DOMWrapperWorld>>& worlds) {
106 if (IsMainThread())
107 worlds.push_back(&MainWorld());
108 for (DOMWrapperWorld* world : GetWorldMap().Values())
109 worlds.push_back(world);
110 }
111
112 void DOMWrapperWorld::MarkWrappersInAllWorlds(
113 ScriptWrappable* script_wrappable,
114 const ScriptWrappableVisitor* visitor) {
115 // Marking for worlds other than the main world.
116 DCHECK(ThreadState::Current()->GetIsolate());
117 for (DOMWrapperWorld* world : GetWorldMap().Values()) {
118 DOMDataStore& data_store = world->DomDataStore();
119 if (data_store.ContainsWrapper(script_wrappable))
120 data_store.MarkWrapper(script_wrappable);
121 }
122
123 // Marking for the main world.
124 if (IsMainThread())
125 script_wrappable->MarkWrapper(visitor);
126 }
127
128 DOMWrapperWorld::~DOMWrapperWorld() {
129 DCHECK(!IsMainWorld());
130 if (IsMainThread())
131 number_of_non_main_worlds_in_main_thread_--;
132
133 // WorkerWorld should be disposed of before the dtor.
134 if (!IsWorkerWorld())
135 Dispose();
136 DCHECK(!GetWorldMap().Contains(world_id_));
137 }
138
139 void DOMWrapperWorld::Dispose() {
140 dom_object_holders_.clear();
141 dom_data_store_.reset();
142 DCHECK(GetWorldMap().Contains(world_id_));
143 GetWorldMap().erase(world_id_);
144 }
145
146 PassRefPtr<DOMWrapperWorld> DOMWrapperWorld::EnsureIsolatedWorld(
147 v8::Isolate* isolate,
148 int world_id) {
149 #if DCHECK_IS_ON()
150 DCHECK(IsIsolatedWorldId(world_id));
151 #endif
152
153 WorldMap& map = GetWorldMap();
154 auto it = map.find(world_id);
155 if (it != map.end()) {
156 RefPtr<DOMWrapperWorld> world = it->value;
157 DCHECK(world->IsIsolatedWorld());
158 DCHECK_EQ(world_id, world->GetWorldId());
159 return world.Release();
160 }
161
162 return AdoptRef(new DOMWrapperWorld(isolate, WorldType::kIsolated, world_id));
163 }
164
165 typedef HashMap<int, RefPtr<SecurityOrigin>> IsolatedWorldSecurityOriginMap;
166 static IsolatedWorldSecurityOriginMap& IsolatedWorldSecurityOrigins() {
167 DCHECK(IsMainThread());
168 DEFINE_STATIC_LOCAL(IsolatedWorldSecurityOriginMap, map, ());
169 return map;
170 }
171
172 SecurityOrigin* DOMWrapperWorld::IsolatedWorldSecurityOrigin() {
173 DCHECK(this->IsIsolatedWorld());
174 IsolatedWorldSecurityOriginMap& origins = IsolatedWorldSecurityOrigins();
175 IsolatedWorldSecurityOriginMap::iterator it = origins.find(GetWorldId());
176 return it == origins.end() ? 0 : it->value.Get();
177 }
178
179 void DOMWrapperWorld::SetIsolatedWorldSecurityOrigin(
180 int world_id,
181 PassRefPtr<SecurityOrigin> security_origin) {
182 #if DCHECK_IS_ON()
183 DCHECK(IsIsolatedWorldId(world_id));
184 #endif
185 if (security_origin)
186 IsolatedWorldSecurityOrigins().Set(world_id, std::move(security_origin));
187 else
188 IsolatedWorldSecurityOrigins().erase(world_id);
189 }
190
191 typedef HashMap<int, String> IsolatedWorldHumanReadableNameMap;
192 static IsolatedWorldHumanReadableNameMap& IsolatedWorldHumanReadableNames() {
193 DCHECK(IsMainThread());
194 DEFINE_STATIC_LOCAL(IsolatedWorldHumanReadableNameMap, map, ());
195 return map;
196 }
197
198 String DOMWrapperWorld::IsolatedWorldHumanReadableName() {
199 ASSERT(this->IsIsolatedWorld());
200 return IsolatedWorldHumanReadableNames().at(GetWorldId());
201 }
202
203 void DOMWrapperWorld::SetIsolatedWorldHumanReadableName(
204 int world_id,
205 const String& human_readable_name) {
206 #if DCHECK_IS_ON()
207 DCHECK(IsIsolatedWorldId(world_id));
208 #endif
209 IsolatedWorldHumanReadableNames().Set(world_id, human_readable_name);
210 }
211
212 typedef HashMap<int, bool> IsolatedWorldContentSecurityPolicyMap;
213 static IsolatedWorldContentSecurityPolicyMap&
214 IsolatedWorldContentSecurityPolicies() {
215 DCHECK(IsMainThread());
216 DEFINE_STATIC_LOCAL(IsolatedWorldContentSecurityPolicyMap, map, ());
217 return map;
218 }
219
220 bool DOMWrapperWorld::IsolatedWorldHasContentSecurityPolicy() {
221 DCHECK(this->IsIsolatedWorld());
222 IsolatedWorldContentSecurityPolicyMap& policies =
223 IsolatedWorldContentSecurityPolicies();
224 IsolatedWorldContentSecurityPolicyMap::iterator it =
225 policies.find(GetWorldId());
226 return it == policies.end() ? false : it->value;
227 }
228
229 void DOMWrapperWorld::SetIsolatedWorldContentSecurityPolicy(
230 int world_id,
231 const String& policy) {
232 #if DCHECK_IS_ON()
233 DCHECK(IsIsolatedWorldId(world_id));
234 #endif
235 if (!policy.IsEmpty())
236 IsolatedWorldContentSecurityPolicies().Set(world_id, true);
237 else
238 IsolatedWorldContentSecurityPolicies().erase(world_id);
239 }
240
241 void DOMWrapperWorld::RegisterDOMObjectHolderInternal(
242 std::unique_ptr<DOMObjectHolderBase> holder_base) {
243 DCHECK(!dom_object_holders_.Contains(holder_base.get()));
244 holder_base->SetWorld(this);
245 holder_base->SetWeak(&DOMWrapperWorld::WeakCallbackForDOMObjectHolder);
246 dom_object_holders_.insert(std::move(holder_base));
247 }
248
249 void DOMWrapperWorld::UnregisterDOMObjectHolder(
250 DOMObjectHolderBase* holder_base) {
251 DCHECK(dom_object_holders_.Contains(holder_base));
252 dom_object_holders_.erase(holder_base);
253 }
254
255 void DOMWrapperWorld::WeakCallbackForDOMObjectHolder(
256 const v8::WeakCallbackInfo<DOMObjectHolderBase>& data) {
257 DOMObjectHolderBase* holder_base = data.GetParameter();
258 holder_base->World()->UnregisterDOMObjectHolder(holder_base);
259 }
260
261 int DOMWrapperWorld::GenerateWorldIdForType(WorldType world_type) {
262 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<int>, next_world_id,
263 new ThreadSpecific<int>);
264 if (!next_world_id.IsSet())
265 *next_world_id = WorldId::kUnspecifiedWorldIdStart;
266 switch (world_type) {
267 case WorldType::kMain:
268 return kMainWorldId;
269 case WorldType::kIsolated:
270 // This function should not be called for IsolatedWorld because an
271 // identifier for the world is given from out of DOMWrapperWorld.
272 NOTREACHED();
273 return kInvalidWorldId;
274 case WorldType::kGarbageCollector:
275 case WorldType::kRegExp:
276 case WorldType::kTesting:
277 case WorldType::kWorker:
278 int world_id = *next_world_id;
279 CHECK_GE(world_id, WorldId::kUnspecifiedWorldIdStart);
280 *next_world_id = world_id + 1;
281 return world_id;
282 }
283 NOTREACHED();
284 return kInvalidWorldId;
285 }
286
287 void DOMWrapperWorld::DissociateDOMWindowWrappersInAllWorlds(
288 ScriptWrappable* script_wrappable) {
289 DCHECK(script_wrappable);
290 DCHECK(IsMainThread());
291
292 script_wrappable->UnsetWrapperIfAny();
293
294 for (auto& world : GetWorldMap().Values())
295 world->DomDataStore().UnsetWrapperIfAny(script_wrappable);
296 }
297
298 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698