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

Side by Side Diff: content/child/v8_value_converter_impl.cc

Issue 1113783002: Use Local instead of Handle in src/content/* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/child/v8_value_converter_impl.h" 5 #include "content/child/v8_value_converter_impl.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.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 "base/values.h" 14 #include "base/values.h"
15 #include "third_party/WebKit/public/web/WebArrayBuffer.h" 15 #include "third_party/WebKit/public/web/WebArrayBuffer.h"
16 #include "third_party/WebKit/public/web/WebArrayBufferConverter.h" 16 #include "third_party/WebKit/public/web/WebArrayBufferConverter.h"
17 #include "third_party/WebKit/public/web/WebArrayBufferView.h" 17 #include "third_party/WebKit/public/web/WebArrayBufferView.h"
18 #include "v8/include/v8.h" 18 #include "v8/include/v8.h"
19 19
20 namespace content { 20 namespace content {
21 21
22 // Default implementation of V8ValueConverter::Strategy 22 // Default implementation of V8ValueConverter::Strategy
23 23
24 bool V8ValueConverter::Strategy::FromV8Object( 24 bool V8ValueConverter::Strategy::FromV8Object(
25 v8::Handle<v8::Object> value, 25 v8::Local<v8::Object> value,
26 base::Value** out, 26 base::Value** out,
27 v8::Isolate* isolate, 27 v8::Isolate* isolate,
28 const FromV8ValueCallback& callback) const { 28 const FromV8ValueCallback& callback) const {
29 return false; 29 return false;
30 } 30 }
31 31
32 bool V8ValueConverter::Strategy::FromV8Array( 32 bool V8ValueConverter::Strategy::FromV8Array(
33 v8::Handle<v8::Array> value, 33 v8::Local<v8::Array> value,
34 base::Value** out, 34 base::Value** out,
35 v8::Isolate* isolate, 35 v8::Isolate* isolate,
36 const FromV8ValueCallback& callback) const { 36 const FromV8ValueCallback& callback) const {
37 return false; 37 return false;
38 } 38 }
39 39
40 bool V8ValueConverter::Strategy::FromV8ArrayBuffer(v8::Handle<v8::Object> value, 40 bool V8ValueConverter::Strategy::FromV8ArrayBuffer(v8::Local<v8::Object> value,
41 base::Value** out, 41 base::Value** out,
42 v8::Isolate* isolate) const { 42 v8::Isolate* isolate) const {
43 return false; 43 return false;
44 } 44 }
45 45
46 bool V8ValueConverter::Strategy::FromV8Number(v8::Handle<v8::Number> value, 46 bool V8ValueConverter::Strategy::FromV8Number(v8::Local<v8::Number> value,
47 base::Value** out) const { 47 base::Value** out) const {
48 return false; 48 return false;
49 } 49 }
50 50
51 bool V8ValueConverter::Strategy::FromV8Undefined(base::Value** out) const { 51 bool V8ValueConverter::Strategy::FromV8Undefined(base::Value** out) const {
52 return false; 52 return false;
53 } 53 }
54 54
55 55
56 namespace { 56 namespace {
(...skipping 24 matching lines...) Expand all
81 : max_recursion_depth_(kMaxRecursionDepth), 81 : max_recursion_depth_(kMaxRecursionDepth),
82 avoid_identity_hash_for_testing_(avoid_identity_hash_for_testing) {} 82 avoid_identity_hash_for_testing_(avoid_identity_hash_for_testing) {}
83 83
84 // If |handle| is not in |unique_map_|, then add it to |unique_map_| and 84 // If |handle| is not in |unique_map_|, then add it to |unique_map_| and
85 // return true. 85 // return true.
86 // 86 //
87 // Otherwise do nothing and return false. Here "A is unique" means that no 87 // Otherwise do nothing and return false. Here "A is unique" means that no
88 // other handle B in the map points to the same object as A. Note that A can 88 // other handle B in the map points to the same object as A. Note that A can
89 // be unique even if there already is another handle with the same identity 89 // be unique even if there already is another handle with the same identity
90 // hash (key) in the map, because two objects can have the same hash. 90 // hash (key) in the map, because two objects can have the same hash.
91 bool UpdateAndCheckUniqueness(v8::Handle<v8::Object> handle) { 91 bool UpdateAndCheckUniqueness(v8::Local<v8::Object> handle) {
92 typedef HashToHandleMap::const_iterator Iterator; 92 typedef HashToHandleMap::const_iterator Iterator;
93 int hash = avoid_identity_hash_for_testing_ ? 0 : handle->GetIdentityHash(); 93 int hash = avoid_identity_hash_for_testing_ ? 0 : handle->GetIdentityHash();
94 // We only compare using == with handles to objects with the same identity 94 // We only compare using == with handles to objects with the same identity
95 // hash. Different hash obviously means different objects, but two objects 95 // hash. Different hash obviously means different objects, but two objects
96 // in a couple of thousands could have the same identity hash. 96 // in a couple of thousands could have the same identity hash.
97 std::pair<Iterator, Iterator> range = unique_map_.equal_range(hash); 97 std::pair<Iterator, Iterator> range = unique_map_.equal_range(hash);
98 for (Iterator it = range.first; it != range.second; ++it) { 98 for (Iterator it = range.first; it != range.second; ++it) {
99 // Operator == for handles actually compares the underlying objects. 99 // Operator == for handles actually compares the underlying objects.
100 if (it->second == handle) 100 if (it->second == handle)
101 return false; 101 return false;
102 } 102 }
103 unique_map_.insert(std::make_pair(hash, handle)); 103 unique_map_.insert(std::make_pair(hash, handle));
104 return true; 104 return true;
105 } 105 }
106 106
107 bool HasReachedMaxRecursionDepth() { 107 bool HasReachedMaxRecursionDepth() {
108 return max_recursion_depth_ < 0; 108 return max_recursion_depth_ < 0;
109 } 109 }
110 110
111 private: 111 private:
112 typedef std::multimap<int, v8::Handle<v8::Object> > HashToHandleMap; 112 typedef std::multimap<int, v8::Local<v8::Object> > HashToHandleMap;
113 HashToHandleMap unique_map_; 113 HashToHandleMap unique_map_;
114 114
115 int max_recursion_depth_; 115 int max_recursion_depth_;
116 116
117 bool avoid_identity_hash_for_testing_; 117 bool avoid_identity_hash_for_testing_;
118 }; 118 };
119 119
120 V8ValueConverter* V8ValueConverter::create() { 120 V8ValueConverter* V8ValueConverter::create() {
121 return new V8ValueConverterImpl(); 121 return new V8ValueConverterImpl();
122 } 122 }
(...skipping 19 matching lines...) Expand all
142 } 142 }
143 143
144 void V8ValueConverterImpl::SetStripNullFromObjects(bool val) { 144 void V8ValueConverterImpl::SetStripNullFromObjects(bool val) {
145 strip_null_from_objects_ = val; 145 strip_null_from_objects_ = val;
146 } 146 }
147 147
148 void V8ValueConverterImpl::SetStrategy(Strategy* strategy) { 148 void V8ValueConverterImpl::SetStrategy(Strategy* strategy) {
149 strategy_ = strategy; 149 strategy_ = strategy;
150 } 150 }
151 151
152 v8::Handle<v8::Value> V8ValueConverterImpl::ToV8Value( 152 v8::Local<v8::Value> V8ValueConverterImpl::ToV8Value(
153 const base::Value* value, v8::Handle<v8::Context> context) const { 153 const base::Value* value, v8::Local<v8::Context> context) const {
154 v8::Context::Scope context_scope(context); 154 v8::Context::Scope context_scope(context);
155 v8::EscapableHandleScope handle_scope(context->GetIsolate()); 155 v8::EscapableHandleScope handle_scope(context->GetIsolate());
156 return handle_scope.Escape( 156 return handle_scope.Escape(
157 ToV8ValueImpl(context->GetIsolate(), context->Global(), value)); 157 ToV8ValueImpl(context->GetIsolate(), context->Global(), value));
158 } 158 }
159 159
160 base::Value* V8ValueConverterImpl::FromV8Value( 160 base::Value* V8ValueConverterImpl::FromV8Value(
161 v8::Handle<v8::Value> val, 161 v8::Local<v8::Value> val,
162 v8::Handle<v8::Context> context) const { 162 v8::Local<v8::Context> context) const {
163 v8::Context::Scope context_scope(context); 163 v8::Context::Scope context_scope(context);
164 v8::HandleScope handle_scope(context->GetIsolate()); 164 v8::HandleScope handle_scope(context->GetIsolate());
165 FromV8ValueState state(avoid_identity_hash_for_testing_); 165 FromV8ValueState state(avoid_identity_hash_for_testing_);
166 return FromV8ValueImpl(&state, val, context->GetIsolate()); 166 return FromV8ValueImpl(&state, val, context->GetIsolate());
167 } 167 }
168 168
169 v8::Local<v8::Value> V8ValueConverterImpl::ToV8ValueImpl( 169 v8::Local<v8::Value> V8ValueConverterImpl::ToV8ValueImpl(
170 v8::Isolate* isolate, 170 v8::Isolate* isolate,
171 v8::Handle<v8::Object> creation_context, 171 v8::Local<v8::Object> creation_context,
172 const base::Value* value) const { 172 const base::Value* value) const {
173 CHECK(value); 173 CHECK(value);
174 switch (value->GetType()) { 174 switch (value->GetType()) {
175 case base::Value::TYPE_NULL: 175 case base::Value::TYPE_NULL:
176 return v8::Null(isolate); 176 return v8::Null(isolate);
177 177
178 case base::Value::TYPE_BOOLEAN: { 178 case base::Value::TYPE_BOOLEAN: {
179 bool val = false; 179 bool val = false;
180 CHECK(value->GetAsBoolean(&val)); 180 CHECK(value->GetAsBoolean(&val));
181 return v8::Boolean::New(isolate, val); 181 return v8::Boolean::New(isolate, val);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 return ToArrayBuffer(isolate, 214 return ToArrayBuffer(isolate,
215 creation_context, 215 creation_context,
216 static_cast<const base::BinaryValue*>(value)); 216 static_cast<const base::BinaryValue*>(value));
217 217
218 default: 218 default:
219 LOG(ERROR) << "Unexpected value type: " << value->GetType(); 219 LOG(ERROR) << "Unexpected value type: " << value->GetType();
220 return v8::Null(isolate); 220 return v8::Null(isolate);
221 } 221 }
222 } 222 }
223 223
224 v8::Handle<v8::Value> V8ValueConverterImpl::ToV8Array( 224 v8::Local<v8::Value> V8ValueConverterImpl::ToV8Array(
225 v8::Isolate* isolate, 225 v8::Isolate* isolate,
226 v8::Handle<v8::Object> creation_context, 226 v8::Local<v8::Object> creation_context,
227 const base::ListValue* val) const { 227 const base::ListValue* val) const {
228 v8::Handle<v8::Array> result(v8::Array::New(isolate, val->GetSize())); 228 v8::Local<v8::Array> result(v8::Array::New(isolate, val->GetSize()));
229 229
230 for (size_t i = 0; i < val->GetSize(); ++i) { 230 for (size_t i = 0; i < val->GetSize(); ++i) {
231 const base::Value* child = NULL; 231 const base::Value* child = NULL;
232 CHECK(val->Get(i, &child)); 232 CHECK(val->Get(i, &child));
233 233
234 v8::Handle<v8::Value> child_v8 = 234 v8::Local<v8::Value> child_v8 =
235 ToV8ValueImpl(isolate, creation_context, child); 235 ToV8ValueImpl(isolate, creation_context, child);
236 CHECK(!child_v8.IsEmpty()); 236 CHECK(!child_v8.IsEmpty());
237 237
238 v8::TryCatch try_catch; 238 v8::TryCatch try_catch;
239 result->Set(static_cast<uint32>(i), child_v8); 239 result->Set(static_cast<uint32>(i), child_v8);
240 if (try_catch.HasCaught()) 240 if (try_catch.HasCaught())
241 LOG(ERROR) << "Setter for index " << i << " threw an exception."; 241 LOG(ERROR) << "Setter for index " << i << " threw an exception.";
242 } 242 }
243 243
244 return result; 244 return result;
245 } 245 }
246 246
247 v8::Handle<v8::Value> V8ValueConverterImpl::ToV8Object( 247 v8::Local<v8::Value> V8ValueConverterImpl::ToV8Object(
248 v8::Isolate* isolate, 248 v8::Isolate* isolate,
249 v8::Handle<v8::Object> creation_context, 249 v8::Local<v8::Object> creation_context,
250 const base::DictionaryValue* val) const { 250 const base::DictionaryValue* val) const {
251 v8::Handle<v8::Object> result(v8::Object::New(isolate)); 251 v8::Local<v8::Object> result(v8::Object::New(isolate));
252 252
253 for (base::DictionaryValue::Iterator iter(*val); 253 for (base::DictionaryValue::Iterator iter(*val);
254 !iter.IsAtEnd(); iter.Advance()) { 254 !iter.IsAtEnd(); iter.Advance()) {
255 const std::string& key = iter.key(); 255 const std::string& key = iter.key();
256 v8::Handle<v8::Value> child_v8 = 256 v8::Local<v8::Value> child_v8 =
257 ToV8ValueImpl(isolate, creation_context, &iter.value()); 257 ToV8ValueImpl(isolate, creation_context, &iter.value());
258 CHECK(!child_v8.IsEmpty()); 258 CHECK(!child_v8.IsEmpty());
259 259
260 v8::TryCatch try_catch; 260 v8::TryCatch try_catch;
261 result->Set( 261 result->Set(
262 v8::String::NewFromUtf8( 262 v8::String::NewFromUtf8(
263 isolate, key.c_str(), v8::String::kNormalString, key.length()), 263 isolate, key.c_str(), v8::String::kNormalString, key.length()),
264 child_v8); 264 child_v8);
265 if (try_catch.HasCaught()) { 265 if (try_catch.HasCaught()) {
266 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an " 266 LOG(ERROR) << "Setter for property " << key.c_str() << " threw an "
267 << "exception."; 267 << "exception.";
268 } 268 }
269 } 269 }
270 270
271 return result; 271 return result;
272 } 272 }
273 273
274 v8::Handle<v8::Value> V8ValueConverterImpl::ToArrayBuffer( 274 v8::Local<v8::Value> V8ValueConverterImpl::ToArrayBuffer(
275 v8::Isolate* isolate, 275 v8::Isolate* isolate,
276 v8::Handle<v8::Object> creation_context, 276 v8::Local<v8::Object> creation_context,
277 const base::BinaryValue* value) const { 277 const base::BinaryValue* value) const {
278 blink::WebArrayBuffer buffer = 278 blink::WebArrayBuffer buffer =
279 blink::WebArrayBuffer::create(value->GetSize(), 1); 279 blink::WebArrayBuffer::create(value->GetSize(), 1);
280 memcpy(buffer.data(), value->GetBuffer(), value->GetSize()); 280 memcpy(buffer.data(), value->GetBuffer(), value->GetSize());
281 return blink::WebArrayBufferConverter::toV8Value( 281 return blink::WebArrayBufferConverter::toV8Value(
282 &buffer, creation_context, isolate); 282 &buffer, creation_context, isolate);
283 } 283 }
284 284
285 base::Value* V8ValueConverterImpl::FromV8ValueImpl( 285 base::Value* V8ValueConverterImpl::FromV8ValueImpl(
286 FromV8ValueState* state, 286 FromV8ValueState* state,
287 v8::Handle<v8::Value> val, 287 v8::Local<v8::Value> val,
288 v8::Isolate* isolate) const { 288 v8::Isolate* isolate) const {
289 CHECK(!val.IsEmpty()); 289 CHECK(!val.IsEmpty());
290 290
291 FromV8ValueState::Level state_level(state); 291 FromV8ValueState::Level state_level(state);
292 if (state->HasReachedMaxRecursionDepth()) 292 if (state->HasReachedMaxRecursionDepth())
293 return NULL; 293 return NULL;
294 294
295 if (val->IsNull()) 295 if (val->IsNull())
296 return base::Value::CreateNullValue(); 296 return base::Value::CreateNullValue();
297 297
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 return FromV8ArrayBuffer(val.As<v8::Object>(), isolate); 360 return FromV8ArrayBuffer(val.As<v8::Object>(), isolate);
361 361
362 if (val->IsObject()) 362 if (val->IsObject())
363 return FromV8Object(val.As<v8::Object>(), state, isolate); 363 return FromV8Object(val.As<v8::Object>(), state, isolate);
364 364
365 LOG(ERROR) << "Unexpected v8 value type encountered."; 365 LOG(ERROR) << "Unexpected v8 value type encountered.";
366 return NULL; 366 return NULL;
367 } 367 }
368 368
369 base::Value* V8ValueConverterImpl::FromV8Array( 369 base::Value* V8ValueConverterImpl::FromV8Array(
370 v8::Handle<v8::Array> val, 370 v8::Local<v8::Array> val,
371 FromV8ValueState* state, 371 FromV8ValueState* state,
372 v8::Isolate* isolate) const { 372 v8::Isolate* isolate) const {
373 if (!state->UpdateAndCheckUniqueness(val)) 373 if (!state->UpdateAndCheckUniqueness(val))
374 return base::Value::CreateNullValue(); 374 return base::Value::CreateNullValue();
375 375
376 scoped_ptr<v8::Context::Scope> scope; 376 scoped_ptr<v8::Context::Scope> scope;
377 // If val was created in a different context than our current one, change to 377 // If val was created in a different context than our current one, change to
378 // that context, but change back after val is converted. 378 // that context, but change back after val is converted.
379 if (!val->CreationContext().IsEmpty() && 379 if (!val->CreationContext().IsEmpty() &&
380 val->CreationContext() != isolate->GetCurrentContext()) 380 val->CreationContext() != isolate->GetCurrentContext())
381 scope.reset(new v8::Context::Scope(val->CreationContext())); 381 scope.reset(new v8::Context::Scope(val->CreationContext()));
382 382
383 if (strategy_) { 383 if (strategy_) {
384 // These base::Unretained's are safe, because Strategy::FromV8Value should 384 // These base::Unretained's are safe, because Strategy::FromV8Value should
385 // be synchronous, so this object can't be out of scope. 385 // be synchronous, so this object can't be out of scope.
386 V8ValueConverter::Strategy::FromV8ValueCallback callback = 386 V8ValueConverter::Strategy::FromV8ValueCallback callback =
387 base::Bind(&V8ValueConverterImpl::FromV8ValueImpl, 387 base::Bind(&V8ValueConverterImpl::FromV8ValueImpl,
388 base::Unretained(this), 388 base::Unretained(this),
389 base::Unretained(state)); 389 base::Unretained(state));
390 base::Value* out = NULL; 390 base::Value* out = NULL;
391 if (strategy_->FromV8Array(val, &out, isolate, callback)) 391 if (strategy_->FromV8Array(val, &out, isolate, callback))
392 return out; 392 return out;
393 } 393 }
394 394
395 base::ListValue* result = new base::ListValue(); 395 base::ListValue* result = new base::ListValue();
396 396
397 // Only fields with integer keys are carried over to the ListValue. 397 // Only fields with integer keys are carried over to the ListValue.
398 for (uint32 i = 0; i < val->Length(); ++i) { 398 for (uint32 i = 0; i < val->Length(); ++i) {
399 v8::TryCatch try_catch; 399 v8::TryCatch try_catch;
400 v8::Handle<v8::Value> child_v8 = val->Get(i); 400 v8::Local<v8::Value> child_v8 = val->Get(i);
401 if (try_catch.HasCaught()) { 401 if (try_catch.HasCaught()) {
402 LOG(ERROR) << "Getter for index " << i << " threw an exception."; 402 LOG(ERROR) << "Getter for index " << i << " threw an exception.";
403 child_v8 = v8::Null(isolate); 403 child_v8 = v8::Null(isolate);
404 } 404 }
405 405
406 if (!val->HasRealIndexedProperty(i)) { 406 if (!val->HasRealIndexedProperty(i)) {
407 result->Append(base::Value::CreateNullValue()); 407 result->Append(base::Value::CreateNullValue());
408 continue; 408 continue;
409 } 409 }
410 410
411 base::Value* child = FromV8ValueImpl(state, child_v8, isolate); 411 base::Value* child = FromV8ValueImpl(state, child_v8, isolate);
412 if (child) 412 if (child)
413 result->Append(child); 413 result->Append(child);
414 else 414 else
415 // JSON.stringify puts null in places where values don't serialize, for 415 // JSON.stringify puts null in places where values don't serialize, for
416 // example undefined and functions. Emulate that behavior. 416 // example undefined and functions. Emulate that behavior.
417 result->Append(base::Value::CreateNullValue()); 417 result->Append(base::Value::CreateNullValue());
418 } 418 }
419 return result; 419 return result;
420 } 420 }
421 421
422 base::Value* V8ValueConverterImpl::FromV8ArrayBuffer( 422 base::Value* V8ValueConverterImpl::FromV8ArrayBuffer(
423 v8::Handle<v8::Object> val, 423 v8::Local<v8::Object> val,
424 v8::Isolate* isolate) const { 424 v8::Isolate* isolate) const {
425 if (strategy_) { 425 if (strategy_) {
426 base::Value* out = NULL; 426 base::Value* out = NULL;
427 if (strategy_->FromV8ArrayBuffer(val, &out, isolate)) 427 if (strategy_->FromV8ArrayBuffer(val, &out, isolate))
428 return out; 428 return out;
429 } 429 }
430 430
431 char* data = NULL; 431 char* data = NULL;
432 size_t length = 0; 432 size_t length = 0;
433 433
(...skipping 11 matching lines...) Expand all
445 } 445 }
446 } 446 }
447 447
448 if (data) 448 if (data)
449 return base::BinaryValue::CreateWithCopiedBuffer(data, length); 449 return base::BinaryValue::CreateWithCopiedBuffer(data, length);
450 else 450 else
451 return NULL; 451 return NULL;
452 } 452 }
453 453
454 base::Value* V8ValueConverterImpl::FromV8Object( 454 base::Value* V8ValueConverterImpl::FromV8Object(
455 v8::Handle<v8::Object> val, 455 v8::Local<v8::Object> val,
456 FromV8ValueState* state, 456 FromV8ValueState* state,
457 v8::Isolate* isolate) const { 457 v8::Isolate* isolate) const {
458 if (!state->UpdateAndCheckUniqueness(val)) 458 if (!state->UpdateAndCheckUniqueness(val))
459 return base::Value::CreateNullValue(); 459 return base::Value::CreateNullValue();
460 460
461 scoped_ptr<v8::Context::Scope> scope; 461 scoped_ptr<v8::Context::Scope> scope;
462 // If val was created in a different context than our current one, change to 462 // If val was created in a different context than our current one, change to
463 // that context, but change back after val is converted. 463 // that context, but change back after val is converted.
464 if (!val->CreationContext().IsEmpty() && 464 if (!val->CreationContext().IsEmpty() &&
465 val->CreationContext() != isolate->GetCurrentContext()) 465 val->CreationContext() != isolate->GetCurrentContext())
(...skipping 21 matching lines...) Expand all
487 // 487 //
488 // NOTE: check this after |strategy_| so that callers have a chance to 488 // NOTE: check this after |strategy_| so that callers have a chance to
489 // do something else, such as convert to the node's name rather than NULL. 489 // do something else, such as convert to the node's name rather than NULL.
490 // 490 //
491 // ANOTHER NOTE: returning an empty dictionary here to minimise surprise. 491 // ANOTHER NOTE: returning an empty dictionary here to minimise surprise.
492 // See also http://crbug.com/330559. 492 // See also http://crbug.com/330559.
493 if (val->InternalFieldCount()) 493 if (val->InternalFieldCount())
494 return new base::DictionaryValue(); 494 return new base::DictionaryValue();
495 495
496 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue()); 496 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
497 v8::Handle<v8::Array> property_names(val->GetOwnPropertyNames()); 497 v8::Local<v8::Array> property_names(val->GetOwnPropertyNames());
498 498
499 for (uint32 i = 0; i < property_names->Length(); ++i) { 499 for (uint32 i = 0; i < property_names->Length(); ++i) {
500 v8::Handle<v8::Value> key(property_names->Get(i)); 500 v8::Local<v8::Value> key(property_names->Get(i));
501 501
502 // Extend this test to cover more types as necessary and if sensible. 502 // Extend this test to cover more types as necessary and if sensible.
503 if (!key->IsString() && 503 if (!key->IsString() &&
504 !key->IsNumber()) { 504 !key->IsNumber()) {
505 NOTREACHED() << "Key \"" << *v8::String::Utf8Value(key) << "\" " 505 NOTREACHED() << "Key \"" << *v8::String::Utf8Value(key) << "\" "
506 "is neither a string nor a number"; 506 "is neither a string nor a number";
507 continue; 507 continue;
508 } 508 }
509 509
510 v8::String::Utf8Value name_utf8(key); 510 v8::String::Utf8Value name_utf8(key);
511 511
512 v8::TryCatch try_catch; 512 v8::TryCatch try_catch;
513 v8::Handle<v8::Value> child_v8 = val->Get(key); 513 v8::Local<v8::Value> child_v8 = val->Get(key);
514 514
515 if (try_catch.HasCaught()) { 515 if (try_catch.HasCaught()) {
516 LOG(WARNING) << "Getter for property " << *name_utf8 516 LOG(WARNING) << "Getter for property " << *name_utf8
517 << " threw an exception."; 517 << " threw an exception.";
518 child_v8 = v8::Null(isolate); 518 child_v8 = v8::Null(isolate);
519 } 519 }
520 520
521 scoped_ptr<base::Value> child(FromV8ValueImpl(state, child_v8, isolate)); 521 scoped_ptr<base::Value> child(FromV8ValueImpl(state, child_v8, isolate));
522 if (!child) 522 if (!child)
523 // JSON.stringify skips properties whose values don't serialize, for 523 // JSON.stringify skips properties whose values don't serialize, for
(...skipping 24 matching lines...) Expand all
548 continue; 548 continue;
549 549
550 result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()), 550 result->SetWithoutPathExpansion(std::string(*name_utf8, name_utf8.length()),
551 child.release()); 551 child.release());
552 } 552 }
553 553
554 return result.release(); 554 return result.release();
555 } 555 }
556 556
557 } // namespace content 557 } // namespace content
OLDNEW
« no previous file with comments | « content/child/v8_value_converter_impl.h ('k') | content/child/v8_value_converter_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698