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) { |
Igor Sheludko
2014/04/15 12:46:27
We should allow allocation here.
| |
401 return CIRCULAR; | 401 isolate_->Throw<Object>(factory_->NewTypeError( |
402 "circular_structure", HandleVector<Object>(NULL, 0))); | |
403 return EXCEPTION; | |
402 } | 404 } |
403 } | 405 } |
404 } | 406 } |
405 JSArray::EnsureSize(stack_, length + 1); | 407 JSArray::EnsureSize(stack_, length + 1); |
406 FixedArray::cast(stack_->elements())->set(length, *object); | 408 FixedArray::cast(stack_->elements())->set(length, *object); |
407 stack_->set_length(Smi::FromInt(length + 1)); | 409 stack_->set_length(Smi::FromInt(length + 1)); |
408 return SUCCESS; | 410 return SUCCESS; |
409 } | 411 } |
410 | 412 |
411 | 413 |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
679 map->instance_descriptors()->GetFieldIndex(i)), | 681 map->instance_descriptors()->GetFieldIndex(i)), |
680 isolate_); | 682 isolate_); |
681 } else { | 683 } else { |
682 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 684 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
683 isolate_, property, | 685 isolate_, property, |
684 Object::GetPropertyOrElement(object, key), | 686 Object::GetPropertyOrElement(object, key), |
685 EXCEPTION); | 687 EXCEPTION); |
686 } | 688 } |
687 Result result = SerializeProperty(property, comma, key); | 689 Result result = SerializeProperty(property, comma, key); |
688 if (!comma && result == SUCCESS) comma = true; | 690 if (!comma && result == SUCCESS) comma = true; |
689 if (result >= EXCEPTION) return result; | 691 if (result == EXCEPTION) return result; |
690 } | 692 } |
691 } else { | 693 } else { |
692 Handle<FixedArray> contents; | 694 Handle<FixedArray> contents; |
693 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 695 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
694 isolate_, contents, | 696 isolate_, contents, |
695 GetKeysInFixedArrayFor(object, LOCAL_ONLY), | 697 GetKeysInFixedArrayFor(object, LOCAL_ONLY), |
696 EXCEPTION); | 698 EXCEPTION); |
697 | 699 |
698 for (int i = 0; i < contents->length(); i++) { | 700 for (int i = 0; i < contents->length(); i++) { |
699 Object* key = contents->get(i); | 701 Object* key = contents->get(i); |
(...skipping 13 matching lines...) Expand all Loading... | |
713 maybe_property = Object::GetElement(isolate_, object, index); | 715 maybe_property = Object::GetElement(isolate_, object, index); |
714 } else { | 716 } else { |
715 maybe_property = Object::GetPropertyOrElement(object, key_handle); | 717 maybe_property = Object::GetPropertyOrElement(object, key_handle); |
716 } | 718 } |
717 } | 719 } |
718 Handle<Object> property; | 720 Handle<Object> property; |
719 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 721 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
720 isolate_, property, maybe_property, EXCEPTION); | 722 isolate_, property, maybe_property, EXCEPTION); |
721 Result result = SerializeProperty(property, comma, key_handle); | 723 Result result = SerializeProperty(property, comma, key_handle); |
722 if (!comma && result == SUCCESS) comma = true; | 724 if (!comma && result == SUCCESS) comma = true; |
723 if (result >= EXCEPTION) return result; | 725 if (result == EXCEPTION) return result; |
724 } | 726 } |
725 } | 727 } |
726 | 728 |
727 Append('}'); | 729 Append('}'); |
728 StackPop(); | 730 StackPop(); |
729 current_part_ = handle_scope.CloseAndEscape(current_part_); | 731 current_part_ = handle_scope.CloseAndEscape(current_part_); |
730 return SUCCESS; | 732 return SUCCESS; |
731 } | 733 } |
732 | 734 |
733 | 735 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
894 SerializeString_<false, uint8_t>(object); | 896 SerializeString_<false, uint8_t>(object); |
895 } else { | 897 } else { |
896 SerializeString_<false, uc16>(object); | 898 SerializeString_<false, uc16>(object); |
897 } | 899 } |
898 } | 900 } |
899 } | 901 } |
900 | 902 |
901 } } // namespace v8::internal | 903 } } // namespace v8::internal |
902 | 904 |
903 #endif // V8_JSON_STRINGIFIER_H_ | 905 #endif // V8_JSON_STRINGIFIER_H_ |
OLD | NEW |