Skip to content

Commit 678398f

Browse files
bnoordhuisrvagg
authored andcommitted
deps: backport a7e50a5 from upstream v8
PR-URL: nodejs-private/node-private#6 Reviewed-By: Fedor Indutny <[email protected]>
1 parent 76a552c commit 678398f

File tree

2 files changed

+106
-5
lines changed

2 files changed

+106
-5
lines changed

deps/v8/src/json-stringifier.h

+57-5
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ class BasicJsonStringifier BASE_EMBEDDED {
8282
INLINE(Result SerializeJSArray(Handle<JSArray> object));
8383
INLINE(Result SerializeJSObject(Handle<JSObject> object));
8484

85-
Result SerializeJSArraySlow(Handle<JSArray> object, uint32_t length);
85+
Result SerializeJSArraySlow(Handle<JSArray> object, uint32_t start,
86+
uint32_t length);
8687

8788
void SerializeString(Handle<String> object);
8889

@@ -434,17 +435,68 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArray(
434435
uint32_t length = 0;
435436
CHECK(object->length()->ToArrayLength(&length));
436437
builder_.AppendCharacter('[');
437-
Result result = SerializeJSArraySlow(object, length);
438-
if (result != SUCCESS) return result;
438+
switch (object->GetElementsKind()) {
439+
case FAST_SMI_ELEMENTS: {
440+
Handle<FixedArray> elements(FixedArray::cast(object->elements()),
441+
isolate_);
442+
for (uint32_t i = 0; i < length; i++) {
443+
if (i > 0) builder_.AppendCharacter(',');
444+
SerializeSmi(Smi::cast(elements->get(i)));
445+
}
446+
break;
447+
}
448+
case FAST_DOUBLE_ELEMENTS: {
449+
// Empty array is FixedArray but not FixedDoubleArray.
450+
if (length == 0) break;
451+
Handle<FixedDoubleArray> elements(
452+
FixedDoubleArray::cast(object->elements()), isolate_);
453+
for (uint32_t i = 0; i < length; i++) {
454+
if (i > 0) builder_.AppendCharacter(',');
455+
SerializeDouble(elements->get_scalar(i));
456+
}
457+
break;
458+
}
459+
case FAST_ELEMENTS: {
460+
Handle<Object> old_length(object->length(), isolate_);
461+
for (uint32_t i = 0; i < length; i++) {
462+
if (object->length() != *old_length ||
463+
object->GetElementsKind() != FAST_ELEMENTS) {
464+
Result result = SerializeJSArraySlow(object, i, length);
465+
if (result != SUCCESS) return result;
466+
break;
467+
}
468+
if (i > 0) builder_.AppendCharacter(',');
469+
Result result = SerializeElement(
470+
isolate_,
471+
Handle<Object>(FixedArray::cast(object->elements())->get(i),
472+
isolate_),
473+
i);
474+
if (result == SUCCESS) continue;
475+
if (result == UNCHANGED) {
476+
builder_.AppendCString("null");
477+
} else {
478+
return result;
479+
}
480+
}
481+
break;
482+
}
483+
// The FAST_HOLEY_* cases could be handled in a faster way. They resemble
484+
// the non-holey cases except that a lookup is necessary for holes.
485+
default: {
486+
Result result = SerializeJSArraySlow(object, 0, length);
487+
if (result != SUCCESS) return result;
488+
break;
489+
}
490+
}
439491
builder_.AppendCharacter(']');
440492
StackPop();
441493
return SUCCESS;
442494
}
443495

444496

445497
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow(
446-
Handle<JSArray> object, uint32_t length) {
447-
for (uint32_t i = 0; i < length; i++) {
498+
Handle<JSArray> object, uint32_t start, uint32_t length) {
499+
for (uint32_t i = start; i < length; i++) {
448500
if (i > 0) builder_.AppendCharacter(',');
449501
Handle<Object> element;
450502
ASSIGN_RETURN_ON_EXCEPTION_VALUE(

deps/v8/test/mjsunit/regress/regress-crbug-554946.js

+49
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,52 @@ for (var i = 0; i < 10; i++) array[i] = i;
1010
array[0] = funky;
1111
assertEquals('["funky",null,null,null,null,null,null,null,null,null]',
1212
JSON.stringify(array));
13+
14+
array = [];
15+
funky = {
16+
get value() { array.length = 1; return "funky"; }
17+
};
18+
for (var i = 0; i < 10; i++) array[i] = i;
19+
array[3] = funky;
20+
assertEquals('[0,1,2,{"value":"funky"},null,null,null,null,null,null]',
21+
JSON.stringify(array));
22+
23+
array = [];
24+
funky = {
25+
get value() { array.pop(); return "funky"; }
26+
};
27+
for (var i = 0; i < 10; i++) array[i] = i;
28+
array[3] = funky;
29+
assertEquals('[0,1,2,{"value":"funky"},4,5,6,7,8,null]', JSON.stringify(array));
30+
31+
array = [];
32+
funky = {
33+
get value() { delete array[9]; return "funky"; }
34+
};
35+
for (var i = 0; i < 10; i++) array[i] = i;
36+
array[3] = funky;
37+
assertEquals('[0,1,2,{"value":"funky"},4,5,6,7,8,null]', JSON.stringify(array));
38+
39+
array = [];
40+
funky = {
41+
get value() { delete array[6]; return "funky"; }
42+
};
43+
for (var i = 0; i < 10; i++) array[i] = i;
44+
array[3] = funky;
45+
assertEquals('[0,1,2,{"value":"funky"},4,5,null,7,8,9]', JSON.stringify(array));
46+
47+
array = [];
48+
funky = {
49+
get value() { array[12] = 12; return "funky"; }
50+
};
51+
for (var i = 0; i < 10; i++) array[i] = i;
52+
array[3] = funky;
53+
assertEquals('[0,1,2,{"value":"funky"},4,5,6,7,8,9]', JSON.stringify(array));
54+
55+
array = [];
56+
funky = {
57+
get value() { array[10000000] = 12; return "funky"; }
58+
};
59+
for (var i = 0; i < 10; i++) array[i] = i;
60+
array[3] = funky;
61+
assertEquals('[0,1,2,{"value":"funky"},4,5,6,7,8,9]', JSON.stringify(array));

0 commit comments

Comments
 (0)