| 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 21 matching lines...) Expand all Loading... |
| 32 #include "v8utils.h" | 32 #include "v8utils.h" |
| 33 #include "v8conversions.h" | 33 #include "v8conversions.h" |
| 34 | 34 |
| 35 namespace v8 { | 35 namespace v8 { |
| 36 namespace internal { | 36 namespace internal { |
| 37 | 37 |
| 38 class BasicJsonStringifier BASE_EMBEDDED { | 38 class BasicJsonStringifier BASE_EMBEDDED { |
| 39 public: | 39 public: |
| 40 explicit BasicJsonStringifier(Isolate* isolate); | 40 explicit BasicJsonStringifier(Isolate* isolate); |
| 41 | 41 |
| 42 MaybeObject* Stringify(Handle<Object> object); | 42 MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object); |
| 43 | 43 |
| 44 INLINE(static MaybeObject* StringifyString(Isolate* isolate, | 44 MUST_USE_RESULT INLINE(static MaybeHandle<Object> StringifyString( |
| 45 Handle<String> object)); | 45 Isolate* isolate, |
| 46 Handle<String> object)); |
| 46 | 47 |
| 47 private: | 48 private: |
| 48 static const int kInitialPartLength = 32; | 49 static const int kInitialPartLength = 32; |
| 49 static const int kMaxPartLength = 16 * 1024; | 50 static const int kMaxPartLength = 16 * 1024; |
| 50 static const int kPartLengthGrowthFactor = 2; | 51 static const int kPartLengthGrowthFactor = 2; |
| 51 | 52 |
| 52 enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW }; | 53 enum Result { UNCHANGED, SUCCESS, EXCEPTION }; |
| 53 | 54 |
| 54 void Accumulate(); | 55 void Accumulate(); |
| 55 | 56 |
| 56 void Extend(); | 57 void Extend(); |
| 57 | 58 |
| 58 void ChangeEncoding(); | 59 void ChangeEncoding(); |
| 59 | 60 |
| 60 INLINE(void ShrinkCurrentPart()); | 61 INLINE(void ShrinkCurrentPart()); |
| 61 | 62 |
| 62 template <bool is_ascii, typename Char> | 63 template <bool is_ascii, typename Char> |
| (...skipping 21 matching lines...) Expand all Loading... |
| 84 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction( | 85 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction( |
| 85 Handle<Object> object, | 86 Handle<Object> object, |
| 86 Handle<Object> key); | 87 Handle<Object> key); |
| 87 | 88 |
| 88 Result SerializeGeneric(Handle<Object> object, | 89 Result SerializeGeneric(Handle<Object> object, |
| 89 Handle<Object> key, | 90 Handle<Object> key, |
| 90 bool deferred_comma, | 91 bool deferred_comma, |
| 91 bool deferred_key); | 92 bool deferred_key); |
| 92 | 93 |
| 93 template <typename ResultType, typename Char> | 94 template <typename ResultType, typename Char> |
| 94 INLINE(static MaybeObject* StringifyString_(Isolate* isolate, | 95 INLINE(static Handle<String> StringifyString_(Isolate* isolate, |
| 95 Vector<Char> vector, | 96 Vector<Char> vector, |
| 96 Handle<String> result)); | 97 Handle<String> result)); |
| 97 | 98 |
| 98 // Entry point to serialize the object. | 99 // Entry point to serialize the object. |
| 99 INLINE(Result SerializeObject(Handle<Object> obj)) { | 100 INLINE(Result SerializeObject(Handle<Object> obj)) { |
| 100 return Serialize_<false>(obj, false, factory_->empty_string()); | 101 return Serialize_<false>(obj, false, factory_->empty_string()); |
| 101 } | 102 } |
| 102 | 103 |
| 103 // Serialize an array element. | 104 // Serialize an array element. |
| 104 // The index may serve as argument for the toJSON function. | 105 // The index may serve as argument for the toJSON function. |
| 105 INLINE(Result SerializeElement(Isolate* isolate, | 106 INLINE(Result SerializeElement(Isolate* isolate, |
| 106 Handle<Object> object, | 107 Handle<Object> object, |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 factory_ = isolate_->factory(); | 266 factory_ = isolate_->factory(); |
| 266 accumulator_store_ = Handle<JSValue>::cast( | 267 accumulator_store_ = Handle<JSValue>::cast( |
| 267 Object::ToObject(isolate, factory_->empty_string()).ToHandleChecked()); | 268 Object::ToObject(isolate, factory_->empty_string()).ToHandleChecked()); |
| 268 part_length_ = kInitialPartLength; | 269 part_length_ = kInitialPartLength; |
| 269 current_part_ = factory_->NewRawOneByteString(part_length_).ToHandleChecked(); | 270 current_part_ = factory_->NewRawOneByteString(part_length_).ToHandleChecked(); |
| 270 tojson_string_ = factory_->toJSON_string(); | 271 tojson_string_ = factory_->toJSON_string(); |
| 271 stack_ = factory_->NewJSArray(8); | 272 stack_ = factory_->NewJSArray(8); |
| 272 } | 273 } |
| 273 | 274 |
| 274 | 275 |
| 275 MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) { | 276 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) { |
| 276 switch (SerializeObject(object)) { | 277 Result result = SerializeObject(object); |
| 277 case UNCHANGED: | 278 if (result == UNCHANGED) return isolate_->factory()->undefined_value(); |
| 278 return isolate_->heap()->undefined_value(); | 279 if (result == SUCCESS) { |
| 279 case SUCCESS: { | 280 ShrinkCurrentPart(); |
| 280 ShrinkCurrentPart(); | 281 Accumulate(); |
| 281 Accumulate(); | 282 if (overflowed_) { |
| 282 if (overflowed_) return isolate_->ThrowInvalidStringLength(); | 283 return isolate_->Throw<Object>( |
| 283 return *accumulator(); | 284 isolate_->factory()->NewInvalidStringLengthError()); |
| 284 } | 285 } |
| 285 case CIRCULAR: | 286 return accumulator(); |
| 286 return isolate_->Throw(*factory_->NewTypeError( | |
| 287 "circular_structure", HandleVector<Object>(NULL, 0))); | |
| 288 case STACK_OVERFLOW: | |
| 289 return isolate_->StackOverflow(); | |
| 290 default: | |
| 291 return Failure::Exception(); | |
| 292 } | 287 } |
| 288 ASSERT(result == EXCEPTION); |
| 289 return MaybeHandle<Object>(); |
| 293 } | 290 } |
| 294 | 291 |
| 295 | 292 |
| 296 MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate, | 293 MaybeHandle<Object> BasicJsonStringifier::StringifyString( |
| 297 Handle<String> object) { | 294 Isolate* isolate, Handle<String> object) { |
| 298 static const int kJsonQuoteWorstCaseBlowup = 6; | 295 static const int kJsonQuoteWorstCaseBlowup = 6; |
| 299 static const int kSpaceForQuotes = 2; | 296 static const int kSpaceForQuotes = 2; |
| 300 int worst_case_length = | 297 int worst_case_length = |
| 301 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; | 298 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; |
| 302 | 299 |
| 303 if (worst_case_length > 32 * KB) { // Slow path if too large. | 300 if (worst_case_length > 32 * KB) { // Slow path if too large. |
| 304 BasicJsonStringifier stringifier(isolate); | 301 BasicJsonStringifier stringifier(isolate); |
| 305 return stringifier.Stringify(object); | 302 return stringifier.Stringify(object); |
| 306 } | 303 } |
| 307 | 304 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 321 DisallowHeapAllocation no_gc; | 318 DisallowHeapAllocation no_gc; |
| 322 return StringifyString_<SeqTwoByteString>( | 319 return StringifyString_<SeqTwoByteString>( |
| 323 isolate, | 320 isolate, |
| 324 object->GetFlatContent().ToUC16Vector(), | 321 object->GetFlatContent().ToUC16Vector(), |
| 325 result); | 322 result); |
| 326 } | 323 } |
| 327 } | 324 } |
| 328 | 325 |
| 329 | 326 |
| 330 template <typename ResultType, typename Char> | 327 template <typename ResultType, typename Char> |
| 331 MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate, | 328 Handle<String> BasicJsonStringifier::StringifyString_(Isolate* isolate, |
| 332 Vector<Char> vector, | 329 Vector<Char> vector, |
| 333 Handle<String> result) { | 330 Handle<String> result) { |
| 334 DisallowHeapAllocation no_gc; | 331 DisallowHeapAllocation no_gc; |
| 335 int final_size = 0; | 332 int final_size = 0; |
| 336 ResultType* dest = ResultType::cast(*result); | 333 ResultType* dest = ResultType::cast(*result); |
| 337 dest->Set(final_size++, '\"'); | 334 dest->Set(final_size++, '\"'); |
| 338 final_size += SerializeStringUnchecked_(vector.start(), | 335 final_size += SerializeStringUnchecked_(vector.start(), |
| 339 dest->GetChars() + 1, | 336 dest->GetChars() + 1, |
| 340 vector.length()); | 337 vector.length()); |
| 341 dest->Set(final_size++, '\"'); | 338 dest->Set(final_size++, '\"'); |
| 342 return *SeqString::Truncate(Handle<SeqString>::cast(result), final_size); | 339 return SeqString::Truncate(Handle<SeqString>::cast(result), final_size); |
| 343 } | 340 } |
| 344 | 341 |
| 345 | 342 |
| 346 template <bool is_ascii, typename Char> | 343 template <bool is_ascii, typename Char> |
| 347 void BasicJsonStringifier::Append_(Char c) { | 344 void BasicJsonStringifier::Append_(Char c) { |
| 348 if (is_ascii) { | 345 if (is_ascii) { |
| 349 SeqOneByteString::cast(*current_part_)->SeqOneByteStringSet( | 346 SeqOneByteString::cast(*current_part_)->SeqOneByteStringSet( |
| 350 current_index_++, c); | 347 current_index_++, c); |
| 351 } else { | 348 } else { |
| 352 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( | 349 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( |
| (...skipping 30 matching lines...) Expand all Loading... |
| 383 isolate_, object, | 380 isolate_, object, |
| 384 Execution::Call(isolate_, fun, object, 1, argv), | 381 Execution::Call(isolate_, fun, object, 1, argv), |
| 385 Object); | 382 Object); |
| 386 return scope.CloseAndEscape(object); | 383 return scope.CloseAndEscape(object); |
| 387 } | 384 } |
| 388 | 385 |
| 389 | 386 |
| 390 BasicJsonStringifier::Result BasicJsonStringifier::StackPush( | 387 BasicJsonStringifier::Result BasicJsonStringifier::StackPush( |
| 391 Handle<Object> object) { | 388 Handle<Object> object) { |
| 392 StackLimitCheck check(isolate_); | 389 StackLimitCheck check(isolate_); |
| 393 if (check.HasOverflowed()) return STACK_OVERFLOW; | 390 if (check.HasOverflowed()) { |
| 391 isolate_->StackOverflow(); |
| 392 return EXCEPTION; |
| 393 } |
| 394 | 394 |
| 395 int length = Smi::cast(stack_->length())->value(); | 395 int length = Smi::cast(stack_->length())->value(); |
| 396 { | 396 { |
| 397 DisallowHeapAllocation no_allocation; | 397 DisallowHeapAllocation no_allocation; |
| 398 FixedArray* elements = FixedArray::cast(stack_->elements()); | 398 FixedArray* elements = FixedArray::cast(stack_->elements()); |
| 399 for (int i = 0; i < length; i++) { | 399 for (int i = 0; i < length; i++) { |
| 400 if (elements->get(i) == *object) { | 400 if (elements->get(i) == *object) { |
| 401 return CIRCULAR; | 401 AllowHeapAllocation allow_to_return_error; |
| 402 isolate_->Throw<Object>(factory_->NewTypeError( |
| 403 "circular_structure", HandleVector<Object>(NULL, 0))); |
| 404 return EXCEPTION; |
| 402 } | 405 } |
| 403 } | 406 } |
| 404 } | 407 } |
| 405 JSArray::EnsureSize(stack_, length + 1); | 408 JSArray::EnsureSize(stack_, length + 1); |
| 406 FixedArray::cast(stack_->elements())->set(length, *object); | 409 FixedArray::cast(stack_->elements())->set(length, *object); |
| 407 stack_->set_length(Smi::FromInt(length + 1)); | 410 stack_->set_length(Smi::FromInt(length + 1)); |
| 408 return SUCCESS; | 411 return SUCCESS; |
| 409 } | 412 } |
| 410 | 413 |
| 411 | 414 |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 map->instance_descriptors()->GetFieldIndex(i)), | 682 map->instance_descriptors()->GetFieldIndex(i)), |
| 680 isolate_); | 683 isolate_); |
| 681 } else { | 684 } else { |
| 682 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 685 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 683 isolate_, property, | 686 isolate_, property, |
| 684 Object::GetPropertyOrElement(object, key), | 687 Object::GetPropertyOrElement(object, key), |
| 685 EXCEPTION); | 688 EXCEPTION); |
| 686 } | 689 } |
| 687 Result result = SerializeProperty(property, comma, key); | 690 Result result = SerializeProperty(property, comma, key); |
| 688 if (!comma && result == SUCCESS) comma = true; | 691 if (!comma && result == SUCCESS) comma = true; |
| 689 if (result >= EXCEPTION) return result; | 692 if (result == EXCEPTION) return result; |
| 690 } | 693 } |
| 691 } else { | 694 } else { |
| 692 Handle<FixedArray> contents; | 695 Handle<FixedArray> contents; |
| 693 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 696 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 694 isolate_, contents, | 697 isolate_, contents, |
| 695 GetKeysInFixedArrayFor(object, LOCAL_ONLY), | 698 GetKeysInFixedArrayFor(object, LOCAL_ONLY), |
| 696 EXCEPTION); | 699 EXCEPTION); |
| 697 | 700 |
| 698 for (int i = 0; i < contents->length(); i++) { | 701 for (int i = 0; i < contents->length(); i++) { |
| 699 Object* key = contents->get(i); | 702 Object* key = contents->get(i); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 713 maybe_property = Object::GetElement(isolate_, object, index); | 716 maybe_property = Object::GetElement(isolate_, object, index); |
| 714 } else { | 717 } else { |
| 715 maybe_property = Object::GetPropertyOrElement(object, key_handle); | 718 maybe_property = Object::GetPropertyOrElement(object, key_handle); |
| 716 } | 719 } |
| 717 } | 720 } |
| 718 Handle<Object> property; | 721 Handle<Object> property; |
| 719 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 722 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 720 isolate_, property, maybe_property, EXCEPTION); | 723 isolate_, property, maybe_property, EXCEPTION); |
| 721 Result result = SerializeProperty(property, comma, key_handle); | 724 Result result = SerializeProperty(property, comma, key_handle); |
| 722 if (!comma && result == SUCCESS) comma = true; | 725 if (!comma && result == SUCCESS) comma = true; |
| 723 if (result >= EXCEPTION) return result; | 726 if (result == EXCEPTION) return result; |
| 724 } | 727 } |
| 725 } | 728 } |
| 726 | 729 |
| 727 Append('}'); | 730 Append('}'); |
| 728 StackPop(); | 731 StackPop(); |
| 729 current_part_ = handle_scope.CloseAndEscape(current_part_); | 732 current_part_ = handle_scope.CloseAndEscape(current_part_); |
| 730 return SUCCESS; | 733 return SUCCESS; |
| 731 } | 734 } |
| 732 | 735 |
| 733 | 736 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 SerializeString_<false, uint8_t>(object); | 897 SerializeString_<false, uint8_t>(object); |
| 895 } else { | 898 } else { |
| 896 SerializeString_<false, uc16>(object); | 899 SerializeString_<false, uc16>(object); |
| 897 } | 900 } |
| 898 } | 901 } |
| 899 } | 902 } |
| 900 | 903 |
| 901 } } // namespace v8::internal | 904 } } // namespace v8::internal |
| 902 | 905 |
| 903 #endif // V8_JSON_STRINGIFIER_H_ | 906 #endif // V8_JSON_STRINGIFIER_H_ |
| OLD | NEW |