OLD | NEW |
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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)); |
62 | 62 |
63 INLINE(void Append(char c)) { | 63 INLINE(void Append(uint8_t c)) { |
64 if (is_ascii_) { | 64 if (is_ascii_) { |
65 Append_<true>(c); | 65 Append_<true>(c); |
66 } else { | 66 } else { |
67 Append_<false>(c); | 67 Append_<false>(c); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 INLINE(void Append(const char* chars)) { | 71 INLINE(void AppendAscii(const char* chars)) { |
72 if (is_ascii_) { | 72 if (is_ascii_) { |
73 Append_<true>(chars); | 73 Append_<true>(reinterpret_cast<const uint8_t*>(chars)); |
74 } else { | 74 } else { |
75 Append_<false>(chars); | 75 Append_<false>(reinterpret_cast<const uint8_t*>(chars)); |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
79 Handle<Object> ApplyToJsonFunction(Handle<Object> object, | 79 Handle<Object> ApplyToJsonFunction(Handle<Object> object, |
80 Handle<Object> key); | 80 Handle<Object> key); |
81 | 81 |
82 Result SerializeGeneric(Handle<Object> object, | 82 Result SerializeGeneric(Handle<Object> object, |
83 Handle<Object> key, | 83 Handle<Object> key, |
84 bool deferred_comma, | 84 bool deferred_comma, |
85 bool deferred_key); | 85 bool deferred_key); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 } | 320 } |
321 | 321 |
322 switch (HeapObject::cast(*object)->map()->instance_type()) { | 322 switch (HeapObject::cast(*object)->map()->instance_type()) { |
323 case HEAP_NUMBER_TYPE: | 323 case HEAP_NUMBER_TYPE: |
324 if (deferred_string_key) SerializeDeferredKey(comma, key); | 324 if (deferred_string_key) SerializeDeferredKey(comma, key); |
325 return SerializeHeapNumber(Handle<HeapNumber>::cast(object)); | 325 return SerializeHeapNumber(Handle<HeapNumber>::cast(object)); |
326 case ODDBALL_TYPE: | 326 case ODDBALL_TYPE: |
327 switch (Oddball::cast(*object)->kind()) { | 327 switch (Oddball::cast(*object)->kind()) { |
328 case Oddball::kFalse: | 328 case Oddball::kFalse: |
329 if (deferred_string_key) SerializeDeferredKey(comma, key); | 329 if (deferred_string_key) SerializeDeferredKey(comma, key); |
330 Append("false"); | 330 AppendAscii("false"); |
331 return SUCCESS; | 331 return SUCCESS; |
332 case Oddball::kTrue: | 332 case Oddball::kTrue: |
333 if (deferred_string_key) SerializeDeferredKey(comma, key); | 333 if (deferred_string_key) SerializeDeferredKey(comma, key); |
334 Append("true"); | 334 AppendAscii("true"); |
335 return SUCCESS; | 335 return SUCCESS; |
336 case Oddball::kNull: | 336 case Oddball::kNull: |
337 if (deferred_string_key) SerializeDeferredKey(comma, key); | 337 if (deferred_string_key) SerializeDeferredKey(comma, key); |
338 Append("null"); | 338 AppendAscii("null"); |
339 return SUCCESS; | 339 return SUCCESS; |
340 default: | 340 default: |
341 return UNCHANGED; | 341 return UNCHANGED; |
342 } | 342 } |
343 case JS_ARRAY_TYPE: | 343 case JS_ARRAY_TYPE: |
344 if (deferred_string_key) SerializeDeferredKey(comma, key); | 344 if (deferred_string_key) SerializeDeferredKey(comma, key); |
345 return SerializeJSArray(Handle<JSArray>::cast(object)); | 345 return SerializeJSArray(Handle<JSArray>::cast(object)); |
346 case JS_VALUE_TYPE: | 346 case JS_VALUE_TYPE: |
347 if (deferred_string_key) SerializeDeferredKey(comma, key); | 347 if (deferred_string_key) SerializeDeferredKey(comma, key); |
348 return SerializeJSValue(Handle<JSValue>::cast(object)); | 348 return SerializeJSValue(Handle<JSValue>::cast(object)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 SerializeString(Handle<String>::cast(value)); | 405 SerializeString(Handle<String>::cast(value)); |
406 } else if (class_name == isolate_->heap()->Number_symbol()) { | 406 } else if (class_name == isolate_->heap()->Number_symbol()) { |
407 Handle<Object> value = Execution::ToNumber(object, &has_exception); | 407 Handle<Object> value = Execution::ToNumber(object, &has_exception); |
408 if (has_exception) return EXCEPTION; | 408 if (has_exception) return EXCEPTION; |
409 if (value->IsSmi()) return SerializeSmi(Smi::cast(*value)); | 409 if (value->IsSmi()) return SerializeSmi(Smi::cast(*value)); |
410 SerializeHeapNumber(Handle<HeapNumber>::cast(value)); | 410 SerializeHeapNumber(Handle<HeapNumber>::cast(value)); |
411 } else { | 411 } else { |
412 ASSERT(class_name == isolate_->heap()->Boolean_symbol()); | 412 ASSERT(class_name == isolate_->heap()->Boolean_symbol()); |
413 Object* value = JSValue::cast(*object)->value(); | 413 Object* value = JSValue::cast(*object)->value(); |
414 ASSERT(value->IsBoolean()); | 414 ASSERT(value->IsBoolean()); |
415 Append(value->IsTrue() ? "true" : "false"); | 415 AppendAscii(value->IsTrue() ? "true" : "false"); |
416 } | 416 } |
417 return SUCCESS; | 417 return SUCCESS; |
418 } | 418 } |
419 | 419 |
420 | 420 |
421 BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) { | 421 BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) { |
422 static const int kBufferSize = 100; | 422 static const int kBufferSize = 100; |
423 char chars[kBufferSize]; | 423 char chars[kBufferSize]; |
424 Vector<char> buffer(chars, kBufferSize); | 424 Vector<char> buffer(chars, kBufferSize); |
425 Append(IntToCString(object->value(), buffer)); | 425 AppendAscii(IntToCString(object->value(), buffer)); |
426 return SUCCESS; | 426 return SUCCESS; |
427 } | 427 } |
428 | 428 |
429 | 429 |
430 BasicJsonStringifier::Result BasicJsonStringifier::SerializeDouble( | 430 BasicJsonStringifier::Result BasicJsonStringifier::SerializeDouble( |
431 double number) { | 431 double number) { |
432 if (isinf(number) || isnan(number)) { | 432 if (isinf(number) || isnan(number)) { |
433 Append("null"); | 433 AppendAscii("null"); |
434 return SUCCESS; | 434 return SUCCESS; |
435 } | 435 } |
436 static const int kBufferSize = 100; | 436 static const int kBufferSize = 100; |
437 char chars[kBufferSize]; | 437 char chars[kBufferSize]; |
438 Vector<char> buffer(chars, kBufferSize); | 438 Vector<char> buffer(chars, kBufferSize); |
439 Append(DoubleToCString(number, buffer)); | 439 AppendAscii(DoubleToCString(number, buffer)); |
440 return SUCCESS; | 440 return SUCCESS; |
441 } | 441 } |
442 | 442 |
443 | 443 |
444 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( | 444 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
445 Handle<JSArray> object) { | 445 Handle<JSArray> object) { |
446 HandleScope handle_scope(isolate_); | 446 HandleScope handle_scope(isolate_); |
447 Result stack_push = StackPush(object); | 447 Result stack_push = StackPush(object); |
448 if (stack_push != SUCCESS) return stack_push; | 448 if (stack_push != SUCCESS) return stack_push; |
449 int length = Smi::cast(object->length())->value(); | 449 int length = Smi::cast(object->length())->value(); |
(...skipping 19 matching lines...) Expand all Loading... |
469 } | 469 } |
470 case FAST_ELEMENTS: { | 470 case FAST_ELEMENTS: { |
471 Handle<FixedArray> elements( | 471 Handle<FixedArray> elements( |
472 FixedArray::cast(object->elements()), isolate_); | 472 FixedArray::cast(object->elements()), isolate_); |
473 for (int i = 0; i < length; i++) { | 473 for (int i = 0; i < length; i++) { |
474 if (i > 0) Append(','); | 474 if (i > 0) Append(','); |
475 Result result = | 475 Result result = |
476 SerializeElement(Handle<Object>(elements->get(i), isolate_), i); | 476 SerializeElement(Handle<Object>(elements->get(i), isolate_), i); |
477 if (result == SUCCESS) continue; | 477 if (result == SUCCESS) continue; |
478 if (result == UNCHANGED) { | 478 if (result == UNCHANGED) { |
479 Append("null"); | 479 AppendAscii("null"); |
480 } else { | 480 } else { |
481 return result; | 481 return result; |
482 } | 482 } |
483 } | 483 } |
484 break; | 484 break; |
485 } | 485 } |
486 // TODO(yangguo): The FAST_HOLEY_* cases could be handled in a faster way. | 486 // TODO(yangguo): The FAST_HOLEY_* cases could be handled in a faster way. |
487 // They resemble the non-holey cases except that a prototype chain lookup | 487 // They resemble the non-holey cases except that a prototype chain lookup |
488 // is necessary for holes. | 488 // is necessary for holes. |
489 default: { | 489 default: { |
490 Result result = SerializeJSArraySlow(object, length); | 490 Result result = SerializeJSArraySlow(object, length); |
491 if (result != SUCCESS) return result; | 491 if (result != SUCCESS) return result; |
492 break; | 492 break; |
493 } | 493 } |
494 } | 494 } |
495 Append(']'); | 495 Append(']'); |
496 StackPop(); | 496 StackPop(); |
497 current_part_ = handle_scope.CloseAndEscape(current_part_); | 497 current_part_ = handle_scope.CloseAndEscape(current_part_); |
498 return SUCCESS; | 498 return SUCCESS; |
499 } | 499 } |
500 | 500 |
501 | 501 |
502 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow( | 502 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow( |
503 Handle<JSArray> object, int length) { | 503 Handle<JSArray> object, int length) { |
504 for (int i = 0; i < length; i++) { | 504 for (int i = 0; i < length; i++) { |
505 if (i > 0) Append(','); | 505 if (i > 0) Append(','); |
506 Handle<Object> element = Object::GetElement(object, i); | 506 Handle<Object> element = Object::GetElement(object, i); |
507 if (element->IsUndefined()) { | 507 if (element->IsUndefined()) { |
508 Append("null"); | 508 AppendAscii("null"); |
509 } else { | 509 } else { |
510 Result result = SerializeElement(element, i); | 510 Result result = SerializeElement(element, i); |
511 if (result == SUCCESS) continue; | 511 if (result == SUCCESS) continue; |
512 if (result == UNCHANGED) { | 512 if (result == UNCHANGED) { |
513 Append("null"); | 513 AppendAscii("null"); |
514 } else { | 514 } else { |
515 return result; | 515 return result; |
516 } | 516 } |
517 } | 517 } |
518 } | 518 } |
519 return SUCCESS; | 519 return SUCCESS; |
520 } | 520 } |
521 | 521 |
522 | 522 |
523 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( | 523 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 length); | 675 length); |
676 } | 676 } |
677 } else { | 677 } else { |
678 String* string_location = *string; | 678 String* string_location = *string; |
679 Vector<const Char> vector = GetCharVector<Char>(string); | 679 Vector<const Char> vector = GetCharVector<Char>(string); |
680 for (int i = 0; i < length; i++) { | 680 for (int i = 0; i < length; i++) { |
681 Char c = vector[i]; | 681 Char c = vector[i]; |
682 if (DoNotEscape(c)) { | 682 if (DoNotEscape(c)) { |
683 Append_<is_ascii, Char>(c); | 683 Append_<is_ascii, Char>(c); |
684 } else { | 684 } else { |
685 Append_<is_ascii, char>( | 685 Append_<is_ascii, uint8_t>( |
686 &JsonEscapeTable[c * kJsonEscapeTableEntrySize]); | 686 reinterpret_cast<const uint8_t*>( |
| 687 &JsonEscapeTable[c * kJsonEscapeTableEntrySize])); |
687 } | 688 } |
688 // If GC moved the string, we need to refresh the vector. | 689 // If GC moved the string, we need to refresh the vector. |
689 if (*string != string_location) { | 690 if (*string != string_location) { |
690 vector = GetCharVector<Char>(string); | 691 vector = GetCharVector<Char>(string); |
691 string_location = *string; | 692 string_location = *string; |
692 } | 693 } |
693 } | 694 } |
694 } | 695 } |
695 | 696 |
696 Append_<is_ascii, char>('"'); | 697 Append_<is_ascii, uint8_t>('"'); |
697 } | 698 } |
698 | 699 |
699 | 700 |
700 template <> | 701 template <typename Char> |
701 bool BasicJsonStringifier::DoNotEscape(char c) { | 702 bool BasicJsonStringifier::DoNotEscape(Char c) { |
702 return c >= '#' && c <= '~' && c != '\\'; | |
703 } | |
704 | |
705 | |
706 template <> | |
707 bool BasicJsonStringifier::DoNotEscape(uc16 c) { | |
708 return (c >= 0x80) || (c >= '#' && c <= '~' && c != '\\'); | 703 return (c >= 0x80) || (c >= '#' && c <= '~' && c != '\\'); |
709 } | 704 } |
710 | 705 |
711 | 706 |
712 template <> | 707 template <> |
713 Vector<const char> BasicJsonStringifier::GetCharVector(Handle<String> string) { | 708 Vector<const uint8_t> BasicJsonStringifier::GetCharVector( |
| 709 Handle<String> string) { |
714 String::FlatContent flat = string->GetFlatContent(); | 710 String::FlatContent flat = string->GetFlatContent(); |
715 ASSERT(flat.IsAscii()); | 711 ASSERT(flat.IsAscii()); |
716 return flat.ToAsciiVector(); | 712 return flat.ToOneByteVector(); |
717 } | 713 } |
718 | 714 |
719 | 715 |
720 template <> | 716 template <> |
721 Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) { | 717 Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) { |
722 String::FlatContent flat = string->GetFlatContent(); | 718 String::FlatContent flat = string->GetFlatContent(); |
723 ASSERT(flat.IsTwoByte()); | 719 ASSERT(flat.IsTwoByte()); |
724 return flat.ToUC16Vector(); | 720 return flat.ToUC16Vector(); |
725 } | 721 } |
726 | 722 |
727 | 723 |
728 void BasicJsonStringifier::SerializeString(Handle<String> object) { | 724 void BasicJsonStringifier::SerializeString(Handle<String> object) { |
729 FlattenString(object); | 725 FlattenString(object); |
730 String::FlatContent flat = object->GetFlatContent(); | 726 String::FlatContent flat = object->GetFlatContent(); |
731 if (is_ascii_) { | 727 if (is_ascii_) { |
732 if (flat.IsAscii()) { | 728 if (flat.IsAscii()) { |
733 SerializeString_<true, char>(object); | 729 SerializeString_<true, uint8_t>(object); |
734 } else { | 730 } else { |
735 ChangeEncoding(); | 731 ChangeEncoding(); |
736 SerializeString(object); | 732 SerializeString(object); |
737 } | 733 } |
738 } else { | 734 } else { |
739 if (flat.IsAscii()) { | 735 if (flat.IsAscii()) { |
740 SerializeString_<false, char>(object); | 736 SerializeString_<false, uint8_t>(object); |
741 } else { | 737 } else { |
742 SerializeString_<false, uc16>(object); | 738 SerializeString_<false, uc16>(object); |
743 } | 739 } |
744 } | 740 } |
745 } | 741 } |
746 | 742 |
747 } } // namespace v8::internal | 743 } } // namespace v8::internal |
748 | 744 |
749 #endif // V8_JSON_STRINGIFIER_H_ | 745 #endif // V8_JSON_STRINGIFIER_H_ |
OLD | NEW |