| 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" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 Isolate* isolate, | 26 Isolate* isolate, |
| 27 Handle<String> object)); | 27 Handle<String> object)); |
| 28 | 28 |
| 29 private: | 29 private: |
| 30 enum Result { UNCHANGED, SUCCESS, EXCEPTION }; | 30 enum Result { UNCHANGED, SUCCESS, EXCEPTION }; |
| 31 | 31 |
| 32 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction( | 32 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction( |
| 33 Handle<Object> object, | 33 Handle<Object> object, |
| 34 Handle<Object> key); | 34 Handle<Object> key); |
| 35 | 35 |
| 36 Result SerializeGeneric(Handle<Object> object, | |
| 37 Handle<Object> key, | |
| 38 bool deferred_comma, | |
| 39 bool deferred_key); | |
| 40 | |
| 41 // Entry point to serialize the object. | 36 // Entry point to serialize the object. |
| 42 INLINE(Result SerializeObject(Handle<Object> obj)) { | 37 INLINE(Result SerializeObject(Handle<Object> obj)) { |
| 43 return Serialize_<false>(obj, false, factory()->empty_string()); | 38 return Serialize_<false>(obj, false, factory()->empty_string()); |
| 44 } | 39 } |
| 45 | 40 |
| 46 // Serialize an array element. | 41 // Serialize an array element. |
| 47 // The index may serve as argument for the toJSON function. | 42 // The index may serve as argument for the toJSON function. |
| 48 INLINE(Result SerializeElement(Isolate* isolate, | 43 INLINE(Result SerializeElement(Isolate* isolate, |
| 49 Handle<Object> object, | 44 Handle<Object> object, |
| 50 int i)) { | 45 int i)) { |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 builder_.AppendCString("true"); | 351 builder_.AppendCString("true"); |
| 357 return SUCCESS; | 352 return SUCCESS; |
| 358 case Oddball::kNull: | 353 case Oddball::kNull: |
| 359 if (deferred_string_key) SerializeDeferredKey(comma, key); | 354 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 360 builder_.AppendCString("null"); | 355 builder_.AppendCString("null"); |
| 361 return SUCCESS; | 356 return SUCCESS; |
| 362 default: | 357 default: |
| 363 return UNCHANGED; | 358 return UNCHANGED; |
| 364 } | 359 } |
| 365 case JS_ARRAY_TYPE: | 360 case JS_ARRAY_TYPE: |
| 366 if (object->IsAccessCheckNeeded()) break; | |
| 367 if (deferred_string_key) SerializeDeferredKey(comma, key); | 361 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 368 return SerializeJSArray(Handle<JSArray>::cast(object)); | 362 return SerializeJSArray(Handle<JSArray>::cast(object)); |
| 369 case JS_VALUE_TYPE: | 363 case JS_VALUE_TYPE: |
| 370 if (deferred_string_key) SerializeDeferredKey(comma, key); | 364 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 371 return SerializeJSValue(Handle<JSValue>::cast(object)); | 365 return SerializeJSValue(Handle<JSValue>::cast(object)); |
| 366 case SIMD128_VALUE_TYPE: |
| 367 case SYMBOL_TYPE: |
| 368 return UNCHANGED; |
| 372 default: | 369 default: |
| 373 if (object->IsString()) { | 370 if (object->IsString()) { |
| 374 if (deferred_string_key) SerializeDeferredKey(comma, key); | 371 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 375 SerializeString(Handle<String>::cast(object)); | 372 SerializeString(Handle<String>::cast(object)); |
| 376 return SUCCESS; | 373 return SUCCESS; |
| 377 } else if (object->IsJSReceiver()) { | 374 } else { |
| 375 DCHECK(object->IsJSReceiver()); |
| 378 if (object->IsCallable()) return UNCHANGED; | 376 if (object->IsCallable()) return UNCHANGED; |
| 379 // Go to slow path for global proxy and objects requiring access checks. | 377 // Go to slow path for global proxy and objects requiring access checks. |
| 380 if (object->IsAccessCheckNeeded() || object->IsJSGlobalProxy()) break; | |
| 381 if (deferred_string_key) SerializeDeferredKey(comma, key); | 378 if (deferred_string_key) SerializeDeferredKey(comma, key); |
| 382 if (object->IsJSProxy()) { | 379 if (object->IsJSProxy()) { |
| 383 return SerializeJSProxy(Handle<JSProxy>::cast(object)); | 380 return SerializeJSProxy(Handle<JSProxy>::cast(object)); |
| 384 } | 381 } |
| 385 return SerializeJSObject(Handle<JSObject>::cast(object)); | 382 return SerializeJSObject(Handle<JSObject>::cast(object)); |
| 386 } | 383 } |
| 387 } | 384 } |
| 388 | 385 |
| 389 return SerializeGeneric(object, key, comma, deferred_string_key); | 386 UNREACHABLE(); |
| 387 return UNCHANGED; |
| 390 } | 388 } |
| 391 | 389 |
| 392 | 390 |
| 393 BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric( | |
| 394 Handle<Object> object, | |
| 395 Handle<Object> key, | |
| 396 bool deferred_comma, | |
| 397 bool deferred_key) { | |
| 398 Handle<JSFunction> fun = isolate_->json_serialize_adapter(); | |
| 399 Handle<Object> indent(Smi::FromInt(indent_), isolate_); | |
| 400 Handle<Object> argv[] = {key, object, indent, gap_string_}; | |
| 401 Handle<Object> result; | |
| 402 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
| 403 isolate_, result, | |
| 404 Execution::Call(isolate_, fun, object, arraysize(argv), argv), EXCEPTION); | |
| 405 if (result->IsUndefined()) return UNCHANGED; | |
| 406 if (deferred_key) { | |
| 407 if (key->IsSmi()) key = factory()->NumberToString(key); | |
| 408 SerializeDeferredKey(deferred_comma, key); | |
| 409 } | |
| 410 | |
| 411 builder_.AppendString(Handle<String>::cast(result)); | |
| 412 return SUCCESS; | |
| 413 } | |
| 414 | |
| 415 | |
| 416 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( | 391 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue( |
| 417 Handle<JSValue> object) { | 392 Handle<JSValue> object) { |
| 418 String* class_name = object->class_name(); | 393 String* class_name = object->class_name(); |
| 419 if (class_name == isolate_->heap()->String_string()) { | 394 if (class_name == isolate_->heap()->String_string()) { |
| 420 Handle<Object> value; | 395 Handle<Object> value; |
| 421 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 396 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 422 isolate_, value, Object::ToString(isolate_, object), EXCEPTION); | 397 isolate_, value, Object::ToString(isolate_, object), EXCEPTION); |
| 423 SerializeString(Handle<String>::cast(value)); | 398 SerializeString(Handle<String>::cast(value)); |
| 424 } else if (class_name == isolate_->heap()->Number_string()) { | 399 } else if (class_name == isolate_->heap()->Number_string()) { |
| 425 Handle<Object> value; | 400 Handle<Object> value; |
| 426 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, value, Object::ToNumber(object), | 401 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, value, Object::ToNumber(object), |
| 427 EXCEPTION); | 402 EXCEPTION); |
| 428 if (value->IsSmi()) return SerializeSmi(Smi::cast(*value)); | 403 if (value->IsSmi()) return SerializeSmi(Smi::cast(*value)); |
| 429 SerializeHeapNumber(Handle<HeapNumber>::cast(value)); | 404 SerializeHeapNumber(Handle<HeapNumber>::cast(value)); |
| 430 } else if (class_name == isolate_->heap()->Boolean_string()) { | 405 } else if (class_name == isolate_->heap()->Boolean_string()) { |
| 431 Object* value = JSValue::cast(*object)->value(); | 406 Object* value = JSValue::cast(*object)->value(); |
| 432 DCHECK(value->IsBoolean()); | 407 DCHECK(value->IsBoolean()); |
| 433 builder_.AppendCString(value->IsTrue() ? "true" : "false"); | 408 builder_.AppendCString(value->IsTrue() ? "true" : "false"); |
| 434 } else { | 409 } else { |
| 435 // ES6 24.3.2.1 step 10.c, serialize as an ordinary JSObject. | 410 // ES6 24.3.2.1 step 10.c, serialize as an ordinary JSObject. |
| 436 CHECK(!object->IsAccessCheckNeeded()); | |
| 437 CHECK(!object->IsJSGlobalProxy()); | |
| 438 return SerializeJSObject(object); | 411 return SerializeJSObject(object); |
| 439 } | 412 } |
| 440 return SUCCESS; | 413 return SUCCESS; |
| 441 } | 414 } |
| 442 | 415 |
| 443 | 416 |
| 444 BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) { | 417 BasicJsonStringifier::Result BasicJsonStringifier::SerializeSmi(Smi* object) { |
| 445 static const int kBufferSize = 100; | 418 static const int kBufferSize = 100; |
| 446 char chars[kBufferSize]; | 419 char chars[kBufferSize]; |
| 447 Vector<char> buffer(chars, kBufferSize); | 420 Vector<char> buffer(chars, kBufferSize); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 464 } | 437 } |
| 465 | 438 |
| 466 | 439 |
| 467 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( | 440 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray( |
| 468 Handle<JSArray> object) { | 441 Handle<JSArray> object) { |
| 469 HandleScope handle_scope(isolate_); | 442 HandleScope handle_scope(isolate_); |
| 470 Result stack_push = StackPush(object); | 443 Result stack_push = StackPush(object); |
| 471 if (stack_push != SUCCESS) return stack_push; | 444 if (stack_push != SUCCESS) return stack_push; |
| 472 uint32_t length = 0; | 445 uint32_t length = 0; |
| 473 CHECK(object->length()->ToArrayLength(&length)); | 446 CHECK(object->length()->ToArrayLength(&length)); |
| 447 DCHECK(!object->IsAccessCheckNeeded()); |
| 474 builder_.AppendCharacter('['); | 448 builder_.AppendCharacter('['); |
| 475 Indent(); | 449 Indent(); |
| 476 switch (object->GetElementsKind()) { | 450 switch (object->GetElementsKind()) { |
| 477 case FAST_SMI_ELEMENTS: { | 451 case FAST_SMI_ELEMENTS: { |
| 478 Handle<FixedArray> elements(FixedArray::cast(object->elements()), | 452 Handle<FixedArray> elements(FixedArray::cast(object->elements()), |
| 479 isolate_); | 453 isolate_); |
| 480 for (uint32_t i = 0; i < length; i++) { | 454 for (uint32_t i = 0; i < length; i++) { |
| 481 Separator(i == 0); | 455 Separator(i == 0); |
| 482 SerializeSmi(Smi::cast(elements->get(i))); | 456 SerializeSmi(Smi::cast(elements->get(i))); |
| 483 } | 457 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 } | 528 } |
| 555 } | 529 } |
| 556 return SUCCESS; | 530 return SUCCESS; |
| 557 } | 531 } |
| 558 | 532 |
| 559 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( | 533 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( |
| 560 Handle<JSObject> object) { | 534 Handle<JSObject> object) { |
| 561 HandleScope handle_scope(isolate_); | 535 HandleScope handle_scope(isolate_); |
| 562 Result stack_push = StackPush(object); | 536 Result stack_push = StackPush(object); |
| 563 if (stack_push != SUCCESS) return stack_push; | 537 if (stack_push != SUCCESS) return stack_push; |
| 564 DCHECK(!object->IsJSGlobalProxy() && !object->IsJSGlobalObject()); | |
| 565 | 538 |
| 566 if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER && | 539 if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER && |
| 567 object->HasFastProperties() && | 540 object->HasFastProperties() && |
| 568 Handle<JSObject>::cast(object)->elements()->length() == 0) { | 541 Handle<JSObject>::cast(object)->elements()->length() == 0) { |
| 569 DCHECK(object->IsJSObject()); | 542 DCHECK(object->IsJSObject()); |
| 543 DCHECK(!object->IsJSGlobalProxy()); |
| 570 Handle<JSObject> js_obj = Handle<JSObject>::cast(object); | 544 Handle<JSObject> js_obj = Handle<JSObject>::cast(object); |
| 571 DCHECK(!js_obj->HasIndexedInterceptor()); | 545 DCHECK(!js_obj->HasIndexedInterceptor()); |
| 572 DCHECK(!js_obj->HasNamedInterceptor()); | 546 DCHECK(!js_obj->HasNamedInterceptor()); |
| 573 Handle<Map> map(js_obj->map()); | 547 Handle<Map> map(js_obj->map()); |
| 574 builder_.AppendCharacter('{'); | 548 builder_.AppendCharacter('{'); |
| 575 Indent(); | 549 Indent(); |
| 576 bool comma = false; | 550 bool comma = false; |
| 577 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { | 551 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { |
| 578 Handle<Name> name(map->instance_descriptors()->GetKey(i), isolate_); | 552 Handle<Name> name(map->instance_descriptors()->GetKey(i), isolate_); |
| 579 // TODO(rossberg): Should this throw? | 553 // TODO(rossberg): Should this throw? |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 } else { | 741 } else { |
| 768 SerializeString_<uc16, uc16>(object); | 742 SerializeString_<uc16, uc16>(object); |
| 769 } | 743 } |
| 770 } | 744 } |
| 771 } | 745 } |
| 772 | 746 |
| 773 } // namespace internal | 747 } // namespace internal |
| 774 } // namespace v8 | 748 } // namespace v8 |
| 775 | 749 |
| 776 #endif // V8_JSON_STRINGIFIER_H_ | 750 #endif // V8_JSON_STRINGIFIER_H_ |
| OLD | NEW |