summaryrefslogtreecommitdiff
path: root/chromium/v8/src/json-stringifier.h
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/v8/src/json-stringifier.h
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
downloadqtwebengine-chromium-ab0a50979b9eb4dfa3320eff7e187e41efedf7a9.tar.gz
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/v8/src/json-stringifier.h')
-rw-r--r--chromium/v8/src/json-stringifier.h288
1 files changed, 155 insertions, 133 deletions
diff --git a/chromium/v8/src/json-stringifier.h b/chromium/v8/src/json-stringifier.h
index 4510c4b45b6..03461d72353 100644
--- a/chromium/v8/src/json-stringifier.h
+++ b/chromium/v8/src/json-stringifier.h
@@ -1,36 +1,13 @@
// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 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 "v8.h"
-#include "v8utils.h"
-#include "v8conversions.h"
+#include "src/v8.h"
+#include "src/conversions.h"
+#include "src/utils.h"
namespace v8 {
namespace internal {
@@ -39,17 +16,20 @@ class BasicJsonStringifier BASE_EMBEDDED {
public:
explicit BasicJsonStringifier(Isolate* isolate);
- MaybeObject* Stringify(Handle<Object> object);
+ MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object);
- INLINE(static MaybeObject* StringifyString(Isolate* isolate,
- Handle<String> object));
+ MUST_USE_RESULT INLINE(static MaybeHandle<Object> StringifyString(
+ Isolate* isolate,
+ Handle<String> object));
private:
static const int kInitialPartLength = 32;
static const int kMaxPartLength = 16 * 1024;
static const int kPartLengthGrowthFactor = 2;
- enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW };
+ enum Result { UNCHANGED, SUCCESS, EXCEPTION };
+
+ void Accumulate();
void Extend();
@@ -79,8 +59,9 @@ class BasicJsonStringifier BASE_EMBEDDED {
}
}
- Handle<Object> ApplyToJsonFunction(Handle<Object> object,
- Handle<Object> key);
+ MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction(
+ Handle<Object> object,
+ Handle<Object> key);
Result SerializeGeneric(Handle<Object> object,
Handle<Object> key,
@@ -88,9 +69,9 @@ class BasicJsonStringifier BASE_EMBEDDED {
bool deferred_key);
template <typename ResultType, typename Char>
- INLINE(static MaybeObject* StringifyString_(Isolate* isolate,
- Vector<Char> vector,
- Handle<String> result));
+ INLINE(static Handle<String> StringifyString_(Isolate* isolate,
+ Vector<Char> vector,
+ Handle<String> result));
// Entry point to serialize the object.
INLINE(Result SerializeObject(Handle<Object> obj)) {
@@ -138,7 +119,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
INLINE(Result SerializeJSArray(Handle<JSArray> object));
INLINE(Result SerializeJSObject(Handle<JSObject> object));
- Result SerializeJSArraySlow(Handle<JSArray> object, int length);
+ Result SerializeJSArraySlow(Handle<JSArray> object, uint32_t length);
void SerializeString(Handle<String> object);
@@ -178,6 +159,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
int current_index_;
int part_length_;
bool is_ascii_;
+ bool overflowed_;
static const int kJsonEscapeTableEntrySize = 8;
static const char* const JsonEscapeTable;
@@ -254,37 +236,39 @@ const char* const BasicJsonStringifier::JsonEscapeTable =
BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
- : isolate_(isolate), current_index_(0), is_ascii_(true) {
+ : isolate_(isolate),
+ current_index_(0),
+ is_ascii_(true),
+ overflowed_(false) {
factory_ = isolate_->factory();
accumulator_store_ = Handle<JSValue>::cast(
- factory_->ToObject(factory_->empty_string()));
+ Object::ToObject(isolate, factory_->empty_string()).ToHandleChecked());
part_length_ = kInitialPartLength;
- current_part_ = factory_->NewRawOneByteString(part_length_);
+ current_part_ = factory_->NewRawOneByteString(part_length_).ToHandleChecked();
tojson_string_ = factory_->toJSON_string();
stack_ = factory_->NewJSArray(8);
}
-MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) {
- switch (SerializeObject(object)) {
- case UNCHANGED:
- return isolate_->heap()->undefined_value();
- case SUCCESS:
- ShrinkCurrentPart();
- return *factory_->NewConsString(accumulator(), current_part_);
- case CIRCULAR:
- return isolate_->Throw(*factory_->NewTypeError(
- "circular_structure", HandleVector<Object>(NULL, 0)));
- case STACK_OVERFLOW:
- return isolate_->StackOverflow();
- default:
- return Failure::Exception();
+MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) {
+ Result result = SerializeObject(object);
+ if (result == UNCHANGED) return isolate_->factory()->undefined_value();
+ if (result == SUCCESS) {
+ ShrinkCurrentPart();
+ Accumulate();
+ if (overflowed_) {
+ return isolate_->Throw<Object>(
+ isolate_->factory()->NewInvalidStringLengthError());
+ }
+ return accumulator();
}
+ ASSERT(result == EXCEPTION);
+ return MaybeHandle<Object>();
}
-MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
- Handle<String> object) {
+MaybeHandle<Object> BasicJsonStringifier::StringifyString(
+ Isolate* isolate, Handle<String> object) {
static const int kJsonQuoteWorstCaseBlowup = 6;
static const int kSpaceForQuotes = 2;
int worst_case_length =
@@ -295,19 +279,19 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
return stringifier.Stringify(object);
}
- FlattenString(object);
+ object = String::Flatten(object);
ASSERT(object->IsFlat());
if (object->IsOneByteRepresentationUnderneath()) {
- Handle<String> result =
- isolate->factory()->NewRawOneByteString(worst_case_length);
+ Handle<String> result = isolate->factory()->NewRawOneByteString(
+ worst_case_length).ToHandleChecked();
DisallowHeapAllocation no_gc;
return StringifyString_<SeqOneByteString>(
isolate,
object->GetFlatContent().ToOneByteVector(),
result);
} else {
- Handle<String> result =
- isolate->factory()->NewRawTwoByteString(worst_case_length);
+ Handle<String> result = isolate->factory()->NewRawTwoByteString(
+ worst_case_length).ToHandleChecked();
DisallowHeapAllocation no_gc;
return StringifyString_<SeqTwoByteString>(
isolate,
@@ -318,9 +302,9 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
template <typename ResultType, typename Char>
-MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
- Vector<Char> vector,
- Handle<String> result) {
+Handle<String> BasicJsonStringifier::StringifyString_(Isolate* isolate,
+ Vector<Char> vector,
+ Handle<String> result) {
DisallowHeapAllocation no_gc;
int final_size = 0;
ResultType* dest = ResultType::cast(*result);
@@ -329,7 +313,7 @@ MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
dest->GetChars() + 1,
vector.length());
dest->Set(final_size++, '\"');
- return *SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
+ return SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
}
@@ -352,25 +336,21 @@ void BasicJsonStringifier::Append_(const Char* chars) {
}
-Handle<Object> BasicJsonStringifier::ApplyToJsonFunction(
+MaybeHandle<Object> BasicJsonStringifier::ApplyToJsonFunction(
Handle<Object> object, Handle<Object> key) {
- LookupResult lookup(isolate_);
- JSObject::cast(*object)->LookupRealNamedProperty(*tojson_string_, &lookup);
- if (!lookup.IsProperty()) return object;
- PropertyAttributes attr;
- Handle<Object> fun =
- Object::GetProperty(object, object, &lookup, tojson_string_, &attr);
- if (fun.is_null()) return Handle<Object>::null();
+ LookupIterator it(object, tojson_string_, LookupIterator::SKIP_INTERCEPTOR);
+ Handle<Object> fun;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate_, fun, Object::GetProperty(&it), Object);
if (!fun->IsJSFunction()) return object;
// Call toJSON function.
if (key->IsSmi()) key = factory_->NumberToString(key);
Handle<Object> argv[] = { key };
- bool has_exception = false;
HandleScope scope(isolate_);
- object = Execution::Call(isolate_, fun, object, 1, argv, &has_exception);
- // Return empty handle to signal an exception.
- if (has_exception) return Handle<Object>::null();
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate_, object,
+ Execution::Call(isolate_, fun, object, 1, argv),
+ Object);
return scope.CloseAndEscape(object);
}
@@ -378,16 +358,25 @@ Handle<Object> BasicJsonStringifier::ApplyToJsonFunction(
BasicJsonStringifier::Result BasicJsonStringifier::StackPush(
Handle<Object> object) {
StackLimitCheck check(isolate_);
- if (check.HasOverflowed()) return STACK_OVERFLOW;
+ if (check.HasOverflowed()) {
+ isolate_->StackOverflow();
+ return EXCEPTION;
+ }
int length = Smi::cast(stack_->length())->value();
- FixedArray* elements = FixedArray::cast(stack_->elements());
- for (int i = 0; i < length; i++) {
- if (elements->get(i) == *object) {
- return CIRCULAR;
+ {
+ DisallowHeapAllocation no_allocation;
+ FixedArray* elements = FixedArray::cast(stack_->elements());
+ for (int i = 0; i < length; i++) {
+ if (elements->get(i) == *object) {
+ AllowHeapAllocation allow_to_return_error;
+ isolate_->Throw(*factory_->NewTypeError(
+ "circular_structure", HandleVector<Object>(NULL, 0)));
+ return EXCEPTION;
+ }
}
}
- stack_->EnsureSize(length + 1);
+ JSArray::EnsureSize(stack_, length + 1);
FixedArray::cast(stack_->elements())->set(length, *object);
stack_->set_length(Smi::FromInt(length + 1));
return SUCCESS;
@@ -404,8 +393,10 @@ template <bool deferred_string_key>
BasicJsonStringifier::Result BasicJsonStringifier::Serialize_(
Handle<Object> object, bool comma, Handle<Object> key) {
if (object->IsJSObject()) {
- object = ApplyToJsonFunction(object, key);
- if (object.is_null()) return EXCEPTION;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, object,
+ ApplyToJsonFunction(object, key),
+ EXCEPTION);
}
if (object->IsSmi()) {
@@ -464,15 +455,16 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
Handle<Object> key,
bool deferred_comma,
bool deferred_key) {
- Handle<JSObject> builtins(isolate_->native_context()->builtins());
- Handle<JSFunction> builtin =
- Handle<JSFunction>::cast(GetProperty(builtins, "JSONSerializeAdapter"));
+ Handle<JSObject> builtins(isolate_->native_context()->builtins(), isolate_);
+ Handle<JSFunction> builtin = Handle<JSFunction>::cast(Object::GetProperty(
+ isolate_, builtins, "JSONSerializeAdapter").ToHandleChecked());
Handle<Object> argv[] = { key, object };
- bool has_exception = false;
- Handle<Object> result =
- Execution::Call(isolate_, builtin, object, 2, argv, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<Object> result;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, result,
+ Execution::Call(isolate_, builtin, object, 2, argv),
+ EXCEPTION);
if (result->IsUndefined()) return UNCHANGED;
if (deferred_key) {
if (key->IsSmi()) key = factory_->NumberToString(key);
@@ -486,24 +478,28 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
part_length_ = kInitialPartLength; // Allocate conservatively.
Extend(); // Attach current part and allocate new part.
// Attach result string to the accumulator.
- set_accumulator(factory_->NewConsString(accumulator(), result_string));
+ Handle<String> cons;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, cons,
+ factory_->NewConsString(accumulator(), result_string),
+ EXCEPTION);
+ set_accumulator(cons);
return SUCCESS;
}
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSValue(
Handle<JSValue> object) {
- bool has_exception = false;
String* class_name = object->class_name();
if (class_name == isolate_->heap()->String_string()) {
- Handle<Object> value =
- Execution::ToString(isolate_, object, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, value, Execution::ToString(isolate_, object), EXCEPTION);
SerializeString(Handle<String>::cast(value));
} else if (class_name == isolate_->heap()->Number_string()) {
- Handle<Object> value =
- Execution::ToNumber(isolate_, object, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, value, Execution::ToNumber(isolate_, object), EXCEPTION);
if (value->IsSmi()) return SerializeSmi(Smi::cast(*value));
SerializeHeapNumber(Handle<HeapNumber>::cast(value));
} else {
@@ -544,22 +540,25 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
HandleScope handle_scope(isolate_);
Result stack_push = StackPush(object);
if (stack_push != SUCCESS) return stack_push;
- int length = Smi::cast(object->length())->value();
+ uint32_t length = 0;
+ CHECK(object->length()->ToArrayIndex(&length));
Append('[');
switch (object->GetElementsKind()) {
case FAST_SMI_ELEMENTS: {
Handle<FixedArray> elements(
FixedArray::cast(object->elements()), isolate_);
- for (int i = 0; i < length; i++) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
SerializeSmi(Smi::cast(elements->get(i)));
}
break;
}
case FAST_DOUBLE_ELEMENTS: {
+ // Empty array is FixedArray but not FixedDoubleArray.
+ if (length == 0) break;
Handle<FixedDoubleArray> elements(
FixedDoubleArray::cast(object->elements()), isolate_);
- for (int i = 0; i < length; i++) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
SerializeDouble(elements->get_scalar(i));
}
@@ -568,7 +567,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
case FAST_ELEMENTS: {
Handle<FixedArray> elements(
FixedArray::cast(object->elements()), isolate_);
- for (int i = 0; i < length; i++) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
Result result =
SerializeElement(isolate_,
@@ -600,11 +599,14 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow(
- Handle<JSArray> object, int length) {
- for (int i = 0; i < length; i++) {
+ Handle<JSArray> object, uint32_t length) {
+ for (uint32_t i = 0; i < length; i++) {
if (i > 0) Append(',');
- Handle<Object> element = Object::GetElement(isolate_, object, i);
- RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, element, EXCEPTION);
+ Handle<Object> element;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, element,
+ Object::GetElement(isolate_, object, i),
+ EXCEPTION);
if (element->IsUndefined()) {
AppendAscii("null");
} else {
@@ -649,48 +651,51 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
if (details.IsDontEnum()) continue;
Handle<Object> property;
if (details.type() == FIELD && *map == object->map()) {
- property = Handle<Object>(
- object->RawFastPropertyAt(
- map->instance_descriptors()->GetFieldIndex(i)),
- isolate_);
+ property = Handle<Object>(object->RawFastPropertyAt(
+ FieldIndex::ForDescriptor(*map, i)), isolate_);
} else {
- property = GetProperty(isolate_, object, key);
- if (property.is_null()) return EXCEPTION;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, property,
+ Object::GetPropertyOrElement(object, key),
+ EXCEPTION);
}
Result result = SerializeProperty(property, comma, key);
if (!comma && result == SUCCESS) comma = true;
- if (result >= EXCEPTION) return result;
+ if (result == EXCEPTION) return result;
}
} else {
- bool has_exception = false;
- Handle<FixedArray> contents =
- GetKeysInFixedArrayFor(object, LOCAL_ONLY, &has_exception);
- if (has_exception) return EXCEPTION;
+ Handle<FixedArray> contents;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, contents,
+ JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY),
+ EXCEPTION);
for (int i = 0; i < contents->length(); i++) {
Object* key = contents->get(i);
Handle<String> key_handle;
- Handle<Object> property;
+ MaybeHandle<Object> maybe_property;
if (key->IsString()) {
key_handle = Handle<String>(String::cast(key), isolate_);
- property = GetProperty(isolate_, object, key_handle);
+ maybe_property = Object::GetPropertyOrElement(object, key_handle);
} else {
ASSERT(key->IsNumber());
key_handle = factory_->NumberToString(Handle<Object>(key, isolate_));
uint32_t index;
if (key->IsSmi()) {
- property = Object::GetElement(
+ maybe_property = Object::GetElement(
isolate_, object, Smi::cast(key)->value());
} else if (key_handle->AsArrayIndex(&index)) {
- property = Object::GetElement(isolate_, object, index);
+ maybe_property = Object::GetElement(isolate_, object, index);
} else {
- property = GetProperty(isolate_, object, key_handle);
+ maybe_property = Object::GetPropertyOrElement(object, key_handle);
}
}
- if (property.is_null()) return EXCEPTION;
+ Handle<Object> property;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, property, maybe_property, EXCEPTION);
Result result = SerializeProperty(property, comma, key_handle);
if (!comma && result == SUCCESS) comma = true;
- if (result >= EXCEPTION) return result;
+ if (result == EXCEPTION) return result;
}
}
@@ -708,24 +713,41 @@ void BasicJsonStringifier::ShrinkCurrentPart() {
}
+void BasicJsonStringifier::Accumulate() {
+ if (accumulator()->length() + current_part_->length() > String::kMaxLength) {
+ // Screw it. Simply set the flag and carry on. Throw exception at the end.
+ set_accumulator(factory_->empty_string());
+ overflowed_ = true;
+ } else {
+ set_accumulator(factory_->NewConsString(accumulator(),
+ current_part_).ToHandleChecked());
+ }
+}
+
+
void BasicJsonStringifier::Extend() {
- set_accumulator(factory_->NewConsString(accumulator(), current_part_));
+ Accumulate();
if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
part_length_ *= kPartLengthGrowthFactor;
}
if (is_ascii_) {
- current_part_ = factory_->NewRawOneByteString(part_length_);
+ current_part_ =
+ factory_->NewRawOneByteString(part_length_).ToHandleChecked();
} else {
- current_part_ = factory_->NewRawTwoByteString(part_length_);
+ current_part_ =
+ factory_->NewRawTwoByteString(part_length_).ToHandleChecked();
}
+ ASSERT(!current_part_.is_null());
current_index_ = 0;
}
void BasicJsonStringifier::ChangeEncoding() {
ShrinkCurrentPart();
- set_accumulator(factory_->NewConsString(accumulator(), current_part_));
- current_part_ = factory_->NewRawTwoByteString(part_length_);
+ Accumulate();
+ current_part_ =
+ factory_->NewRawTwoByteString(part_length_).ToHandleChecked();
+ ASSERT(!current_part_.is_null());
current_index_ = 0;
is_ascii_ = false;
}
@@ -834,7 +856,7 @@ Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
void BasicJsonStringifier::SerializeString(Handle<String> object) {
- object = FlattenGetString(object);
+ object = String::Flatten(object);
if (is_ascii_) {
if (object->IsOneByteRepresentationUnderneath()) {
SerializeString_<true, uint8_t>(object);