diff options
Diffstat (limited to 'deps/v8/src/json-stringifier.cc')
-rw-r--r-- | deps/v8/src/json-stringifier.cc | 122 |
1 files changed, 120 insertions, 2 deletions
diff --git a/deps/v8/src/json-stringifier.cc b/deps/v8/src/json-stringifier.cc index b1d95422b0c..91a1b7201bf 100644 --- a/deps/v8/src/json-stringifier.cc +++ b/deps/v8/src/json-stringifier.cc @@ -5,14 +5,128 @@ #include "src/json-stringifier.h" #include "src/conversions.h" +#include "src/heap/heap-inl.h" #include "src/lookup.h" #include "src/messages.h" #include "src/objects-inl.h" +#include "src/objects/js-array-inl.h" +#include "src/string-builder-inl.h" #include "src/utils.h" namespace v8 { namespace internal { +class JsonStringifier BASE_EMBEDDED { + public: + explicit JsonStringifier(Isolate* isolate); + + ~JsonStringifier() { DeleteArray(gap_); } + + V8_WARN_UNUSED_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); + + V8_WARN_UNUSED_RESULT MaybeHandle<Object> ApplyToJsonFunction( + Handle<Object> object, Handle<Object> key); + V8_WARN_UNUSED_RESULT MaybeHandle<Object> ApplyReplacerFunction( + Handle<Object> value, Handle<Object> key, Handle<Object> initial_holder); + + // Entry point to serialize the object. + V8_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. + V8_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. + V8_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); + + V8_INLINE void SerializeDeferredKey(bool deferred_comma, + Handle<Object> deferred_key); + + Result SerializeSmi(Smi* object); + + Result SerializeDouble(double number); + V8_INLINE Result SerializeHeapNumber(Handle<HeapNumber> object) { + return SerializeDouble(object->value()); + } + + Result SerializeJSValue(Handle<JSValue> object); + + V8_INLINE Result SerializeJSArray(Handle<JSArray> object); + V8_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> + V8_INLINE static void SerializeStringUnchecked_( + Vector<const SrcChar> src, + IncrementalStringBuilder::NoExtend<DestChar>* dest); + + template <typename SrcChar, typename DestChar> + V8_INLINE void SerializeString_(Handle<String> string); + + template <typename Char> + V8_INLINE static bool DoNotEscape(Char c); + + V8_INLINE void NewLine(); + V8_INLINE void Indent() { indent_++; } + V8_INLINE void Unindent() { indent_--; } + V8_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; +}; + +MaybeHandle<Object> JsonStringify(Isolate* isolate, Handle<Object> object, + Handle<Object> replacer, Handle<Object> gap) { + JsonStringifier stringifier(isolate); + return stringifier.Stringify(object, replacer, gap); +} + // Translation table to escape Latin1 characters. // Table entries start at a multiple of 8 and are null-terminated. const char* const JsonStringifier::JsonEscapeTable = @@ -112,7 +226,9 @@ bool JsonStringifier::InitializeReplacer(Handle<Object> replacer) { Handle<Object> length_obj; ASSIGN_RETURN_ON_EXCEPTION_VALUE( isolate_, length_obj, - Object::GetLengthFromArrayLike(isolate_, replacer), false); + Object::GetLengthFromArrayLike(isolate_, + Handle<JSReceiver>::cast(replacer)), + false); uint32_t length; if (!length_obj->ToUint32(&length)) length = kMaxUInt32; for (uint32_t i = 0; i < length; i++) { @@ -606,7 +722,9 @@ JsonStringifier::Result JsonStringifier::SerializeJSProxy( Handle<Object> length_object; ASSIGN_RETURN_ON_EXCEPTION_VALUE( isolate_, length_object, - Object::GetLengthFromArrayLike(isolate_, object), EXCEPTION); + Object::GetLengthFromArrayLike(isolate_, + Handle<JSReceiver>::cast(object)), + EXCEPTION); uint32_t length; if (!length_object->ToUint32(&length)) { // Technically, we need to be able to handle lengths outside the |