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

Side by Side Diff: src/json-stringifier.h

Issue 11369004: Correctly handle proxies in JSON.stringify. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month 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
« no previous file with comments | « src/json.js ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 30 matching lines...) Expand all
41 41
42 MaybeObject* Stringify(Handle<Object> object); 42 MaybeObject* Stringify(Handle<Object> object);
43 43
44 private: 44 private:
45 static const int kInitialPartLength = 32; 45 static const int kInitialPartLength = 32;
46 static const int kMaxPartLength = 16 * 1024; 46 static const int kMaxPartLength = 16 * 1024;
47 static const int kPartLengthGrowthFactor = 2; 47 static const int kPartLengthGrowthFactor = 2;
48 48
49 enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW }; 49 enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW };
50 50
51 template <bool is_ascii> void Extend(); 51 void Extend();
52 52
53 void ChangeEncoding(); 53 void ChangeEncoding();
54 54
55 void ShrinkCurrentPart(); 55 void ShrinkCurrentPart();
56 56
57 template <bool is_ascii, typename Char> 57 template <bool is_ascii, typename Char>
58 INLINE(void Append_(Char c)); 58 INLINE(void Append_(Char c));
59 59
60 template <bool is_ascii, typename Char> 60 template <bool is_ascii, typename Char>
61 INLINE(void Append_(const Char* chars)); 61 INLINE(void Append_(const Char* chars));
(...skipping 13 matching lines...) Expand all
75 Append_<false>(chars); 75 Append_<false>(chars);
76 } 76 }
77 } 77 }
78 78
79 Handle<Object> GetProperty(Handle<JSObject> object, 79 Handle<Object> GetProperty(Handle<JSObject> object,
80 Handle<String> key); 80 Handle<String> key);
81 81
82 Handle<Object> ApplyToJsonFunction(Handle<Object> object, 82 Handle<Object> ApplyToJsonFunction(Handle<Object> object,
83 Handle<Object> key); 83 Handle<Object> key);
84 84
85 Result SerializeGeneric(Handle<Object> object,
86 Handle<Object> key,
87 bool deferred_comma,
88 bool deferred_key);
89
85 // Entry point to serialize the object. 90 // Entry point to serialize the object.
86 INLINE(Result SerializeObject(Handle<Object> obj)) { 91 INLINE(Result SerializeObject(Handle<Object> obj)) {
87 return Serialize_<false>(obj, false, isolate_->factory()->empty_string()); 92 return Serialize_<false>(obj, false, isolate_->factory()->empty_string());
88 } 93 }
89 94
90 // Serialize an array element. 95 // Serialize an array element.
91 // The index may serve as argument for the toJSON function. 96 // The index may serve as argument for the toJSON function.
92 INLINE(Result SerializeElement(Handle<Object> object, int i)) { 97 INLINE(Result SerializeElement(Handle<Object> object, int i)) {
93 return Serialize_<false>(object, false, Handle<Object>(Smi::FromInt(i))); 98 return Serialize_<false>(object, false, Handle<Object>(Smi::FromInt(i)));
94 } 99 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 244
240 template <bool is_ascii, typename Char> 245 template <bool is_ascii, typename Char>
241 void BasicJsonStringifier::Append_(Char c) { 246 void BasicJsonStringifier::Append_(Char c) {
242 if (is_ascii) { 247 if (is_ascii) {
243 SeqAsciiString::cast(*current_part_)->SeqAsciiStringSet( 248 SeqAsciiString::cast(*current_part_)->SeqAsciiStringSet(
244 current_index_++, c); 249 current_index_++, c);
245 } else { 250 } else {
246 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( 251 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet(
247 current_index_++, c); 252 current_index_++, c);
248 } 253 }
249 if (current_index_ == part_length_) Extend<is_ascii>(); 254 if (current_index_ == part_length_) Extend();
250 } 255 }
251 256
252 257
253 template <bool is_ascii, typename Char> 258 template <bool is_ascii, typename Char>
254 void BasicJsonStringifier::Append_(const Char* chars) { 259 void BasicJsonStringifier::Append_(const Char* chars) {
255 for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars); 260 for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars);
256 } 261 }
257 262
258 263
259 Handle<Object> BasicJsonStringifier::GetProperty(Handle<JSObject> object, 264 Handle<Object> BasicJsonStringifier::GetProperty(Handle<JSObject> object,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 336
332 337
333 template <bool deferred_string_key> 338 template <bool deferred_string_key>
334 BasicJsonStringifier::Result BasicJsonStringifier::Serialize_( 339 BasicJsonStringifier::Result BasicJsonStringifier::Serialize_(
335 Handle<Object> object, bool comma, Handle<Object> key) { 340 Handle<Object> object, bool comma, Handle<Object> key) {
336 if (object->IsJSObject()) { 341 if (object->IsJSObject()) {
337 object = ApplyToJsonFunction(object, key); 342 object = ApplyToJsonFunction(object, key);
338 if (object.is_null()) return EXCEPTION; 343 if (object.is_null()) return EXCEPTION;
339 } 344 }
340 345
341 if (object->IsJSObject()) { 346 if (object->IsSmi()) {
342 if (object->IsJSFunction()) return UNCHANGED;
343 if (deferred_string_key) SerializeDeferredKey(comma, key); 347 if (deferred_string_key) SerializeDeferredKey(comma, key);
344 if (object->IsJSArray()) { 348 return SerializeSmi(Smi::cast(*object));
345 return SerializeJSArray(Handle<JSArray>::cast(object));
346 } else if (object->IsJSValue()) {
347 return SerializeJSValue(Handle<JSValue>::cast(object));
348 } else {
349 return SerializeJSObject(Handle<JSObject>::cast(object));
350 }
351 } 349 }
352 350
353 // Handle non-JSObject. 351 switch (HeapObject::cast(*object)->map()->instance_type()) {
354 if (object->IsString()) { 352 case HEAP_NUMBER_TYPE:
355 if (deferred_string_key) SerializeDeferredKey(comma, key); 353 if (deferred_string_key) SerializeDeferredKey(comma, key);
356 SerializeString(Handle<String>::cast(object)); 354 return SerializeHeapNumber(Handle<HeapNumber>::cast(object));
357 return SUCCESS; 355 case ODDBALL_TYPE:
358 } else if (object->IsSmi()) { 356 switch (Oddball::cast(*object)->kind()) {
359 if (deferred_string_key) SerializeDeferredKey(comma, key); 357 case Oddball::kFalse:
360 return SerializeSmi(Smi::cast(*object)); 358 if (deferred_string_key) SerializeDeferredKey(comma, key);
361 } else if (object->IsHeapNumber()) { 359 Append("false");
362 if (deferred_string_key) SerializeDeferredKey(comma, key); 360 return SUCCESS;
363 return SerializeHeapNumber(Handle<HeapNumber>::cast(object)); 361 case Oddball::kTrue:
364 } else if (object->IsOddball()) { 362 if (deferred_string_key) SerializeDeferredKey(comma, key);
365 switch (Oddball::cast(*object)->kind()) { 363 Append("true");
366 case Oddball::kFalse: 364 return SUCCESS;
365 case Oddball::kNull:
366 if (deferred_string_key) SerializeDeferredKey(comma, key);
367 Append("null");
368 return SUCCESS;
369 default:
370 return UNCHANGED;
371 }
372 case JS_ARRAY_TYPE:
373 if (deferred_string_key) SerializeDeferredKey(comma, key);
374 return SerializeJSArray(Handle<JSArray>::cast(object));
375 case JS_VALUE_TYPE:
376 if (deferred_string_key) SerializeDeferredKey(comma, key);
377 return SerializeJSValue(Handle<JSValue>::cast(object));
378 case JS_FUNCTION_TYPE:
379 return UNCHANGED;
380 default:
381 if (object->IsString()) {
367 if (deferred_string_key) SerializeDeferredKey(comma, key); 382 if (deferred_string_key) SerializeDeferredKey(comma, key);
368 Append("false"); 383 SerializeString(Handle<String>::cast(object));
369 return SUCCESS; 384 return SUCCESS;
370 case Oddball::kTrue: 385 } else if (object->IsJSObject()) {
371 if (deferred_string_key) SerializeDeferredKey(comma, key); 386 if (deferred_string_key) SerializeDeferredKey(comma, key);
372 Append("true"); 387 return SerializeJSObject(Handle<JSObject>::cast(object));
373 return SUCCESS; 388 } else {
374 case Oddball::kNull: 389 return SerializeGeneric(object, key, comma, deferred_string_key);
375 if (deferred_string_key) SerializeDeferredKey(comma, key); 390 }
376 Append("null");
377 return SUCCESS;
378 }
379 } 391 }
380
381 return UNCHANGED;
382 } 392 }
383 393
384 394
395 BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
396 Handle<Object> object,
397 Handle<Object> key,
398 bool deferred_comma,
399 bool deferred_key) {
400 Handle<JSObject> builtins(isolate_->native_context()->builtins());
401 Handle<JSFunction> builtin = Handle<JSFunction>::cast(
402 v8::internal::GetProperty(builtins, "JSONSerializeAdapter"));
403
404 Handle<Object> argv[] = { key, object };
405 bool has_exception = false;
406 Handle<Object> result =
407 Execution::Call(builtin, object, 2, argv, &has_exception);
408 if (has_exception) return EXCEPTION;
409 if (result->IsUndefined()) return UNCHANGED;
410 if (deferred_key) {
411 if (key->IsSmi()) key = isolate_->factory()->NumberToString(key);
412 SerializeDeferredKey(deferred_comma, key);
413 }
414
415 Handle<String> result_string = Handle<String>::cast(result);
416 // Shrink current part, attach it to the accumulator, also attach the result
417 // string to the accumulator, and allocate a new part.
418 ShrinkCurrentPart(); // Shrink.
419 part_length_ = kInitialPartLength; // Allocate conservatively.
420 Extend(); // Attach current part and allocate new part.
421 set_accumulator( // Attach result string to the accumulator.
422 isolate_->factory()->NewConsString(accumulator(), result_string));
423 return SUCCESS;
424 }
425
426
385 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( 427 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue(
386 Handle<JSValue> object) { 428 Handle<JSValue> object) {
387 bool has_exception = false; 429 bool has_exception = false;
388 String* class_name = object->class_name(); 430 String* class_name = object->class_name();
389 if (class_name == isolate_->heap()->String_symbol()) { 431 if (class_name == isolate_->heap()->String_symbol()) {
390 Handle<Object> value = Execution::ToString(object, &has_exception); 432 Handle<Object> value = Execution::ToString(object, &has_exception);
391 if (has_exception) return EXCEPTION; 433 if (has_exception) return EXCEPTION;
392 SerializeString(Handle<String>::cast(value)); 434 SerializeString(Handle<String>::cast(value));
393 } else if (class_name == isolate_->heap()->Number_symbol()) { 435 } else if (class_name == isolate_->heap()->Number_symbol()) {
394 Handle<Object> value = Execution::ToNumber(object, &has_exception); 436 Handle<Object> value = Execution::ToNumber(object, &has_exception);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 // that are a multiple of pointer size. 615 // that are a multiple of pointer size.
574 Address end_of_string = current_part_->address() + string_size; 616 Address end_of_string = current_part_->address() + string_size;
575 isolate_->heap()->CreateFillerObjectAt(end_of_string, delta); 617 isolate_->heap()->CreateFillerObjectAt(end_of_string, delta);
576 if (Marking::IsBlack(Marking::MarkBitFrom(*current_part_))) { 618 if (Marking::IsBlack(Marking::MarkBitFrom(*current_part_))) {
577 MemoryChunk::IncrementLiveBytesFromMutator( 619 MemoryChunk::IncrementLiveBytesFromMutator(
578 current_part_->address(), -delta); 620 current_part_->address(), -delta);
579 } 621 }
580 } 622 }
581 623
582 624
583 template <bool is_ascii>
584 void BasicJsonStringifier::Extend() { 625 void BasicJsonStringifier::Extend() {
585 set_accumulator( 626 set_accumulator(
586 isolate_->factory()->NewConsString(accumulator(), current_part_)); 627 isolate_->factory()->NewConsString(accumulator(), current_part_));
587 if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) { 628 if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
588 part_length_ *= kPartLengthGrowthFactor; 629 part_length_ *= kPartLengthGrowthFactor;
589 } 630 }
590 if (is_ascii) { 631 if (is_ascii_) {
591 current_part_ = 632 current_part_ =
592 isolate_->factory()->NewRawAsciiString(part_length_); 633 isolate_->factory()->NewRawAsciiString(part_length_);
593 } else { 634 } else {
594 current_part_ = 635 current_part_ =
595 isolate_->factory()->NewRawTwoByteString(part_length_); 636 isolate_->factory()->NewRawTwoByteString(part_length_);
596 } 637 }
597 current_index_ = 0; 638 current_index_ = 0;
598 } 639 }
599 640
600 641
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 SerializeString_<false, char>(flat.ToAsciiVector(), object); 763 SerializeString_<false, char>(flat.ToAsciiVector(), object);
723 } else { 764 } else {
724 SerializeString_<false, uc16>(flat.ToUC16Vector(), object); 765 SerializeString_<false, uc16>(flat.ToUC16Vector(), object);
725 } 766 }
726 } 767 }
727 } 768 }
728 769
729 } } // namespace v8::internal 770 } } // namespace v8::internal
730 771
731 #endif // V8_JSON_STRINGIFIER_H_ 772 #endif // V8_JSON_STRINGIFIER_H_
OLDNEW
« no previous file with comments | « src/json.js ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698