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

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/hash_tables.h" 11 #include "base/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/Source/WebKit/chromium/public/WebArrayBuffer.h" 18 #include "third_party/WebKit/Source/WebKit/chromium/public/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
209 } // namespace 229 } // namespace
210 230
211 V8VarConverter::V8VarConverter() { 231 bool ToV8Value(const PP_Var& var,
212 } 232 v8::Handle<v8::Context> context,
213 233 v8::Handle<v8::Value>* result) {
dmichael (off chromium) 2013/06/05 17:05:47 Without looking carefully, it might be possible to
214 bool V8VarConverter::ToV8Value(const PP_Var& var,
215 v8::Handle<v8::Context> context,
216 v8::Handle<v8::Value>* result) const {
217 v8::Context::Scope context_scope(context); 234 v8::Context::Scope context_scope(context);
218 v8::HandleScope handle_scope; 235 v8::HandleScope handle_scope;
219 236
220 VarHandleMap visited_ids; 237 VarHandleMap visited_ids;
238 ParentVarSet parent_ids;
221 239
222 std::stack<PP_Var> stack; 240 std::stack<StackEntry<PP_Var> > stack;
223 stack.push(var); 241 stack.push(StackEntry<PP_Var>(var));
224 v8::Handle<v8::Value> root; 242 v8::Handle<v8::Value> root;
225 bool is_root = true; 243 bool is_root = true;
226 244
227 while (!stack.empty()) { 245 while (!stack.empty()) {
228 const PP_Var& current_var = stack.top(); 246 const PP_Var& current_var = stack.top().val;
229 v8::Handle<v8::Value> current_v8; 247 v8::Handle<v8::Value> current_v8;
230 stack.pop(); 248
249 if (stack.top().sentinel) {
250 stack.pop();
251 if (::ppapi::VarTracker::IsVarTypeRefcounted(current_var.type))
252 parent_ids.erase(current_var.value.as_id);
253 continue;
254 } else {
255 stack.top().sentinel = true;
256 }
257
231 bool did_create = false; 258 bool did_create = false;
232 if (!GetOrCreateV8Value(current_var, &current_v8, &did_create, 259 if (!GetOrCreateV8Value(current_var, &current_v8, &did_create,
233 &visited_ids)) { 260 &visited_ids, &parent_ids)) {
234 return false; 261 return false;
235 } 262 }
236 263
237 if (is_root) { 264 if (is_root) {
238 is_root = false; 265 is_root = false;
239 root = current_v8; 266 root = current_v8;
240 } 267 }
241 268
242 // Add child nodes to the stack. 269 // Add child nodes to the stack.
243 if (current_var.type == PP_VARTYPE_ARRAY) { 270 if (current_var.type == PP_VARTYPE_ARRAY) {
271 parent_ids.insert(current_var.value.as_id);
244 ArrayVar* array_var = ArrayVar::FromPPVar(current_var); 272 ArrayVar* array_var = ArrayVar::FromPPVar(current_var);
245 if (!array_var) { 273 if (!array_var) {
246 NOTREACHED(); 274 NOTREACHED();
247 return false; 275 return false;
248 } 276 }
249 DCHECK(current_v8->IsArray()); 277 DCHECK(current_v8->IsArray());
250 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>(); 278 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>();
251 279
252 for (size_t i = 0; i < array_var->elements().size(); ++i) { 280 for (size_t i = 0; i < array_var->elements().size(); ++i) {
253 const PP_Var& child_var = array_var->elements()[i].get(); 281 const PP_Var& child_var = array_var->elements()[i].get();
254 v8::Handle<v8::Value> child_v8; 282 v8::Handle<v8::Value> child_v8;
255 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create, 283 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create,
256 &visited_ids)) { 284 &visited_ids, &parent_ids)) {
257 return false; 285 return false;
258 } 286 }
259 if (did_create && 287 if (did_create &&
260 (child_var.type == PP_VARTYPE_DICTIONARY || 288 (child_var.type == PP_VARTYPE_DICTIONARY ||
261 child_var.type == PP_VARTYPE_ARRAY)) { 289 child_var.type == PP_VARTYPE_ARRAY)) {
262 stack.push(child_var); 290 stack.push(child_var);
263 } 291 }
264 v8::TryCatch try_catch; 292 v8::TryCatch try_catch;
265 v8_array->Set(static_cast<uint32>(i), child_v8); 293 v8_array->Set(static_cast<uint32>(i), child_v8);
266 if (try_catch.HasCaught()) { 294 if (try_catch.HasCaught()) {
267 LOG(ERROR) << "Setter for index " << i << " threw an exception."; 295 LOG(ERROR) << "Setter for index " << i << " threw an exception.";
268 return false; 296 return false;
269 } 297 }
270 } 298 }
271 } else if (current_var.type == PP_VARTYPE_DICTIONARY) { 299 } else if (current_var.type == PP_VARTYPE_DICTIONARY) {
300 parent_ids.insert(current_var.value.as_id);
272 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var); 301 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var);
273 if (!dict_var) { 302 if (!dict_var) {
274 NOTREACHED(); 303 NOTREACHED();
275 return false; 304 return false;
276 } 305 }
277 DCHECK(current_v8->IsObject()); 306 DCHECK(current_v8->IsObject());
278 v8::Handle<v8::Object> v8_object = current_v8->ToObject(); 307 v8::Handle<v8::Object> v8_object = current_v8->ToObject();
279 308
280 for (DictionaryVar::KeyValueMap::const_iterator iter = 309 for (DictionaryVar::KeyValueMap::const_iterator iter =
281 dict_var->key_value_map().begin(); 310 dict_var->key_value_map().begin();
282 iter != dict_var->key_value_map().end(); 311 iter != dict_var->key_value_map().end();
283 ++iter) { 312 ++iter) {
284 const std::string& key = iter->first; 313 const std::string& key = iter->first;
285 const PP_Var& child_var = iter->second.get(); 314 const PP_Var& child_var = iter->second.get();
286 v8::Handle<v8::Value> child_v8; 315 v8::Handle<v8::Value> child_v8;
287 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create, 316 if (!GetOrCreateV8Value(child_var, &child_v8, &did_create,
288 &visited_ids)) { 317 &visited_ids, &parent_ids)) {
289 return false; 318 return false;
290 } 319 }
291 if (did_create && 320 if (did_create &&
292 (child_var.type == PP_VARTYPE_DICTIONARY || 321 (child_var.type == PP_VARTYPE_DICTIONARY ||
293 child_var.type == PP_VARTYPE_ARRAY)) { 322 child_var.type == PP_VARTYPE_ARRAY)) {
294 stack.push(child_var); 323 stack.push(child_var);
295 } 324 }
296 v8::TryCatch try_catch; 325 v8::TryCatch try_catch;
297 v8_object->Set(v8::String::New(key.c_str(), key.length()), child_v8); 326 v8_object->Set(v8::String::New(key.c_str(), key.length()), child_v8);
298 if (try_catch.HasCaught()) { 327 if (try_catch.HasCaught()) {
299 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an " 328 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an "
300 << "exception."; 329 << "exception.";
301 return false; 330 return false;
302 } 331 }
303 } 332 }
304 } 333 }
305 } 334 }
306 335
307 *result = handle_scope.Close(root); 336 *result = handle_scope.Close(root);
308 return true; 337 return true;
309 } 338 }
310 339
311 bool V8VarConverter::FromV8Value(v8::Handle<v8::Value> val, 340 bool FromV8Value(v8::Handle<v8::Value> val,
312 v8::Handle<v8::Context> context, 341 v8::Handle<v8::Context> context,
313 PP_Var* result) const { 342 PP_Var* result) {
314 v8::Context::Scope context_scope(context); 343 v8::Context::Scope context_scope(context);
315 v8::HandleScope handle_scope; 344 v8::HandleScope handle_scope;
316 345
317 HandleVarMap visited_handles; 346 HandleVarMap visited_handles;
347 ParentHandleSet parent_handles;
318 348
319 std::stack<v8::Handle<v8::Value> > stack; 349 std::stack<StackEntry<v8::Handle<v8::Value> > > stack;
320 stack.push(val); 350 stack.push(StackEntry<v8::Handle<v8::Value> >(val));
321 ScopedPPVar root; 351 ScopedPPVar root;
322 bool is_root = true; 352 bool is_root = true;
323 353
324 while (!stack.empty()) { 354 while (!stack.empty()) {
325 v8::Handle<v8::Value> current_v8 = stack.top(); 355 v8::Handle<v8::Value> current_v8 = stack.top().val;
326 PP_Var current_var; 356 PP_Var current_var;
327 stack.pop(); 357
358 if (stack.top().sentinel) {
359 stack.pop();
360 if (current_v8->IsObject())
361 parent_handles.erase(HashedHandle(current_v8->ToObject()));
362 continue;
363 } else {
364 stack.top().sentinel = true;
365 }
366
328 bool did_create = false; 367 bool did_create = false;
329 if (!GetOrCreateVar(current_v8, &current_var, &did_create, 368 if (!GetOrCreateVar(current_v8, &current_var, &did_create,
330 &visited_handles)) { 369 &visited_handles, &parent_handles)) {
331 return false; 370 return false;
332 } 371 }
333 372
334 if (is_root) { 373 if (is_root) {
335 is_root = false; 374 is_root = false;
336 root = current_var; 375 root = current_var;
337 } 376 }
338 377
339 // Add child nodes to the stack. 378 // Add child nodes to the stack.
340 if (current_var.type == PP_VARTYPE_ARRAY) { 379 if (current_var.type == PP_VARTYPE_ARRAY) {
341 DCHECK(current_v8->IsArray()); 380 DCHECK(current_v8->IsArray());
342 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>(); 381 v8::Handle<v8::Array> v8_array = current_v8.As<v8::Array>();
382 parent_handles.insert(HashedHandle(v8_array));
343 383
344 ArrayVar* array_var = ArrayVar::FromPPVar(current_var); 384 ArrayVar* array_var = ArrayVar::FromPPVar(current_var);
345 if (!array_var) { 385 if (!array_var) {
346 NOTREACHED(); 386 NOTREACHED();
347 return false; 387 return false;
348 } 388 }
349 389
350 for (uint32 i = 0; i < v8_array->Length(); ++i) { 390 for (uint32 i = 0; i < v8_array->Length(); ++i) {
351 v8::TryCatch try_catch; 391 v8::TryCatch try_catch;
352 v8::Handle<v8::Value> child_v8 = v8_array->Get(i); 392 v8::Handle<v8::Value> child_v8 = v8_array->Get(i);
353 if (try_catch.HasCaught()) 393 if (try_catch.HasCaught())
354 return false; 394 return false;
355 395
356 if (!v8_array->HasRealIndexedProperty(i)) 396 if (!v8_array->HasRealIndexedProperty(i))
357 continue; 397 continue;
358 398
359 PP_Var child_var; 399 PP_Var child_var;
360 if (!GetOrCreateVar(child_v8, &child_var, &did_create, 400 if (!GetOrCreateVar(child_v8, &child_var, &did_create,
361 &visited_handles)) { 401 &visited_handles, &parent_handles)) {
362 // Silently ignore the case where we can't convert to a Var as we may 402 return false;
363 // be trying to convert a type that doesn't have a corresponding
364 // PP_Var type.
365 continue;
366 } 403 }
367 if (did_create && child_v8->IsObject()) 404 if (did_create && child_v8->IsObject())
368 stack.push(child_v8); 405 stack.push(child_v8);
369 406
370 array_var->Set(i, child_var); 407 array_var->Set(i, child_var);
371 } 408 }
372 } else if (current_var.type == PP_VARTYPE_DICTIONARY) { 409 } else if (current_var.type == PP_VARTYPE_DICTIONARY) {
373 DCHECK(current_v8->IsObject()); 410 DCHECK(current_v8->IsObject());
374 v8::Handle<v8::Object> v8_object = current_v8->ToObject(); 411 v8::Handle<v8::Object> v8_object = current_v8->ToObject();
412 parent_handles.insert(HashedHandle(v8_object));
375 413
376 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var); 414 DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var);
377 if (!dict_var) { 415 if (!dict_var) {
378 NOTREACHED(); 416 NOTREACHED();
379 return false; 417 return false;
380 } 418 }
381 419
382 v8::Handle<v8::Array> property_names(v8_object->GetOwnPropertyNames()); 420 v8::Handle<v8::Array> property_names(v8_object->GetOwnPropertyNames());
383 for (uint32 i = 0; i < property_names->Length(); ++i) { 421 for (uint32 i = 0; i < property_names->Length(); ++i) {
384 v8::Handle<v8::Value> key(property_names->Get(i)); 422 v8::Handle<v8::Value> key(property_names->Get(i));
(...skipping 11 matching lines...) Expand all
396 434
397 v8::String::Utf8Value name_utf8(key->ToString()); 435 v8::String::Utf8Value name_utf8(key->ToString());
398 436
399 v8::TryCatch try_catch; 437 v8::TryCatch try_catch;
400 v8::Handle<v8::Value> child_v8 = v8_object->Get(key); 438 v8::Handle<v8::Value> child_v8 = v8_object->Get(key);
401 if (try_catch.HasCaught()) 439 if (try_catch.HasCaught())
402 return false; 440 return false;
403 441
404 PP_Var child_var; 442 PP_Var child_var;
405 if (!GetOrCreateVar(child_v8, &child_var, &did_create, 443 if (!GetOrCreateVar(child_v8, &child_var, &did_create,
406 &visited_handles)) { 444 &visited_handles, &parent_handles)) {
407 continue; 445 return false;
408 } 446 }
409 if (did_create && child_v8->IsObject()) 447 if (did_create && child_v8->IsObject())
410 stack.push(child_v8); 448 stack.push(child_v8);
411 449
412 bool success = dict_var->SetWithStringKey( 450 bool success = dict_var->SetWithStringKey(
413 std::string(*name_utf8, name_utf8.length()), child_var); 451 std::string(*name_utf8, name_utf8.length()), child_var);
414 DCHECK(success); 452 DCHECK(success);
415 } 453 }
416 } 454 }
417 } 455 }
418 *result = root.Release(); 456 *result = root.Release();
419 return true; 457 return true;
420 } 458 }
421 459
460 } // namespace V8VarConverter
422 } // namespace ppapi 461 } // namespace ppapi
423 } // namespace webkit 462 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698