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

Side by Side Diff: webkit/plugins/ppapi/v8_var_converter.cc

Issue 16140011: Don't send PP_Vars/V8 values with cycles across PostMessage (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/plugins/ppapi/v8_var_converter.h" 5 #include "webkit/plugins/ppapi/v8_var_converter.h"
6 6
7 #include <map> 7 #include <map>
8 #include <stack> 8 #include <stack>
9 #include <string> 9 #include <string>
10 10
11 #include "base/containers/hash_tables.h" 11 #include "base/containers/hash_tables.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "ppapi/shared_impl/array_var.h" 14 #include "ppapi/shared_impl/array_var.h"
15 #include "ppapi/shared_impl/dictionary_var.h" 15 #include "ppapi/shared_impl/dictionary_var.h"
16 #include "ppapi/shared_impl/var.h" 16 #include "ppapi/shared_impl/var.h"
17 #include "ppapi/shared_impl/var_tracker.h" 17 #include "ppapi/shared_impl/var_tracker.h"
18 #include "third_party/WebKit/public/web/WebArrayBuffer.h" 18 #include "third_party/WebKit/public/web/WebArrayBuffer.h"
19 #include "webkit/plugins/ppapi/host_array_buffer_var.h" 19 #include "webkit/plugins/ppapi/host_array_buffer_var.h"
20 20
21 using ppapi::ArrayBufferVar; 21 using ppapi::ArrayBufferVar;
22 using ppapi::ArrayVar; 22 using ppapi::ArrayVar;
23 using ppapi::DictionaryVar; 23 using ppapi::DictionaryVar;
24 using ppapi::ScopedPPVar; 24 using ppapi::ScopedPPVar;
25 using ppapi::StringVar; 25 using ppapi::StringVar;
26 using std::make_pair; 26 using std::make_pair;
27 27
28 namespace { 28 namespace {
29 29
30 template <class T>
31 struct StackEntry {
32 StackEntry(T v) : val(v), sentinel(false) {}
33 T val;
34 // Used to track parent nodes on the stack while traversing the graph.
35 bool sentinel;
36 };
37
30 struct HashedHandle { 38 struct HashedHandle {
31 HashedHandle(v8::Handle<v8::Object> h) : handle(h) {} 39 HashedHandle(v8::Handle<v8::Object> h) : handle(h) {}
32 size_t hash() const { return handle->GetIdentityHash(); } 40 size_t hash() const { return handle->GetIdentityHash(); }
33 bool operator==(const HashedHandle& h) const { return handle == h.handle; } 41 bool operator==(const HashedHandle& h) const { return handle == h.handle; }
34 bool operator<(const HashedHandle& h) const { return hash() < h.hash(); } 42 bool operator<(const HashedHandle& h) const { return hash() < h.hash(); }
35 v8::Handle<v8::Object> handle; 43 v8::Handle<v8::Object> handle;
36 }; 44 };
37 45
38 } // namespace 46 } // namespace
39 47
40 namespace BASE_HASH_NAMESPACE { 48 namespace BASE_HASH_NAMESPACE {
41 #if defined(COMPILER_GCC) 49 #if defined(COMPILER_GCC)
42 template <> 50 template <>
43 struct hash<HashedHandle> { 51 struct hash<HashedHandle> {
44 size_t operator()(const HashedHandle& handle) const { 52 size_t operator()(const HashedHandle& handle) const {
45 return handle.hash(); 53 return handle.hash();
46 } 54 }
47 }; 55 };
48 #elif defined(COMPILER_MSVC) 56 #elif defined(COMPILER_MSVC)
49 inline size_t hash_value(const HashedHandle& handle) { 57 inline size_t hash_value(const HashedHandle& handle) {
50 return handle.hash(); 58 return handle.hash();
51 } 59 }
52 #endif 60 #endif
53 } // namespace BASE_HASH_NAMESPACE 61 } // namespace BASE_HASH_NAMESPACE
54 62
55 namespace webkit { 63 namespace webkit {
56 namespace ppapi { 64 namespace ppapi {
65 namespace V8VarConverter {
57 66
58 namespace { 67 namespace {
59 68
60 // Maps PP_Var IDs to the V8 value handle they correspond to. 69 // Maps PP_Var IDs to the V8 value handle they correspond to.
61 typedef base::hash_map<int64_t, v8::Handle<v8::Value> > VarHandleMap; 70 typedef base::hash_map<int64_t, v8::Handle<v8::Value> > VarHandleMap;
71 typedef base::hash_set<int64_t> ParentVarSet;
62 72
63 // Maps V8 value handles to the PP_Var they correspond to. 73 // Maps V8 value handles to the PP_Var they correspond to.
64 typedef base::hash_map<HashedHandle, ScopedPPVar> HandleVarMap; 74 typedef base::hash_map<HashedHandle, ScopedPPVar> HandleVarMap;
75 typedef base::hash_set<HashedHandle> ParentHandleSet;
65 76
66 // Returns a V8 value which corresponds to a given PP_Var. If |var| is a 77 // Returns a V8 value which corresponds to a given PP_Var. If |var| is a
67 // reference counted PP_Var type, and it exists in |visited_ids|, the V8 value 78 // reference counted PP_Var type, and it exists in |visited_ids|, the V8 value
68 // associated with it in the map will be returned, otherwise a new V8 value will 79 // associated with it in the map will be returned, otherwise a new V8 value will
69 // be created and added to the map. |did_create| indicates whether a new v8 80 // be created and added to the map. |did_create| indicates whether a new v8
70 // value was created as a result of calling the function. 81 // value was created as a result of calling the function.
71 bool GetOrCreateV8Value(const PP_Var& var, 82 bool GetOrCreateV8Value(const PP_Var& var,
72 v8::Handle<v8::Value>* result, 83 v8::Handle<v8::Value>* result,
73 bool* did_create, 84 bool* did_create,
74 VarHandleMap* visited_ids) { 85 VarHandleMap* visited_ids,
86 ParentVarSet* parent_ids) {
75 *did_create = false; 87 *did_create = false;
76 88
77 if (::ppapi::VarTracker::IsVarTypeRefcounted(var.type)) { 89 if (::ppapi::VarTracker::IsVarTypeRefcounted(var.type)) {
90 if (parent_ids->count(var.value.as_id) != 0)
91 return false;
78 VarHandleMap::iterator it = visited_ids->find(var.value.as_id); 92 VarHandleMap::iterator it = visited_ids->find(var.value.as_id);
79 if (it != visited_ids->end()) { 93 if (it != visited_ids->end()) {
80 *result = it->second; 94 *result = it->second;
81 return true; 95 return true;
82 } 96 }
83 } 97 }
84 98
85 switch (var.type) { 99 switch (var.type) {
86 case PP_VARTYPE_UNDEFINED: 100 case PP_VARTYPE_UNDEFINED:
87 *result = v8::Undefined(); 101 *result = v8::Undefined();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 } 158 }
145 159
146 // For a given V8 value handle, this returns a PP_Var which corresponds to it. 160 // For a given V8 value handle, this returns a PP_Var which corresponds to it.
147 // If the handle already exists in |visited_handles|, the PP_Var associated with 161 // If the handle already exists in |visited_handles|, the PP_Var associated with
148 // it will be returned, otherwise a new V8 value will be created and added to 162 // it will be returned, otherwise a new V8 value will be created and added to
149 // the map. |did_create| indicates if a new PP_Var was created as a result of 163 // the map. |did_create| indicates if a new PP_Var was created as a result of
150 // calling the function. 164 // calling the function.
151 bool GetOrCreateVar(v8::Handle<v8::Value> val, 165 bool GetOrCreateVar(v8::Handle<v8::Value> val,
152 PP_Var* result, 166 PP_Var* result,
153 bool* did_create, 167 bool* did_create,
154 HandleVarMap* visited_handles) { 168 HandleVarMap* visited_handles,
169 ParentHandleSet* parent_handles) {
155 CHECK(!val.IsEmpty()); 170 CHECK(!val.IsEmpty());
156 *did_create = false; 171 *did_create = false;
157 172
158 // Even though every v8 string primitive encountered will be a unique object, 173 // Even though every v8 string primitive encountered will be a unique object,
159 // we still add them to |visited_handles| so that the corresponding string 174 // we still add them to |visited_handles| so that the corresponding string
160 // PP_Var created will be properly refcounted. 175 // PP_Var created will be properly refcounted.
161 if (val->IsObject() || val->IsString()) { 176 if (val->IsObject() || val->IsString()) {
177 if (parent_handles->count(HashedHandle(val->ToObject())) != 0)
178 return false;
179
162 HandleVarMap::const_iterator it = visited_handles->find( 180 HandleVarMap::const_iterator it = visited_handles->find(
163 HashedHandle(val->ToObject())); 181 HashedHandle(val->ToObject()));
164 if (it != visited_handles->end()) { 182 if (it != visited_handles->end()) {
165 *result = it->second.get(); 183 *result = it->second.get();
166 return true; 184 return true;
167 } 185 }
168 } 186 }
169 187
170 if (val->IsUndefined()) { 188 if (val->IsUndefined()) {
171 *result = PP_MakeUndefined(); 189 *result = PP_MakeUndefined();
(...skipping 14 matching lines...) Expand all
186 scoped_ptr<WebKit::WebArrayBuffer> web_array_buffer( 204 scoped_ptr<WebKit::WebArrayBuffer> web_array_buffer(
187 WebKit::WebArrayBuffer::createFromV8Value(val)); 205 WebKit::WebArrayBuffer::createFromV8Value(val));
188 if (web_array_buffer.get()) { 206 if (web_array_buffer.get()) {
189 scoped_refptr<HostArrayBufferVar> buffer_var(new HostArrayBufferVar( 207 scoped_refptr<HostArrayBufferVar> buffer_var(new HostArrayBufferVar(
190 *web_array_buffer)); 208 *web_array_buffer));
191 *result = buffer_var->GetPPVar(); 209 *result = buffer_var->GetPPVar();
192 } else { 210 } else {
193 *result = (new DictionaryVar())->GetPPVar(); 211 *result = (new DictionaryVar())->GetPPVar();
194 } 212 }
195 } else { 213 } else {
196 NOTREACHED(); 214 // Silently ignore the case where we can't convert to a Var as we may
197 return false; 215 // be trying to convert a type that doesn't have a corresponding
216 // PP_Var type.
217 return true;
198 } 218 }
199 219
200 *did_create = true; 220 *did_create = true;
201 if (val->IsObject() || val->IsString()) { 221 if (val->IsObject() || val->IsString()) {
202 visited_handles->insert(make_pair( 222 visited_handles->insert(make_pair(
203 HashedHandle(val->ToObject()), 223 HashedHandle(val->ToObject()),
204 ScopedPPVar(ScopedPPVar::PassRef(), *result))); 224 ScopedPPVar(ScopedPPVar::PassRef(), *result)));
205 } 225 }
206 return true; 226 return true;
207 } 227 }
208 228
229 bool CanHaveChildren(PP_Var var) {
230 return var.type == PP_VARTYPE_ARRAY || var.type == PP_VARTYPE_DICTIONARY;
231 }
232
209 } // namespace 233 } // namespace
210 234
211 V8VarConverter::V8VarConverter() { 235 // To/FromV8Value use a stack-based DFS search to traverse V8/Var graph. Each
212 } 236 // iteration, the top node on the stack examined. If the node has not been
213 237 // visited yet (i.e. sentinel == false) then it is added to the list of parents
214 bool V8VarConverter::ToV8Value(const PP_Var& var, 238 // which contains all of the nodes on the path from the start node to the
215 v8::Handle<v8::Context> context, 239 // current node. Each of the current nodes children are examined. If they appear
216 v8::Handle<v8::Value>* result) const { 240 // in the list of parents it means we have a cycle and we return NULL.
241 // Otherwise, if they can have children, we add them to the stack. If the
242 // node at the top of the stack has already been visited, then we pop it off the
243 // stack and erase it from the list of parents.
244 // static
245 bool ToV8Value(const PP_Var& var,
246 v8::Handle<v8::Context> context,
247 v8::Handle<v8::Value>* result) {
217 v8::Context::Scope context_scope(context); 248 v8::Context::Scope context_scope(context);
218 v8::HandleScope handle_scope; 249 v8::HandleScope handle_scope;
219 250
220 VarHandleMap visited_ids; 251 VarHandleMap visited_ids;
252 ParentVarSet parent_ids;
221 253
222 std::stack<PP_Var> stack; 254 std::stack<StackEntry<PP_Var> > stack;
223 stack.push(var); 255 stack.push(StackEntry<PP_Var>(var));
224 v8::Handle<v8::Value> root; 256 v8::Handle<v8::Value> root;
225 bool is_root = true; 257 bool is_root = true;
226 258
227 while (!stack.empty()) { 259 while (!stack.empty()) {
228 const PP_Var& current_var = stack.top(); 260 const PP_Var& current_var = stack.top().val;
229 v8::Handle<v8::Value> current_v8; 261 v8::Handle<v8::Value> current_v8;
230 stack.pop(); 262
263 if (stack.top().sentinel) {
264 stack.pop();
265 if (CanHaveChildren(current_var))
266 parent_ids.erase(current_var.value.as_id);
267 continue;
268 } else {
269 stack.top().sentinel = true;
270 }
271
231 bool did_create = false; 272 bool did_create = false;
232 if (!GetOrCreateV8Value(current_var, &current_v8, &did_create, 273 if (!GetOrCreateV8Value(current_var, &current_v8, &did_create,
233 &visited_ids)) { 274 &visited_ids, &parent_ids)) {
234 return false; 275 return false;
235 } 276 }
236 277
237 if (is_root) { 278 if (is_root) {
238 is_root = false; 279 is_root = false;
239 root = current_v8; 280 root = current_v8;
240 } 281 }
241 282
242 // Add child nodes to the stack. 283 // Add child nodes to the stack.
243 if (current_var.type == PP_VARTYPE_ARRAY) { 284 if (current_var.type == PP_VARTYPE_ARRAY) {
285 parent_ids.insert(current_var.value.as_id);
244 ArrayVar* array_var = ArrayVar::FromPPVar(current_var); 286 ArrayVar* array_var = ArrayVar::FromPPVar(current_var);
245 if (!array_var) { 287 if (!array_var) {
246 NOTREACHED(); 288 NOTREACHED();
247 return false; 289 return false;
248 } 290 }
249 DCHECK(current_v8->IsArray()); 291 DCHECK(current_v8->IsArray());
250 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>(); 292 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>();
251 293
252 for (size_t i = 0; i < array_var->elements().size(); ++i) { 294 for (size_t i = 0; i < array_var->elements().size(); ++i) {
253 const PP_Var& child_var = array_var->elements()[i].get(); 295 const PP_Var& child_var = array_var->elements()[i].get();
254 v8::Handle<v8::Value> child_v8; 296 v8::Handle<v8::Value> child_v8;
255 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create, 297 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create,
256 &visited_ids)) { 298 &visited_ids, &parent_ids)) {
257 return false; 299 return false;
258 } 300 }
259 if (did_create && 301 if (did_create && CanHaveChildren(child_var))
260 (child_var.type == PP_VARTYPE_DICTIONARY ||
261 child_var.type == PP_VARTYPE_ARRAY)) {
262 stack.push(child_var); 302 stack.push(child_var);
263 }
264 v8::TryCatch try_catch; 303 v8::TryCatch try_catch;
265 v8_array->Set(static_cast<uint32>(i), child_v8); 304 v8_array->Set(static_cast<uint32>(i), child_v8);
266 if (try_catch.HasCaught()) { 305 if (try_catch.HasCaught()) {
267 LOG(ERROR) << "Setter for index " << i << " threw an exception."; 306 LOG(ERROR) << "Setter for index " << i << " threw an exception.";
268 return false; 307 return false;
269 } 308 }
270 } 309 }
271 } else if (current_var.type == PP_VARTYPE_DICTIONARY) { 310 } else if (current_var.type == PP_VARTYPE_DICTIONARY) {
311 parent_ids.insert(current_var.value.as_id);
272 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var); 312 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var);
273 if (!dict_var) { 313 if (!dict_var) {
274 NOTREACHED(); 314 NOTREACHED();
275 return false; 315 return false;
276 } 316 }
277 DCHECK(current_v8->IsObject()); 317 DCHECK(current_v8->IsObject());
278 v8::Handle<v8::Object> v8_object = current_v8->ToObject(); 318 v8::Handle<v8::Object> v8_object = current_v8->ToObject();
279 319
280 for (DictionaryVar::KeyValueMap::const_iterator iter = 320 for (DictionaryVar::KeyValueMap::const_iterator iter =
281 dict_var->key_value_map().begin(); 321 dict_var->key_value_map().begin();
282 iter != dict_var->key_value_map().end(); 322 iter != dict_var->key_value_map().end();
283 ++iter) { 323 ++iter) {
284 const std::string& key = iter->first; 324 const std::string& key = iter->first;
285 const PP_Var& child_var = iter->second.get(); 325 const PP_Var& child_var = iter->second.get();
286 v8::Handle<v8::Value> child_v8; 326 v8::Handle<v8::Value> child_v8;
287 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create, 327 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create,
288 &visited_ids)) { 328 &visited_ids, &parent_ids)) {
289 return false; 329 return false;
290 } 330 }
291 if (did_create && 331 if (did_create && CanHaveChildren(child_var))
292 (child_var.type == PP_VARTYPE_DICTIONARY ||
293 child_var.type == PP_VARTYPE_ARRAY)) {
294 stack.push(child_var); 332 stack.push(child_var);
295 }
296 v8::TryCatch try_catch; 333 v8::TryCatch try_catch;
297 v8_object->Set(v8::String::New(key.c_str(), key.length()), child_v8); 334 v8_object->Set(v8::String::New(key.c_str(), key.length()), child_v8);
298 if (try_catch.HasCaught()) { 335 if (try_catch.HasCaught()) {
299 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an " 336 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an "
300 << "exception."; 337 << "exception.";
301 return false; 338 return false;
302 } 339 }
303 } 340 }
304 } 341 }
305 } 342 }
306 343
307 *result = handle_scope.Close(root); 344 *result = handle_scope.Close(root);
308 return true; 345 return true;
309 } 346 }
310 347
311 bool V8VarConverter::FromV8Value(v8::Handle<v8::Value> val, 348 bool FromV8Value(v8::Handle<v8::Value> val,
312 v8::Handle<v8::Context> context, 349 v8::Handle<v8::Context> context,
313 PP_Var* result) const { 350 PP_Var* result) {
314 v8::Context::Scope context_scope(context); 351 v8::Context::Scope context_scope(context);
315 v8::HandleScope handle_scope; 352 v8::HandleScope handle_scope;
316 353
317 HandleVarMap visited_handles; 354 HandleVarMap visited_handles;
355 ParentHandleSet parent_handles;
318 356
319 std::stack<v8::Handle<v8::Value> > stack; 357 std::stack<StackEntry<v8::Handle<v8::Value> > > stack;
320 stack.push(val); 358 stack.push(StackEntry<v8::Handle<v8::Value> >(val));
321 ScopedPPVar root; 359 ScopedPPVar root;
322 bool is_root = true; 360 bool is_root = true;
323 361
324 while (!stack.empty()) { 362 while (!stack.empty()) {
325 v8::Handle<v8::Value> current_v8 = stack.top(); 363 v8::Handle<v8::Value> current_v8 = stack.top().val;
326 PP_Var current_var; 364 PP_Var current_var;
327 stack.pop(); 365
366 if (stack.top().sentinel) {
367 stack.pop();
368 if (current_v8->IsObject())
369 parent_handles.erase(HashedHandle(current_v8->ToObject()));
370 continue;
371 } else {
372 stack.top().sentinel = true;
373 }
374
328 bool did_create = false; 375 bool did_create = false;
329 if (!GetOrCreateVar(current_v8, &current_var, &did_create, 376 if (!GetOrCreateVar(current_v8, &current_var, &did_create,
330 &visited_handles)) { 377 &visited_handles, &parent_handles)) {
331 return false; 378 return false;
332 } 379 }
333 380
334 if (is_root) { 381 if (is_root) {
335 is_root = false; 382 is_root = false;
336 root = current_var; 383 root = current_var;
337 } 384 }
338 385
339 // Add child nodes to the stack. 386 // Add child nodes to the stack.
340 if (current_var.type == PP_VARTYPE_ARRAY) { 387 if (current_var.type == PP_VARTYPE_ARRAY) {
341 DCHECK(current_v8->IsArray()); 388 DCHECK(current_v8->IsArray());
342 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>(); 389 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>();
390 parent_handles.insert(HashedHandle(v8_array));
343 391
344 ArrayVar* array_var = ArrayVar::FromPPVar(current_var); 392 ArrayVar* array_var = ArrayVar::FromPPVar(current_var);
345 if (!array_var) { 393 if (!array_var) {
346 NOTREACHED(); 394 NOTREACHED();
347 return false; 395 return false;
348 } 396 }
349 397
350 for (uint32 i = 0; i < v8_array->Length(); ++i) { 398 for (uint32 i = 0; i < v8_array->Length(); ++i) {
351 v8::TryCatch try_catch; 399 v8::TryCatch try_catch;
352 v8::Handle<v8::Value> child_v8 = v8_array->Get(i); 400 v8::Handle<v8::Value> child_v8 = v8_array->Get(i);
353 if (try_catch.HasCaught()) 401 if (try_catch.HasCaught())
354 return false; 402 return false;
355 403
356 if (!v8_array->HasRealIndexedProperty(i)) 404 if (!v8_array->HasRealIndexedProperty(i))
357 continue; 405 continue;
358 406
359 PP_Var child_var; 407 PP_Var child_var;
360 if (!GetOrCreateVar(child_v8, &child_var, &did_create, 408 if (!GetOrCreateVar(child_v8, &child_var, &did_create,
361 &visited_handles)) { 409 &visited_handles, &parent_handles)) {
362 // Silently ignore the case where we can't convert to a Var as we may 410 return false;
363 // be trying to convert a type that doesn't have a corresponding
364 // PP_Var type.
365 continue;
366 } 411 }
367 if (did_create && child_v8->IsObject()) 412 if (did_create && child_v8->IsObject())
368 stack.push(child_v8); 413 stack.push(child_v8);
369 414
370 array_var->Set(i, child_var); 415 array_var->Set(i, child_var);
371 } 416 }
372 } else if (current_var.type == PP_VARTYPE_DICTIONARY) { 417 } else if (current_var.type == PP_VARTYPE_DICTIONARY) {
373 DCHECK(current_v8->IsObject()); 418 DCHECK(current_v8->IsObject());
374 v8::Handle<v8::Object> v8_object = current_v8->ToObject(); 419 v8::Handle<v8::Object> v8_object = current_v8->ToObject();
420 parent_handles.insert(HashedHandle(v8_object));
375 421
376 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var); 422 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var);
377 if (!dict_var) { 423 if (!dict_var) {
378 NOTREACHED(); 424 NOTREACHED();
379 return false; 425 return false;
380 } 426 }
381 427
382 v8::Handle<v8::Array> property_names(v8_object->GetOwnPropertyNames()); 428 v8::Handle<v8::Array> property_names(v8_object->GetOwnPropertyNames());
383 for (uint32 i = 0; i < property_names->Length(); ++i) { 429 for (uint32 i = 0; i < property_names->Length(); ++i) {
384 v8::Handle<v8::Value> key(property_names->Get(i)); 430 v8::Handle<v8::Value> key(property_names->Get(i));
(...skipping 11 matching lines...) Expand all
396 442
397 v8::String::Utf8Value name_utf8(key->ToString()); 443 v8::String::Utf8Value name_utf8(key->ToString());
398 444
399 v8::TryCatch try_catch; 445 v8::TryCatch try_catch;
400 v8::Handle<v8::Value> child_v8 = v8_object->Get(key); 446 v8::Handle<v8::Value> child_v8 = v8_object->Get(key);
401 if (try_catch.HasCaught()) 447 if (try_catch.HasCaught())
402 return false; 448 return false;
403 449
404 PP_Var child_var; 450 PP_Var child_var;
405 if (!GetOrCreateVar(child_v8, &child_var, &did_create, 451 if (!GetOrCreateVar(child_v8, &child_var, &did_create,
406 &visited_handles)) { 452 &visited_handles, &parent_handles)) {
407 continue; 453 return false;
408 } 454 }
409 if (did_create && child_v8->IsObject()) 455 if (did_create && child_v8->IsObject())
410 stack.push(child_v8); 456 stack.push(child_v8);
411 457
412 bool success = dict_var->SetWithStringKey( 458 bool success = dict_var->SetWithStringKey(
413 std::string(*name_utf8, name_utf8.length()), child_var); 459 std::string(*name_utf8, name_utf8.length()), child_var);
414 DCHECK(success); 460 DCHECK(success);
415 } 461 }
416 } 462 }
417 } 463 }
418 *result = root.Release(); 464 *result = root.Release();
419 return true; 465 return true;
420 } 466 }
421 467
468 } // namespace V8VarConverter
422 } // namespace ppapi 469 } // namespace ppapi
423 } // namespace webkit 470 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/v8_var_converter.h ('k') | webkit/plugins/ppapi/v8_var_converter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698