aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/json-stringifier.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/json-stringifier.cc')
-rw-r--r--deps/v8/src/json-stringifier.cc106
1 files changed, 52 insertions, 54 deletions
diff --git a/deps/v8/src/json-stringifier.cc b/deps/v8/src/json-stringifier.cc
index fe9a1468b1..1d3858f351 100644
--- a/deps/v8/src/json-stringifier.cc
+++ b/deps/v8/src/json-stringifier.cc
@@ -5,11 +5,13 @@
#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/message-template.h"
#include "src/objects-inl.h"
+#include "src/objects/heap-number-inl.h"
#include "src/objects/js-array-inl.h"
+#include "src/objects/oddball-inl.h"
+#include "src/objects/smi.h"
#include "src/string-builder-inl.h"
#include "src/utils.h"
@@ -65,19 +67,20 @@ class JsonStringifier {
V8_INLINE void SerializeDeferredKey(bool deferred_comma,
Handle<Object> deferred_key);
- Result SerializeSmi(Smi* object);
+ Result SerializeSmi(Smi object);
Result SerializeDouble(double number);
V8_INLINE Result SerializeHeapNumber(Handle<HeapNumber> object) {
return SerializeDouble(object->value());
}
- Result SerializeJSValue(Handle<JSValue> object);
+ Result SerializeJSValue(Handle<JSValue> object, Handle<Object> key);
- V8_INLINE Result SerializeJSArray(Handle<JSArray> object);
- V8_INLINE Result SerializeJSObject(Handle<JSObject> object);
+ V8_INLINE Result SerializeJSArray(Handle<JSArray> object, Handle<Object> key);
+ V8_INLINE Result SerializeJSObject(Handle<JSObject> object,
+ Handle<Object> key);
- Result SerializeJSProxy(Handle<JSProxy> object);
+ Result SerializeJSProxy(Handle<JSProxy> object, Handle<Object> key);
Result SerializeJSReceiverSlow(Handle<JSReceiver> object);
Result SerializeArrayLikeSlow(Handle<JSReceiver> object, uint32_t start,
uint32_t length);
@@ -103,7 +106,7 @@ class JsonStringifier {
Handle<JSReceiver> CurrentHolder(Handle<Object> value,
Handle<Object> inital_holder);
- Result StackPush(Handle<Object> object);
+ Result StackPush(Handle<Object> object, Handle<Object> key);
void StackPop();
Factory* factory() { return isolate_->factory(); }
@@ -111,12 +114,14 @@ class JsonStringifier {
Isolate* isolate_;
IncrementalStringBuilder builder_;
Handle<String> tojson_string_;
- Handle<JSArray> stack_;
Handle<FixedArray> property_list_;
Handle<JSReceiver> replacer_function_;
uc16* gap_;
int indent_;
+ using KeyObject = std::pair<Handle<Object>, Handle<Object>>;
+ std::vector<KeyObject> stack_;
+
static const int kJsonEscapeTableEntrySize = 8;
static const char* const JsonEscapeTable;
};
@@ -196,9 +201,12 @@ const char* const JsonStringifier::JsonEscapeTable =
"\xFC\0 \xFD\0 \xFE\0 \xFF\0 ";
JsonStringifier::JsonStringifier(Isolate* isolate)
- : isolate_(isolate), builder_(isolate), gap_(nullptr), indent_(0) {
+ : isolate_(isolate),
+ builder_(isolate),
+ gap_(nullptr),
+ indent_(0),
+ stack_() {
tojson_string_ = factory()->toJSON_string();
- stack_ = factory()->NewJSArray(8);
}
MaybeHandle<Object> JsonStringifier::Stringify(Handle<Object> object,
@@ -343,33 +351,30 @@ MaybeHandle<Object> JsonStringifier::ApplyReplacerFunction(
Handle<JSReceiver> JsonStringifier::CurrentHolder(
Handle<Object> value, Handle<Object> initial_holder) {
- int length = Smi::ToInt(stack_->length());
- if (length == 0) {
+ if (stack_.empty()) {
Handle<JSObject> holder =
factory()->NewJSObject(isolate_->object_function());
JSObject::AddProperty(isolate_, holder, factory()->empty_string(),
initial_holder, NONE);
return holder;
} else {
- FixedArray* elements = FixedArray::cast(stack_->elements());
- return Handle<JSReceiver>(JSReceiver::cast(elements->get(length - 1)),
+ return Handle<JSReceiver>(JSReceiver::cast(*stack_.back().second),
isolate_);
}
}
-JsonStringifier::Result JsonStringifier::StackPush(Handle<Object> object) {
+JsonStringifier::Result JsonStringifier::StackPush(Handle<Object> object,
+ Handle<Object> key) {
StackLimitCheck check(isolate_);
if (check.HasOverflowed()) {
isolate_->StackOverflow();
return EXCEPTION;
}
- int length = Smi::ToInt(stack_->length());
{
DisallowHeapAllocation no_allocation;
- FixedArray* elements = FixedArray::cast(stack_->elements());
- for (int i = 0; i < length; i++) {
- if (elements->get(i) == *object) {
+ for (const KeyObject& key_object : stack_) {
+ if (*key_object.second == *object) {
AllowHeapAllocation allow_to_return_error;
Handle<Object> error =
factory()->NewTypeError(MessageTemplate::kCircularStructure);
@@ -378,15 +383,11 @@ JsonStringifier::Result JsonStringifier::StackPush(Handle<Object> object) {
}
}
}
- JSArray::SetLength(stack_, length + 1);
- FixedArray::cast(stack_->elements())->set(length, *object);
+ stack_.emplace_back(key, object);
return SUCCESS;
}
-void JsonStringifier::StackPop() {
- int length = Smi::ToInt(stack_->length());
- stack_->set_length(Smi::FromInt(length - 1));
-}
+void JsonStringifier::StackPop() { stack_.pop_back(); }
template <bool deferred_string_key>
JsonStringifier::Result JsonStringifier::Serialize_(Handle<Object> object,
@@ -441,10 +442,10 @@ JsonStringifier::Result JsonStringifier::Serialize_(Handle<Object> object,
}
case JS_ARRAY_TYPE:
if (deferred_string_key) SerializeDeferredKey(comma, key);
- return SerializeJSArray(Handle<JSArray>::cast(object));
+ return SerializeJSArray(Handle<JSArray>::cast(object), key);
case JS_VALUE_TYPE:
if (deferred_string_key) SerializeDeferredKey(comma, key);
- return SerializeJSValue(Handle<JSValue>::cast(object));
+ return SerializeJSValue(Handle<JSValue>::cast(object), key);
case SYMBOL_TYPE:
return UNCHANGED;
default:
@@ -458,9 +459,9 @@ JsonStringifier::Result JsonStringifier::Serialize_(Handle<Object> object,
// Go to slow path for global proxy and objects requiring access checks.
if (deferred_string_key) SerializeDeferredKey(comma, key);
if (object->IsJSProxy()) {
- return SerializeJSProxy(Handle<JSProxy>::cast(object));
+ return SerializeJSProxy(Handle<JSProxy>::cast(object), key);
}
- return SerializeJSObject(Handle<JSObject>::cast(object));
+ return SerializeJSObject(Handle<JSObject>::cast(object), key);
}
}
@@ -468,8 +469,8 @@ JsonStringifier::Result JsonStringifier::Serialize_(Handle<Object> object,
}
JsonStringifier::Result JsonStringifier::SerializeJSValue(
- Handle<JSValue> object) {
- Object* raw = object->value();
+ Handle<JSValue> object, Handle<Object> key) {
+ Object raw = object->value();
if (raw->IsString()) {
Handle<Object> value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
@@ -489,12 +490,12 @@ JsonStringifier::Result JsonStringifier::SerializeJSValue(
builder_.AppendCString(raw->IsTrue(isolate_) ? "true" : "false");
} else {
// ES6 24.3.2.1 step 10.c, serialize as an ordinary JSObject.
- return SerializeJSObject(object);
+ return SerializeJSObject(object, key);
}
return SUCCESS;
}
-JsonStringifier::Result JsonStringifier::SerializeSmi(Smi* object) {
+JsonStringifier::Result JsonStringifier::SerializeSmi(Smi object) {
static const int kBufferSize = 100;
char chars[kBufferSize];
Vector<char> buffer(chars, kBufferSize);
@@ -515,9 +516,9 @@ JsonStringifier::Result JsonStringifier::SerializeDouble(double number) {
}
JsonStringifier::Result JsonStringifier::SerializeJSArray(
- Handle<JSArray> object) {
+ Handle<JSArray> object, Handle<Object> key) {
HandleScope handle_scope(isolate_);
- Result stack_push = StackPush(object);
+ Result stack_push = StackPush(object, key);
if (stack_push != SUCCESS) return stack_push;
uint32_t length = 0;
CHECK(object->length()->ToArrayLength(&length));
@@ -630,21 +631,18 @@ JsonStringifier::Result JsonStringifier::SerializeArrayLikeSlow(
}
JsonStringifier::Result JsonStringifier::SerializeJSObject(
- Handle<JSObject> object) {
+ Handle<JSObject> object, Handle<Object> key) {
HandleScope handle_scope(isolate_);
- Result stack_push = StackPush(object);
+ Result stack_push = StackPush(object, key);
if (stack_push != SUCCESS) return stack_push;
if (property_list_.is_null() &&
!object->map()->IsCustomElementsReceiverMap() &&
- object->HasFastProperties() &&
- Handle<JSObject>::cast(object)->elements()->length() == 0) {
- DCHECK(object->IsJSObject());
+ object->HasFastProperties() && object->elements()->length() == 0) {
DCHECK(!object->IsJSGlobalProxy());
- Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
- DCHECK(!js_obj->HasIndexedInterceptor());
- DCHECK(!js_obj->HasNamedInterceptor());
- Handle<Map> map(js_obj->map(), isolate_);
+ DCHECK(!object->HasIndexedInterceptor());
+ DCHECK(!object->HasNamedInterceptor());
+ Handle<Map> map(object->map(), isolate_);
builder_.AppendCharacter('{');
Indent();
bool comma = false;
@@ -656,15 +654,15 @@ JsonStringifier::Result JsonStringifier::SerializeJSObject(
PropertyDetails details = map->instance_descriptors()->GetDetails(i);
if (details.IsDontEnum()) continue;
Handle<Object> property;
- if (details.location() == kField && *map == js_obj->map()) {
+ if (details.location() == kField && *map == object->map()) {
DCHECK_EQ(kData, details.kind());
FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
- property = JSObject::FastPropertyAt(js_obj, details.representation(),
+ property = JSObject::FastPropertyAt(object, details.representation(),
field_index);
} else {
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate_, property,
- Object::GetPropertyOrElement(isolate_, js_obj, key), EXCEPTION);
+ Object::GetPropertyOrElement(isolate_, object, key), EXCEPTION);
}
Result result = SerializeProperty(property, comma, key);
if (!comma && result == SUCCESS) comma = true;
@@ -712,9 +710,9 @@ JsonStringifier::Result JsonStringifier::SerializeJSReceiverSlow(
}
JsonStringifier::Result JsonStringifier::SerializeJSProxy(
- Handle<JSProxy> object) {
+ Handle<JSProxy> object, Handle<Object> key) {
HandleScope scope(isolate_);
- Result stack_push = StackPush(object);
+ Result stack_push = StackPush(object, key);
if (stack_push != SUCCESS) return stack_push;
Maybe<bool> is_array = Object::IsArray(object);
if (is_array.IsNothing()) return EXCEPTION;
@@ -812,9 +810,9 @@ void JsonStringifier::SerializeString_(Handle<String> string) {
// part, or we might need to allocate.
if (int worst_case_length = builder_.EscapedLengthIfCurrentPartFits(length)) {
DisallowHeapAllocation no_gc;
- Vector<const SrcChar> vector = string->GetCharVector<SrcChar>();
+ Vector<const SrcChar> vector = string->GetCharVector<SrcChar>(no_gc);
IncrementalStringBuilder::NoExtendBuilder<DestChar> no_extend(
- &builder_, worst_case_length);
+ &builder_, worst_case_length, no_gc);
SerializeStringUnchecked_(vector, &no_extend);
} else {
FlatStringReader reader(isolate_, string);
@@ -904,14 +902,14 @@ void JsonStringifier::SerializeDeferredKey(bool deferred_comma,
void JsonStringifier::SerializeString(Handle<String> object) {
object = String::Flatten(isolate_, object);
if (builder_.CurrentEncoding() == String::ONE_BYTE_ENCODING) {
- if (object->IsOneByteRepresentationUnderneath()) {
+ if (String::IsOneByteRepresentationUnderneath(*object)) {
SerializeString_<uint8_t, uint8_t>(object);
} else {
builder_.ChangeEncoding();
SerializeString(object);
}
} else {
- if (object->IsOneByteRepresentationUnderneath()) {
+ if (String::IsOneByteRepresentationUnderneath(*object)) {
SerializeString_<uint8_t, uc16>(object);
} else {
SerializeString_<uc16, uc16>(object);