Skip to content

Commit 9a063fd

Browse files
bnoordhuisrvagg
authored andcommitted
deps: backport a7e50a5 from upstream v8
PR-URL: nodejs-private/node-private#8 Reviewed-By: Fedor Indutny <fedor@indutny.com>
1 parent 0723320 commit 9a063fd

File tree

2 files changed

+106
-5
lines changed

2 files changed

+106
-5
lines changed

deps/v8/src/json-stringifier.h

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ class BasicJsonStringifier BASE_EMBEDDED {
8383
INLINE(Result SerializeJSArray(Handle<JSArray> object));
8484
INLINE(Result SerializeJSObject(Handle<JSObject> object));
8585

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

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

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

450502

451503
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow(
452-
Handle<JSArray> object, uint32_t length) {
453-
for (uint32_t i = 0; i < length; i++) {
504+
Handle<JSArray> object, uint32_t start, uint32_t length) {
505+
for (uint32_t i = start; i < length; i++) {
454506
if (i > 0) builder_.AppendCharacter(',');
455507
Handle<Object> element;
456508
ASSIGN_RETURN_ON_EXCEPTION_VALUE(

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

Lines changed: 49 additions & 0 deletions
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)