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