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 3 // found in the LICENSE file. 4 5 #ifndef V8_JSON_STRINGIFIER_H_ 6 #define V8_JSON_STRINGIFIER_H_ 7 8 #include "src/objects.h" 9 #include "src/string-builder.h" 10 11 namespace v8 { 12 namespace internal { 13 14 class JsonStringifier BASE_EMBEDDED { 15 public: 16 explicit JsonStringifier(Isolate* isolate); 17 ~JsonStringifier()18 ~JsonStringifier() { DeleteArray(gap_); } 19 20 MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object, 21 Handle<Object> replacer, 22 Handle<Object> gap); 23 24 private: 25 enum Result { UNCHANGED, SUCCESS, EXCEPTION }; 26 27 bool InitializeReplacer(Handle<Object> replacer); 28 bool InitializeGap(Handle<Object> gap); 29 30 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction( 31 Handle<Object> object, 32 Handle<Object> key); 33 MUST_USE_RESULT MaybeHandle<Object> ApplyReplacerFunction( 34 Handle<Object> value, Handle<Object> key, Handle<Object> initial_holder); 35 36 // Entry point to serialize the object. INLINE(Result SerializeObject (Handle<Object> obj))37 INLINE(Result SerializeObject(Handle<Object> obj)) { 38 return Serialize_<false>(obj, false, factory()->empty_string()); 39 } 40 41 // Serialize an array element. 42 // The index may serve as argument for the toJSON function. INLINE(Result SerializeElement (Isolate * isolate,Handle<Object> object,int i))43 INLINE(Result SerializeElement(Isolate* isolate, 44 Handle<Object> object, 45 int i)) { 46 return Serialize_<false>(object, 47 false, 48 Handle<Object>(Smi::FromInt(i), isolate)); 49 } 50 51 // Serialize a object property. 52 // The key may or may not be serialized depending on the property. 53 // The key may also serve as argument for the toJSON function. INLINE(Result SerializeProperty (Handle<Object> object,bool deferred_comma,Handle<String> deferred_key))54 INLINE(Result SerializeProperty(Handle<Object> object, 55 bool deferred_comma, 56 Handle<String> deferred_key)) { 57 DCHECK(!deferred_key.is_null()); 58 return Serialize_<true>(object, deferred_comma, deferred_key); 59 } 60 61 template <bool deferred_string_key> 62 Result Serialize_(Handle<Object> object, bool comma, Handle<Object> key); 63 64 INLINE(void SerializeDeferredKey(bool deferred_comma, 65 Handle<Object> deferred_key)); 66 67 Result SerializeSmi(Smi* object); 68 69 Result SerializeDouble(double number); INLINE(Result SerializeHeapNumber (Handle<HeapNumber> object))70 INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) { 71 return SerializeDouble(object->value()); 72 } 73 74 Result SerializeJSValue(Handle<JSValue> object); 75 76 INLINE(Result SerializeJSArray(Handle<JSArray> object)); 77 INLINE(Result SerializeJSObject(Handle<JSObject> object)); 78 79 Result SerializeJSProxy(Handle<JSProxy> object); 80 Result SerializeJSReceiverSlow(Handle<JSReceiver> object); 81 Result SerializeArrayLikeSlow(Handle<JSReceiver> object, uint32_t start, 82 uint32_t length); 83 84 void SerializeString(Handle<String> object); 85 86 template <typename SrcChar, typename DestChar> 87 INLINE(static void SerializeStringUnchecked_( 88 Vector<const SrcChar> src, 89 IncrementalStringBuilder::NoExtend<DestChar>* dest)); 90 91 template <typename SrcChar, typename DestChar> 92 INLINE(void SerializeString_(Handle<String> string)); 93 94 template <typename Char> 95 INLINE(static bool DoNotEscape(Char c)); 96 97 INLINE(void NewLine()); 98 INLINE(void Indent() { indent_++; }); 99 INLINE(void Unindent() { indent_--; }); 100 INLINE(void Separator(bool first)); 101 102 Handle<JSReceiver> CurrentHolder(Handle<Object> value, 103 Handle<Object> inital_holder); 104 105 Result StackPush(Handle<Object> object); 106 void StackPop(); 107 factory()108 Factory* factory() { return isolate_->factory(); } 109 110 Isolate* isolate_; 111 IncrementalStringBuilder builder_; 112 Handle<String> tojson_string_; 113 Handle<JSArray> stack_; 114 Handle<FixedArray> property_list_; 115 Handle<JSReceiver> replacer_function_; 116 uc16* gap_; 117 int indent_; 118 119 static const int kJsonEscapeTableEntrySize = 8; 120 static const char* const JsonEscapeTable; 121 }; 122 123 } // namespace internal 124 } // namespace v8 125 126 #endif // V8_JSON_STRINGIFIER_H_ 127