blob: e72bd9d3d2205e9b124fa78b1d83da90bf36f64e [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch61f157c2016-09-16 13:49:30 +01008#include "src/objects.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04009#include "src/string-builder.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010
11namespace v8 {
12namespace internal {
13
Ben Murdoch61f157c2016-09-16 13:49:30 +010014class JsonStringifier BASE_EMBEDDED {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015 public:
Ben Murdoch61f157c2016-09-16 13:49:30 +010016 explicit JsonStringifier(Isolate* isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017
Ben Murdoch61f157c2016-09-16 13:49:30 +010018 ~JsonStringifier() { DeleteArray(gap_); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019
Ben Murdoch61f157c2016-09-16 13:49:30 +010020 MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object,
21 Handle<Object> replacer,
22 Handle<Object> gap);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023
24 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025 enum Result { UNCHANGED, SUCCESS, EXCEPTION };
26
Ben Murdoch61f157c2016-09-16 13:49:30 +010027 bool InitializeReplacer(Handle<Object> replacer);
28 bool InitializeGap(Handle<Object> gap);
29
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030 MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction(
31 Handle<Object> object,
32 Handle<Object> key);
Ben Murdoch61f157c2016-09-16 13:49:30 +010033 MUST_USE_RESULT MaybeHandle<Object> ApplyReplacerFunction(
34 Handle<Object> value, Handle<Object> key, Handle<Object> initial_holder);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036 // Entry point to serialize the object.
37 INLINE(Result SerializeObject(Handle<Object> obj)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040038 return Serialize_<false>(obj, false, factory()->empty_string());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039 }
40
41 // Serialize an array element.
42 // The index may serve as argument for the toJSON function.
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.
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
Ben Murdoch61f157c2016-09-16 13:49:30 +010064 INLINE(void SerializeDeferredKey(bool deferred_comma,
65 Handle<Object> deferred_key));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066
67 Result SerializeSmi(Smi* object);
68
69 Result SerializeDouble(double number);
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
Ben Murdoch61f157c2016-09-16 13:49:30 +010079 Result SerializeJSProxy(Handle<JSProxy> object);
80 Result SerializeJSReceiverSlow(Handle<JSReceiver> object);
81 Result SerializeArrayLikeSlow(Handle<JSReceiver> object, uint32_t start,
82 uint32_t length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083
84 void SerializeString(Handle<String> object);
85
86 template <typename SrcChar, typename DestChar>
Emily Bernierd0a1eb72015-03-24 16:35:39 -040087 INLINE(static void SerializeStringUnchecked_(
88 Vector<const SrcChar> src,
89 IncrementalStringBuilder::NoExtend<DestChar>* dest));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090
Emily Bernierd0a1eb72015-03-24 16:35:39 -040091 template <typename SrcChar, typename DestChar>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092 INLINE(void SerializeString_(Handle<String> string));
93
94 template <typename Char>
95 INLINE(static bool DoNotEscape(Char c));
96
Ben Murdoch61f157c2016-09-16 13:49:30 +010097 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105 Result StackPush(Handle<Object> object);
106 void StackPop();
107
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400108 Factory* factory() { return isolate_->factory(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109
110 Isolate* isolate_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400111 IncrementalStringBuilder builder_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 Handle<String> tojson_string_;
113 Handle<JSArray> stack_;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100114 Handle<FixedArray> property_list_;
115 Handle<JSReceiver> replacer_function_;
116 uc16* gap_;
117 int indent_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118
119 static const int kJsonEscapeTableEntrySize = 8;
120 static const char* const JsonEscapeTable;
121};
122
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123} // namespace internal
124} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000125
126#endif // V8_JSON_STRINGIFIER_H_