Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(875)

Unified Diff: src/json-stringifier.cc

Issue 2006663002: [json] implement JSON.stringify gap pre-processing in C++. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@jsonrefactor
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/json-stringifier.h ('k') | src/runtime/runtime-json.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/json-stringifier.cc
diff --git a/src/json-stringifier.cc b/src/json-stringifier.cc
index cc859929d79db46a6114f705ebe4df7f94c2e1c1..ac206822e9abc5b704c3aad1d8f09e18603c984a 100644
--- a/src/json-stringifier.cc
+++ b/src/json-stringifier.cc
@@ -81,29 +81,15 @@ const char* const BasicJsonStringifier::JsonEscapeTable =
"\370\0 \371\0 \372\0 \373\0 "
"\374\0 \375\0 \376\0 \377\0 ";
-BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate, Handle<String> gap)
- : isolate_(isolate), builder_(isolate), gap_string_(gap), indent_(0) {
+BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
+ : isolate_(isolate), builder_(isolate), gap_(nullptr), indent_(0) {
tojson_string_ = factory()->toJSON_string();
stack_ = factory()->NewJSArray(8);
- int gap_length = gap->length();
- if (gap_length != 0) {
- gap = String::Flatten(gap);
- if (gap->IsTwoByteRepresentation()) builder_.ChangeEncoding();
- DisallowHeapAllocation no_gc;
- String::FlatContent flat = gap->GetFlatContent();
- gap_ = NewArray<uc16>(gap_length + 1);
- if (flat.IsOneByte()) {
- CopyChars(gap_, flat.ToOneByteVector().start(), gap_length);
- } else {
- CopyChars(gap_, flat.ToUC16Vector().start(), gap_length);
- }
- gap_[gap_length] = '\0';
- } else {
- gap_ = nullptr;
- }
}
-MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) {
+MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object,
+ Handle<Object> gap) {
+ if (!gap->IsUndefined() && !InitializeGap(gap)) return MaybeHandle<Object>();
Result result = SerializeObject(object);
if (result == UNCHANGED) return factory()->undefined_value();
if (result == SUCCESS) return builder_.Finish();
@@ -111,6 +97,46 @@ MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) {
return MaybeHandle<Object>();
}
+bool BasicJsonStringifier::InitializeGap(Handle<Object> gap) {
+ DCHECK_NULL(gap_);
+ HandleScope scope(isolate_);
+ if (gap->IsJSReceiver()) {
+ Handle<String> class_name(Handle<JSReceiver>::cast(gap)->class_name());
+ if (class_name.is_identical_to(factory()->String_string())) {
Camillo Bruni 2016/05/23 14:08:25 argh :D we should have a IsNumberLike() somewhere
Yang 2016/05/23 18:19:07 Actually, the string case and the number case are
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap,
+ Object::ToString(isolate_, gap), false);
+ } else if (class_name.is_identical_to(factory()->number_string())) {
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap, Object::ToNumber(gap),
+ false);
+ }
+ }
+
+ if (gap->IsString()) {
+ Handle<String> gap_string = Handle<String>::cast(gap);
+ if (gap_string->length() > 0) {
+ int gap_length = std::min(gap_string->length(), 10);
+ gap_ = NewArray<uc16>(gap_length + 1);
+ String::WriteToFlat(*gap_string, gap_, 0, gap_length);
+ for (int i = 0; i < gap_length; i++) {
+ if (gap_[i] > String::kMaxOneByteCharCode) {
+ builder_.ChangeEncoding();
+ break;
+ }
+ }
+ gap_[gap_length] = '\0';
+ }
+ } else if (gap->IsNumber()) {
+ int num_value = DoubleToInt32(gap->Number());
+ if (num_value > 0) {
+ int gap_length = std::min(num_value, 10);
Camillo Bruni 2016/05/23 14:08:25 just read the spec, wut? :D
Yang 2016/05/23 18:19:07 Yeah. Magic numbers ftw.
+ gap_ = NewArray<uc16>(gap_length + 1);
+ for (int i = 0; i < gap_length; i++) gap_[i] = ' ';
+ gap_[gap_length] = '\0';
+ }
+ }
+ return true;
+}
+
MaybeHandle<Object> BasicJsonStringifier::StringifyString(
Isolate* isolate, Handle<String> object) {
static const int kJsonQuoteWorstCaseBlowup = 6;
@@ -119,9 +145,8 @@ MaybeHandle<Object> BasicJsonStringifier::StringifyString(
object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
if (worst_case_length > 32 * KB) { // Slow path if too large.
- BasicJsonStringifier stringifier(isolate,
- isolate->factory()->empty_string());
- return stringifier.Stringify(object);
+ BasicJsonStringifier stringifier(isolate);
+ return stringifier.Stringify(object, isolate->factory()->undefined_value());
}
object = String::Flatten(object);
« no previous file with comments | « src/json-stringifier.h ('k') | src/runtime/runtime-json.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698