// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_JSON_STRINGIFIER_H_
#define V8_JSON_STRINGIFIER_H_
#include "src/objects.h"
#include "src/string-builder.h"
namespace v8 {
namespace internal {
class JsonStringifier BASE_EMBEDDED {
public:
explicit JsonStringifier(Isolate* isolate);
~JsonStringifier() { DeleteArray(gap_); }
MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object,
Handle<Object> replacer,
Handle<Object> gap);
private:
enum Result { UNCHANGED, SUCCESS, EXCEPTION };
bool InitializeReplacer(Handle<Object> replacer);
bool InitializeGap(Handle<Object> gap);
MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction(
Handle<Object> object,
Handle<Object> key);
MUST_USE_RESULT MaybeHandle<Object> ApplyReplacerFunction(
Handle<Object> value, Handle<Object> key, Handle<Object> initial_holder);
// Entry point to serialize the object.
INLINE(Result SerializeObject(Handle<Object> obj)) {
return Serialize_<false>(obj, false, factory()->empty_string());
}
// Serialize an array element.
// The index may serve as argument for the toJSON function.
INLINE(Result SerializeElement(Isolate* isolate,
Handle<Object> object,
int i)) {
return Serialize_<false>(object,
false,
Handle<Object>(Smi::FromInt(i), isolate));
}
// Serialize a object property.
// The key may or may not be serialized depending on the property.
// The key may also serve as argument for the toJSON function.
INLINE(Result SerializeProperty(Handle<Object> object,
bool deferred_comma,
Handle<String> deferred_key)) {
DCHECK(!deferred_key.is_null());
return Serialize_<true>(object, deferred_comma, deferred_key);
}
template <bool deferred_string_key>
Result Serialize_(Handle<Object> object, bool comma, Handle<Object> key);
INLINE(void SerializeDeferredKey(bool deferred_comma,
Handle<Object> deferred_key));
Result SerializeSmi(Smi* object);
Result SerializeDouble(double number);
INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) {
return SerializeDouble(object->value());
}
Result SerializeJSValue(Handle<JSValue> object);
INLINE(Result SerializeJSArray(Handle<JSArray> object));
INLINE(Result SerializeJSObject(Handle<JSObject> object));
Result SerializeJSProxy(Handle<JSProxy> object);
Result SerializeJSReceiverSlow(Handle<JSReceiver> object);
Result SerializeArrayLikeSlow(Handle<JSReceiver> object, uint32_t start,
uint32_t length);
void SerializeString(Handle<String> object);
template <typename SrcChar, typename DestChar>
INLINE(static void SerializeStringUnchecked_(
Vector<const SrcChar> src,
IncrementalStringBuilder::NoExtend<DestChar>* dest));
template <typename SrcChar, typename DestChar>
INLINE(void SerializeString_(Handle<String> string));
template <typename Char>
INLINE(static bool DoNotEscape(Char c));
INLINE(void NewLine());
INLINE(void Indent() { indent_++; });
INLINE(void Unindent() { indent_--; });
INLINE(void Separator(bool first));
Handle<JSReceiver> CurrentHolder(Handle<Object> value,
Handle<Object> inital_holder);
Result StackPush(Handle<Object> object);
void StackPop();
Factory* factory() { return isolate_->factory(); }
Isolate* isolate_;
IncrementalStringBuilder builder_;
Handle<String> tojson_string_;
Handle<JSArray> stack_;
Handle<FixedArray> property_list_;
Handle<JSReceiver> replacer_function_;
uc16* gap_;
int indent_;
static const int kJsonEscapeTableEntrySize = 8;
static const char* const JsonEscapeTable;
};
} // namespace internal
} // namespace v8
#endif // V8_JSON_STRINGIFIER_H_