Commit b4932fc2 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Handlify BasicJsonStringifier.

R=ishell@chromium.org

Review URL: https://codereview.chromium.org/238273005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20768 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a650916d
...@@ -39,17 +39,18 @@ class BasicJsonStringifier BASE_EMBEDDED { ...@@ -39,17 +39,18 @@ class BasicJsonStringifier BASE_EMBEDDED {
public: public:
explicit BasicJsonStringifier(Isolate* isolate); explicit BasicJsonStringifier(Isolate* isolate);
MaybeObject* Stringify(Handle<Object> object); MUST_USE_RESULT MaybeHandle<Object> Stringify(Handle<Object> object);
INLINE(static MaybeObject* StringifyString(Isolate* isolate, MUST_USE_RESULT INLINE(static MaybeHandle<Object> StringifyString(
Handle<String> object)); Isolate* isolate,
Handle<String> object));
private: private:
static const int kInitialPartLength = 32; static const int kInitialPartLength = 32;
static const int kMaxPartLength = 16 * 1024; static const int kMaxPartLength = 16 * 1024;
static const int kPartLengthGrowthFactor = 2; static const int kPartLengthGrowthFactor = 2;
enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW }; enum Result { UNCHANGED, SUCCESS, EXCEPTION };
void Accumulate(); void Accumulate();
...@@ -91,9 +92,9 @@ class BasicJsonStringifier BASE_EMBEDDED { ...@@ -91,9 +92,9 @@ class BasicJsonStringifier BASE_EMBEDDED {
bool deferred_key); bool deferred_key);
template <typename ResultType, typename Char> template <typename ResultType, typename Char>
INLINE(static MaybeObject* StringifyString_(Isolate* isolate, INLINE(static Handle<String> StringifyString_(Isolate* isolate,
Vector<Char> vector, Vector<Char> vector,
Handle<String> result)); Handle<String> result));
// Entry point to serialize the object. // Entry point to serialize the object.
INLINE(Result SerializeObject(Handle<Object> obj)) { INLINE(Result SerializeObject(Handle<Object> obj)) {
...@@ -272,29 +273,25 @@ BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate) ...@@ -272,29 +273,25 @@ BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
} }
MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) { MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) {
switch (SerializeObject(object)) { Result result = SerializeObject(object);
case UNCHANGED: if (result == UNCHANGED) return isolate_->factory()->undefined_value();
return isolate_->heap()->undefined_value(); if (result == SUCCESS) {
case SUCCESS: { ShrinkCurrentPart();
ShrinkCurrentPart(); Accumulate();
Accumulate(); if (overflowed_) {
if (overflowed_) return isolate_->ThrowInvalidStringLength(); return isolate_->Throw<Object>(
return *accumulator(); isolate_->factory()->NewInvalidStringLengthError());
} }
case CIRCULAR: return accumulator();
return isolate_->Throw(*factory_->NewTypeError(
"circular_structure", HandleVector<Object>(NULL, 0)));
case STACK_OVERFLOW:
return isolate_->StackOverflow();
default:
return Failure::Exception();
} }
ASSERT(result == EXCEPTION);
return MaybeHandle<Object>();
} }
MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate, MaybeHandle<Object> BasicJsonStringifier::StringifyString(
Handle<String> object) { Isolate* isolate, Handle<String> object) {
static const int kJsonQuoteWorstCaseBlowup = 6; static const int kJsonQuoteWorstCaseBlowup = 6;
static const int kSpaceForQuotes = 2; static const int kSpaceForQuotes = 2;
int worst_case_length = int worst_case_length =
...@@ -328,9 +325,9 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate, ...@@ -328,9 +325,9 @@ MaybeObject* BasicJsonStringifier::StringifyString(Isolate* isolate,
template <typename ResultType, typename Char> template <typename ResultType, typename Char>
MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate, Handle<String> BasicJsonStringifier::StringifyString_(Isolate* isolate,
Vector<Char> vector, Vector<Char> vector,
Handle<String> result) { Handle<String> result) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
int final_size = 0; int final_size = 0;
ResultType* dest = ResultType::cast(*result); ResultType* dest = ResultType::cast(*result);
...@@ -339,7 +336,7 @@ MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate, ...@@ -339,7 +336,7 @@ MaybeObject* BasicJsonStringifier::StringifyString_(Isolate* isolate,
dest->GetChars() + 1, dest->GetChars() + 1,
vector.length()); vector.length());
dest->Set(final_size++, '\"'); dest->Set(final_size++, '\"');
return *SeqString::Truncate(Handle<SeqString>::cast(result), final_size); return SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
} }
...@@ -390,7 +387,10 @@ MaybeHandle<Object> BasicJsonStringifier::ApplyToJsonFunction( ...@@ -390,7 +387,10 @@ MaybeHandle<Object> BasicJsonStringifier::ApplyToJsonFunction(
BasicJsonStringifier::Result BasicJsonStringifier::StackPush( BasicJsonStringifier::Result BasicJsonStringifier::StackPush(
Handle<Object> object) { Handle<Object> object) {
StackLimitCheck check(isolate_); StackLimitCheck check(isolate_);
if (check.HasOverflowed()) return STACK_OVERFLOW; if (check.HasOverflowed()) {
isolate_->StackOverflow();
return EXCEPTION;
}
int length = Smi::cast(stack_->length())->value(); int length = Smi::cast(stack_->length())->value();
{ {
...@@ -398,7 +398,10 @@ BasicJsonStringifier::Result BasicJsonStringifier::StackPush( ...@@ -398,7 +398,10 @@ BasicJsonStringifier::Result BasicJsonStringifier::StackPush(
FixedArray* elements = FixedArray::cast(stack_->elements()); FixedArray* elements = FixedArray::cast(stack_->elements());
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
if (elements->get(i) == *object) { if (elements->get(i) == *object) {
return CIRCULAR; AllowHeapAllocation allow_to_return_error;
isolate_->Throw<Object>(factory_->NewTypeError(
"circular_structure", HandleVector<Object>(NULL, 0)));
return EXCEPTION;
} }
} }
} }
...@@ -686,7 +689,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( ...@@ -686,7 +689,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
} }
Result result = SerializeProperty(property, comma, key); Result result = SerializeProperty(property, comma, key);
if (!comma && result == SUCCESS) comma = true; if (!comma && result == SUCCESS) comma = true;
if (result >= EXCEPTION) return result; if (result == EXCEPTION) return result;
} }
} else { } else {
Handle<FixedArray> contents; Handle<FixedArray> contents;
...@@ -720,7 +723,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( ...@@ -720,7 +723,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
isolate_, property, maybe_property, EXCEPTION); isolate_, property, maybe_property, EXCEPTION);
Result result = SerializeProperty(property, comma, key_handle); Result result = SerializeProperty(property, comma, key_handle);
if (!comma && result == SUCCESS) comma = true; if (!comma && result == SUCCESS) comma = true;
if (result >= EXCEPTION) return result; if (result == EXCEPTION) return result;
} }
} }
......
...@@ -6278,7 +6278,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) { ...@@ -6278,7 +6278,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
HandleScope scope(isolate); HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(String, string, 0); CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
return BasicJsonStringifier::StringifyString(isolate, string); Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
return *result;
} }
...@@ -6286,7 +6289,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) { ...@@ -6286,7 +6289,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_BasicJSONStringify) {
HandleScope scope(isolate); HandleScope scope(isolate);
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
BasicJsonStringifier stringifier(isolate); BasicJsonStringifier stringifier(isolate);
return stringifier.Stringify(Handle<Object>(args[0], isolate)); Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, stringifier.Stringify(args.at<Object>(0)));
return *result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment