| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project 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 #ifndef V8_JSON_STRINGIFIER_H_ | 5 #ifndef V8_JSON_STRINGIFIER_H_ |
| 6 #define V8_JSON_STRINGIFIER_H_ | 6 #define V8_JSON_STRINGIFIER_H_ |
| 7 | 7 |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/lookup.h" | 9 #include "src/lookup.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| 11 #include "src/string-builder.h" | 11 #include "src/string-builder.h" |
| 12 #include "src/utils.h" | 12 #include "src/utils.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 | 16 |
| 17 class BasicJsonStringifier BASE_EMBEDDED { | 17 class BasicJsonStringifier BASE_EMBEDDED { |
| 18 public: | 18 public: |
| 19 explicit BasicJsonStringifier(Isolate* isolate); | 19 BasicJsonStringifier(Isolate* isolate, Handle<String> gap); |
| 20 |
| 21 ~BasicJsonStringifier() { DeleteArray(gap_); } |
| 20 | 22 |
| 21 MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object); | 23 MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object); |
| 22 | 24 |
| 23 MUST_USE_RESULT INLINE(static MaybeHandle<Object> StringifyString( | 25 MUST_USE_RESULT INLINE(static MaybeHandle<Object> StringifyString( |
| 24 Isolate* isolate, | 26 Isolate* isolate, |
| 25 Handle<String> object)); | 27 Handle<String> object)); |
| 26 | 28 |
| 27 private: | 29 private: |
| 28 enum Result { UNCHANGED, SUCCESS, EXCEPTION }; | 30 enum Result { UNCHANGED, SUCCESS, EXCEPTION }; |
| 29 | 31 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 58 bool deferred_comma, | 60 bool deferred_comma, |
| 59 Handle<String> deferred_key)) { | 61 Handle<String> deferred_key)) { |
| 60 DCHECK(!deferred_key.is_null()); | 62 DCHECK(!deferred_key.is_null()); |
| 61 return Serialize_<true>(object, deferred_comma, deferred_key); | 63 return Serialize_<true>(object, deferred_comma, deferred_key); |
| 62 } | 64 } |
| 63 | 65 |
| 64 template <bool deferred_string_key> | 66 template <bool deferred_string_key> |
| 65 Result Serialize_(Handle<Object> object, bool comma, Handle<Object> key); | 67 Result Serialize_(Handle<Object> object, bool comma, Handle<Object> key); |
| 66 | 68 |
| 67 void SerializeDeferredKey(bool deferred_comma, Handle<Object> deferred_key) { | 69 void SerializeDeferredKey(bool deferred_comma, Handle<Object> deferred_key) { |
| 68 if (deferred_comma) builder_.AppendCharacter(','); | 70 Separator(!deferred_comma); |
| 69 SerializeString(Handle<String>::cast(deferred_key)); | 71 SerializeString(Handle<String>::cast(deferred_key)); |
| 70 builder_.AppendCharacter(':'); | 72 builder_.AppendCharacter(':'); |
| 73 if (gap_ != nullptr) builder_.AppendCharacter(' '); |
| 71 } | 74 } |
| 72 | 75 |
| 73 Result SerializeSmi(Smi* object); | 76 Result SerializeSmi(Smi* object); |
| 74 | 77 |
| 75 Result SerializeDouble(double number); | 78 Result SerializeDouble(double number); |
| 76 INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) { | 79 INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) { |
| 77 return SerializeDouble(object->value()); | 80 return SerializeDouble(object->value()); |
| 78 } | 81 } |
| 79 | 82 |
| 80 Result SerializeJSValue(Handle<JSValue> object); | 83 Result SerializeJSValue(Handle<JSValue> object); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 91 INLINE(static void SerializeStringUnchecked_( | 94 INLINE(static void SerializeStringUnchecked_( |
| 92 Vector<const SrcChar> src, | 95 Vector<const SrcChar> src, |
| 93 IncrementalStringBuilder::NoExtend<DestChar>* dest)); | 96 IncrementalStringBuilder::NoExtend<DestChar>* dest)); |
| 94 | 97 |
| 95 template <typename SrcChar, typename DestChar> | 98 template <typename SrcChar, typename DestChar> |
| 96 INLINE(void SerializeString_(Handle<String> string)); | 99 INLINE(void SerializeString_(Handle<String> string)); |
| 97 | 100 |
| 98 template <typename Char> | 101 template <typename Char> |
| 99 INLINE(static bool DoNotEscape(Char c)); | 102 INLINE(static bool DoNotEscape(Char c)); |
| 100 | 103 |
| 104 INLINE(void NewLine()); |
| 105 INLINE(void Indent() { indent_++; }); |
| 106 INLINE(void Unindent() { indent_--; }); |
| 107 INLINE(void Separator(bool first) { |
| 108 if (!first) builder_.AppendCharacter(','); |
| 109 NewLine(); |
| 110 }) |
| 111 |
| 101 Result StackPush(Handle<Object> object); | 112 Result StackPush(Handle<Object> object); |
| 102 void StackPop(); | 113 void StackPop(); |
| 103 | 114 |
| 104 Factory* factory() { return isolate_->factory(); } | 115 Factory* factory() { return isolate_->factory(); } |
| 105 | 116 |
| 106 Isolate* isolate_; | 117 Isolate* isolate_; |
| 107 IncrementalStringBuilder builder_; | 118 IncrementalStringBuilder builder_; |
| 108 Handle<String> tojson_string_; | 119 Handle<String> tojson_string_; |
| 109 Handle<JSArray> stack_; | 120 Handle<JSArray> stack_; |
| 121 Handle<String> gap_string_; |
| 122 uc16* gap_; |
| 123 int indent_; |
| 110 | 124 |
| 111 static const int kJsonEscapeTableEntrySize = 8; | 125 static const int kJsonEscapeTableEntrySize = 8; |
| 112 static const char* const JsonEscapeTable; | 126 static const char* const JsonEscapeTable; |
| 113 }; | 127 }; |
| 114 | 128 |
| 115 | 129 |
| 116 // Translation table to escape Latin1 characters. | 130 // Translation table to escape Latin1 characters. |
| 117 // Table entries start at a multiple of 8 and are null-terminated. | 131 // Table entries start at a multiple of 8 and are null-terminated. |
| 118 const char* const BasicJsonStringifier::JsonEscapeTable = | 132 const char* const BasicJsonStringifier::JsonEscapeTable = |
| 119 "\\u0000\0 \\u0001\0 \\u0002\0 \\u0003\0 " | 133 "\\u0000\0 \\u0001\0 \\u0002\0 \\u0003\0 " |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 "\334\0 \335\0 \336\0 \337\0 " | 188 "\334\0 \335\0 \336\0 \337\0 " |
| 175 "\340\0 \341\0 \342\0 \343\0 " | 189 "\340\0 \341\0 \342\0 \343\0 " |
| 176 "\344\0 \345\0 \346\0 \347\0 " | 190 "\344\0 \345\0 \346\0 \347\0 " |
| 177 "\350\0 \351\0 \352\0 \353\0 " | 191 "\350\0 \351\0 \352\0 \353\0 " |
| 178 "\354\0 \355\0 \356\0 \357\0 " | 192 "\354\0 \355\0 \356\0 \357\0 " |
| 179 "\360\0 \361\0 \362\0 \363\0 " | 193 "\360\0 \361\0 \362\0 \363\0 " |
| 180 "\364\0 \365\0 \366\0 \367\0 " | 194 "\364\0 \365\0 \366\0 \367\0 " |
| 181 "\370\0 \371\0 \372\0 \373\0 " | 195 "\370\0 \371\0 \372\0 \373\0 " |
| 182 "\374\0 \375\0 \376\0 \377\0 "; | 196 "\374\0 \375\0 \376\0 \377\0 "; |
| 183 | 197 |
| 184 | 198 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate, Handle<String> gap) |
| 185 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate) | 199 : isolate_(isolate), builder_(isolate), gap_string_(gap), indent_(0) { |
| 186 : isolate_(isolate), builder_(isolate) { | |
| 187 tojson_string_ = factory()->toJSON_string(); | 200 tojson_string_ = factory()->toJSON_string(); |
| 188 stack_ = factory()->NewJSArray(8); | 201 stack_ = factory()->NewJSArray(8); |
| 202 int gap_length = gap->length(); |
| 203 if (gap_length != 0) { |
| 204 String::Flatten(gap); |
| 205 DisallowHeapAllocation no_gc; |
| 206 String::FlatContent flat = gap->GetFlatContent(); |
| 207 gap_ = NewArray<uc16>(gap_length + 1); |
| 208 if (flat.IsOneByte()) { |
| 209 CopyChars(gap_, flat.ToOneByteVector().start(), gap_length); |
| 210 } else { |
| 211 CopyChars(gap_, flat.ToUC16Vector().start(), gap_length); |
| 212 builder_.ChangeEncoding(); |
| 213 } |
| 214 gap_[gap_length] = '\0'; |
| 215 } else { |
| 216 gap_ = nullptr; |
| 217 } |
| 189 } | 218 } |
| 190 | 219 |
| 191 | 220 |
| 192 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) { | 221 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) { |
| 193 Result result = SerializeObject(object); | 222 Result result = SerializeObject(object); |
| 194 if (result == UNCHANGED) return factory()->undefined_value(); | 223 if (result == UNCHANGED) return factory()->undefined_value(); |
| 195 if (result == SUCCESS) return builder_.Finish(); | 224 if (result == SUCCESS) return builder_.Finish(); |
| 196 DCHECK(result == EXCEPTION); | 225 DCHECK(result == EXCEPTION); |
| 197 return MaybeHandle<Object>(); | 226 return MaybeHandle<Object>(); |
| 198 } | 227 } |
| 199 | 228 |
| 200 | 229 |
| 201 MaybeHandle<Object> BasicJsonStringifier::StringifyString( | 230 MaybeHandle<Object> BasicJsonStringifier::StringifyString( |
| 202 Isolate* isolate, Handle<String> object) { | 231 Isolate* isolate, Handle<String> object) { |
| 203 static const int kJsonQuoteWorstCaseBlowup = 6; | 232 static const int kJsonQuoteWorstCaseBlowup = 6; |
| 204 static const int kSpaceForQuotes = 2; | 233 static const int kSpaceForQuotes = 2; |
| 205 int worst_case_length = | 234 int worst_case_length = |
| 206 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; | 235 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; |
| 207 | 236 |
| 208 if (worst_case_length > 32 * KB) { // Slow path if too large. | 237 if (worst_case_length > 32 * KB) { // Slow path if too large. |
| 209 BasicJsonStringifier stringifier(isolate); | 238 BasicJsonStringifier stringifier(isolate, |
| 239 isolate->factory()->empty_string()); |
| 210 return stringifier.Stringify(object); | 240 return stringifier.Stringify(object); |
| 211 } | 241 } |
| 212 | 242 |
| 213 object = String::Flatten(object); | 243 object = String::Flatten(object); |
| 214 DCHECK(object->IsFlat()); | 244 DCHECK(object->IsFlat()); |
| 215 Handle<SeqString> result; | 245 Handle<SeqString> result; |
| 216 if (object->IsOneByteRepresentationUnderneath()) { | 246 if (object->IsOneByteRepresentationUnderneath()) { |
| 217 result = isolate->factory() | 247 result = isolate->factory() |
| 218 ->NewRawOneByteString(worst_case_length) | 248 ->NewRawOneByteString(worst_case_length) |
| 219 .ToHandleChecked(); | 249 .ToHandleChecked(); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 return SerializeGeneric(object, key, comma, deferred_string_key); | 384 return SerializeGeneric(object, key, comma, deferred_string_key); |
| 355 } | 385 } |
| 356 | 386 |
| 357 | 387 |
| 358 BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric( | 388 BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric( |
| 359 Handle<Object> object, | 389 Handle<Object> object, |
| 360 Handle<Object> key, | 390 Handle<Object> key, |
| 361 bool deferred_comma, | 391 bool deferred_comma, |
| 362 bool deferred_key) { | 392 bool deferred_key) { |
| 363 Handle<JSFunction> fun = isolate_->json_serialize_adapter(); | 393 Handle<JSFunction> fun = isolate_->json_serialize_adapter(); |
| 364 Handle<Object> argv[] = { key, object }; | 394 Handle<Object> indent(Smi::FromInt(indent_), isolate_); |
| 395 Handle<Object> argv[] = {key, object, indent, gap_string_}; |
| 365 Handle<Object> result; | 396 Handle<Object> result; |
| 366 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 397 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 367 isolate_, result, Execution::Call(isolate_, fun, object, 2, argv), | 398 isolate_, result, |
| 368 EXCEPTION); | 399 Execution::Call(isolate_, fun, object, arraysize(argv), argv), EXCEPTION); |
| 369 if (result->IsUndefined()) return UNCHANGED; | 400 if (result->IsUndefined()) return UNCHANGED; |
| 370 if (deferred_key) { | 401 if (deferred_key) { |
| 371 if (key->IsSmi()) key = factory()->NumberToString(key); | 402 if (key->IsSmi()) key = factory()->NumberToString(key); |
| 372 SerializeDeferredKey(deferred_comma, key); | 403 SerializeDeferredKey(deferred_comma, key); |
| 373 } | 404 } |
| 374 | 405 |
| 375 builder_.AppendString(Handle<String>::cast(result)); | 406 builder_.AppendString(Handle<String>::cast(result)); |
| 376 return SUCCESS; | 407 return SUCCESS; |
| 377 } | 408 } |
| 378 | 409 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 | 460 |
| 430 | 461 |
| 431 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( | 462 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
| 432 Handle<JSArray> object) { | 463 Handle<JSArray> object) { |
| 433 HandleScope handle_scope(isolate_); | 464 HandleScope handle_scope(isolate_); |
| 434 Result stack_push = StackPush(object); | 465 Result stack_push = StackPush(object); |
| 435 if (stack_push != SUCCESS) return stack_push; | 466 if (stack_push != SUCCESS) return stack_push; |
| 436 uint32_t length = 0; | 467 uint32_t length = 0; |
| 437 CHECK(object->length()->ToArrayLength(&length)); | 468 CHECK(object->length()->ToArrayLength(&length)); |
| 438 builder_.AppendCharacter('['); | 469 builder_.AppendCharacter('['); |
| 470 Indent(); |
| 439 switch (object->GetElementsKind()) { | 471 switch (object->GetElementsKind()) { |
| 440 case FAST_SMI_ELEMENTS: { | 472 case FAST_SMI_ELEMENTS: { |
| 441 Handle<FixedArray> elements(FixedArray::cast(object->elements()), | 473 Handle<FixedArray> elements(FixedArray::cast(object->elements()), |
| 442 isolate_); | 474 isolate_); |
| 443 for (uint32_t i = 0; i < length; i++) { | 475 for (uint32_t i = 0; i < length; i++) { |
| 444 if (i > 0) builder_.AppendCharacter(','); | 476 Separator(i == 0); |
| 445 SerializeSmi(Smi::cast(elements->get(i))); | 477 SerializeSmi(Smi::cast(elements->get(i))); |
| 446 } | 478 } |
| 447 break; | 479 break; |
| 448 } | 480 } |
| 449 case FAST_DOUBLE_ELEMENTS: { | 481 case FAST_DOUBLE_ELEMENTS: { |
| 450 // Empty array is FixedArray but not FixedDoubleArray. | 482 // Empty array is FixedArray but not FixedDoubleArray. |
| 451 if (length == 0) break; | 483 if (length == 0) break; |
| 452 Handle<FixedDoubleArray> elements( | 484 Handle<FixedDoubleArray> elements( |
| 453 FixedDoubleArray::cast(object->elements()), isolate_); | 485 FixedDoubleArray::cast(object->elements()), isolate_); |
| 454 for (uint32_t i = 0; i < length; i++) { | 486 for (uint32_t i = 0; i < length; i++) { |
| 455 if (i > 0) builder_.AppendCharacter(','); | 487 Separator(i == 0); |
| 456 SerializeDouble(elements->get_scalar(i)); | 488 SerializeDouble(elements->get_scalar(i)); |
| 457 } | 489 } |
| 458 break; | 490 break; |
| 459 } | 491 } |
| 460 case FAST_ELEMENTS: { | 492 case FAST_ELEMENTS: { |
| 461 Handle<Object> old_length(object->length(), isolate_); | 493 Handle<Object> old_length(object->length(), isolate_); |
| 462 for (uint32_t i = 0; i < length; i++) { | 494 for (uint32_t i = 0; i < length; i++) { |
| 463 if (object->length() != *old_length || | 495 if (object->length() != *old_length || |
| 464 object->GetElementsKind() != FAST_ELEMENTS) { | 496 object->GetElementsKind() != FAST_ELEMENTS) { |
| 465 Result result = SerializeJSArraySlow(object, i, length); | 497 Result result = SerializeJSArraySlow(object, i, length); |
| 466 if (result != SUCCESS) return result; | 498 if (result != SUCCESS) return result; |
| 467 break; | 499 break; |
| 468 } | 500 } |
| 469 if (i > 0) builder_.AppendCharacter(','); | 501 Separator(i == 0); |
| 470 Result result = SerializeElement( | 502 Result result = SerializeElement( |
| 471 isolate_, | 503 isolate_, |
| 472 Handle<Object>(FixedArray::cast(object->elements())->get(i), | 504 Handle<Object>(FixedArray::cast(object->elements())->get(i), |
| 473 isolate_), | 505 isolate_), |
| 474 i); | 506 i); |
| 475 if (result == SUCCESS) continue; | 507 if (result == SUCCESS) continue; |
| 476 if (result == UNCHANGED) { | 508 if (result == UNCHANGED) { |
| 477 builder_.AppendCString("null"); | 509 builder_.AppendCString("null"); |
| 478 } else { | 510 } else { |
| 479 return result; | 511 return result; |
| 480 } | 512 } |
| 481 } | 513 } |
| 482 break; | 514 break; |
| 483 } | 515 } |
| 484 // The FAST_HOLEY_* cases could be handled in a faster way. They resemble | 516 // The FAST_HOLEY_* cases could be handled in a faster way. They resemble |
| 485 // the non-holey cases except that a lookup is necessary for holes. | 517 // the non-holey cases except that a lookup is necessary for holes. |
| 486 default: { | 518 default: { |
| 487 Result result = SerializeJSArraySlow(object, 0, length); | 519 Result result = SerializeJSArraySlow(object, 0, length); |
| 488 if (result != SUCCESS) return result; | 520 if (result != SUCCESS) return result; |
| 489 break; | 521 break; |
| 490 } | 522 } |
| 491 } | 523 } |
| 524 Unindent(); |
| 525 if (length > 0) NewLine(); |
| 492 builder_.AppendCharacter(']'); | 526 builder_.AppendCharacter(']'); |
| 493 StackPop(); | 527 StackPop(); |
| 494 return SUCCESS; | 528 return SUCCESS; |
| 495 } | 529 } |
| 496 | 530 |
| 497 | 531 |
| 498 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow( | 532 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow( |
| 499 Handle<JSArray> object, uint32_t start, uint32_t length) { | 533 Handle<JSArray> object, uint32_t start, uint32_t length) { |
| 500 for (uint32_t i = start; i < length; i++) { | 534 for (uint32_t i = start; i < length; i++) { |
| 501 if (i > 0) builder_.AppendCharacter(','); | 535 Separator(i == 0); |
| 502 Handle<Object> element; | 536 Handle<Object> element; |
| 503 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 537 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 504 isolate_, element, JSReceiver::GetElement(isolate_, object, i), | 538 isolate_, element, JSReceiver::GetElement(isolate_, object, i), |
| 505 EXCEPTION); | 539 EXCEPTION); |
| 506 if (element->IsUndefined()) { | 540 if (element->IsUndefined()) { |
| 507 builder_.AppendCString("null"); | 541 builder_.AppendCString("null"); |
| 508 } else { | 542 } else { |
| 509 Result result = SerializeElement(isolate_, element, i); | 543 Result result = SerializeElement(isolate_, element, i); |
| 510 if (result == SUCCESS) continue; | 544 if (result == SUCCESS) continue; |
| 511 if (result == UNCHANGED) { | 545 if (result == UNCHANGED) { |
| 512 builder_.AppendCString("null"); | 546 builder_.AppendCString("null"); |
| 513 } else { | 547 } else { |
| 514 return result; | 548 return result; |
| 515 } | 549 } |
| 516 } | 550 } |
| 517 } | 551 } |
| 518 return SUCCESS; | 552 return SUCCESS; |
| 519 } | 553 } |
| 520 | 554 |
| 521 | 555 |
| 522 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( | 556 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( |
| 523 Handle<JSObject> object) { | 557 Handle<JSObject> object) { |
| 524 HandleScope handle_scope(isolate_); | 558 HandleScope handle_scope(isolate_); |
| 525 Result stack_push = StackPush(object); | 559 Result stack_push = StackPush(object); |
| 526 if (stack_push != SUCCESS) return stack_push; | 560 if (stack_push != SUCCESS) return stack_push; |
| 527 DCHECK(!object->IsJSGlobalProxy() && !object->IsJSGlobalObject()); | 561 DCHECK(!object->IsJSGlobalProxy() && !object->IsJSGlobalObject()); |
| 528 | 562 |
| 529 builder_.AppendCharacter('{'); | 563 builder_.AppendCharacter('{'); |
| 564 Indent(); |
| 530 bool comma = false; | 565 bool comma = false; |
| 531 | 566 |
| 532 if (object->HasFastProperties() && | 567 if (object->HasFastProperties() && |
| 533 !object->HasIndexedInterceptor() && | 568 !object->HasIndexedInterceptor() && |
| 534 !object->HasNamedInterceptor() && | 569 !object->HasNamedInterceptor() && |
| 535 object->elements()->length() == 0) { | 570 object->elements()->length() == 0) { |
| 536 Handle<Map> map(object->map()); | 571 Handle<Map> map(object->map()); |
| 537 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { | 572 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { |
| 538 Handle<Name> name(map->instance_descriptors()->GetKey(i), isolate_); | 573 Handle<Name> name(map->instance_descriptors()->GetKey(i), isolate_); |
| 539 // TODO(rossberg): Should this throw? | 574 // TODO(rossberg): Should this throw? |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 } | 621 } |
| 587 } | 622 } |
| 588 Handle<Object> property; | 623 Handle<Object> property; |
| 589 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 624 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 590 isolate_, property, maybe_property, EXCEPTION); | 625 isolate_, property, maybe_property, EXCEPTION); |
| 591 Result result = SerializeProperty(property, comma, key_handle); | 626 Result result = SerializeProperty(property, comma, key_handle); |
| 592 if (!comma && result == SUCCESS) comma = true; | 627 if (!comma && result == SUCCESS) comma = true; |
| 593 if (result == EXCEPTION) return result; | 628 if (result == EXCEPTION) return result; |
| 594 } | 629 } |
| 595 } | 630 } |
| 596 | 631 Unindent(); |
| 632 if (comma) NewLine(); |
| 597 builder_.AppendCharacter('}'); | 633 builder_.AppendCharacter('}'); |
| 598 StackPop(); | 634 StackPop(); |
| 599 return SUCCESS; | 635 return SUCCESS; |
| 600 } | 636 } |
| 601 | 637 |
| 602 | 638 |
| 603 template <typename SrcChar, typename DestChar> | 639 template <typename SrcChar, typename DestChar> |
| 604 void BasicJsonStringifier::SerializeStringUnchecked_( | 640 void BasicJsonStringifier::SerializeStringUnchecked_( |
| 605 Vector<const SrcChar> src, | 641 Vector<const SrcChar> src, |
| 606 IncrementalStringBuilder::NoExtend<DestChar>* dest) { | 642 IncrementalStringBuilder::NoExtend<DestChar>* dest) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 bool BasicJsonStringifier::DoNotEscape(uint8_t c) { | 690 bool BasicJsonStringifier::DoNotEscape(uint8_t c) { |
| 655 return c >= '#' && c <= '~' && c != '\\'; | 691 return c >= '#' && c <= '~' && c != '\\'; |
| 656 } | 692 } |
| 657 | 693 |
| 658 | 694 |
| 659 template <> | 695 template <> |
| 660 bool BasicJsonStringifier::DoNotEscape(uint16_t c) { | 696 bool BasicJsonStringifier::DoNotEscape(uint16_t c) { |
| 661 return c >= '#' && c != '\\' && c != 0x7f; | 697 return c >= '#' && c != '\\' && c != 0x7f; |
| 662 } | 698 } |
| 663 | 699 |
| 700 void BasicJsonStringifier::NewLine() { |
| 701 if (gap_ == nullptr) return; |
| 702 builder_.AppendCharacter('\n'); |
| 703 for (int i = 0; i < indent_; i++) builder_.AppendCString(gap_); |
| 704 } |
| 664 | 705 |
| 665 void BasicJsonStringifier::SerializeString(Handle<String> object) { | 706 void BasicJsonStringifier::SerializeString(Handle<String> object) { |
| 666 object = String::Flatten(object); | 707 object = String::Flatten(object); |
| 667 if (builder_.CurrentEncoding() == String::ONE_BYTE_ENCODING) { | 708 if (builder_.CurrentEncoding() == String::ONE_BYTE_ENCODING) { |
| 668 if (object->IsOneByteRepresentationUnderneath()) { | 709 if (object->IsOneByteRepresentationUnderneath()) { |
| 669 SerializeString_<uint8_t, uint8_t>(object); | 710 SerializeString_<uint8_t, uint8_t>(object); |
| 670 } else { | 711 } else { |
| 671 builder_.ChangeEncoding(); | 712 builder_.ChangeEncoding(); |
| 672 SerializeString(object); | 713 SerializeString(object); |
| 673 } | 714 } |
| 674 } else { | 715 } else { |
| 675 if (object->IsOneByteRepresentationUnderneath()) { | 716 if (object->IsOneByteRepresentationUnderneath()) { |
| 676 SerializeString_<uint8_t, uc16>(object); | 717 SerializeString_<uint8_t, uc16>(object); |
| 677 } else { | 718 } else { |
| 678 SerializeString_<uc16, uc16>(object); | 719 SerializeString_<uc16, uc16>(object); |
| 679 } | 720 } |
| 680 } | 721 } |
| 681 } | 722 } |
| 682 | 723 |
| 683 } // namespace internal | 724 } // namespace internal |
| 684 } // namespace v8 | 725 } // namespace v8 |
| 685 | 726 |
| 686 #endif // V8_JSON_STRINGIFIER_H_ | 727 #endif // V8_JSON_STRINGIFIER_H_ |
| OLD | NEW |