Fix StringToList to set right length of the new array.

Previously StringToList use the length of the original string, which is
not the right value: we expect the length of the new array to be the
number of characters (codepoints).

Bug: v8:7980
Change-Id: I2efca5715323c4399cb45c53871ae349207f3458
Reviewed-on: https://chromium-review.googlesource.com/c/1297320
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56944}
This commit is contained in:
Hai Dang 2018-10-24 14:12:42 +02:00 committed by Commit Bot
parent 4ae6b581b0
commit 902d21dd66
3 changed files with 33 additions and 17 deletions

View File

@ -2531,9 +2531,9 @@ TNode<JSArray> StringBuiltinsAssembler::StringToList(TNode<Context> context,
const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag;
TNode<IntPtrT> first_to_element_offset =
ElementOffsetFromIndex(IntPtrConstant(0), kind, INTPTR_PARAMETERS, 0);
VARIABLE(
var_offset, MachineType::PointerRepresentation(),
IntPtrAdd(first_to_element_offset, IntPtrConstant(first_element_offset)));
TNode<IntPtrT> first_offset =
IntPtrAdd(first_to_element_offset, IntPtrConstant(first_element_offset));
TVARIABLE(IntPtrT, var_offset, first_offset);
TVARIABLE(IntPtrT, var_position, IntPtrConstant(0));
Label done(this), next_codepoint(this, {&var_position, &var_offset});
@ -2554,12 +2554,19 @@ TNode<JSArray> StringBuiltinsAssembler::StringToList(TNode<Context> context,
TNode<IntPtrT> ch_length = LoadStringLengthAsWord(value);
var_position = IntPtrAdd(var_position.value(), ch_length);
// Increment the array offset and continue the loop.
var_offset.Bind(
IntPtrAdd(var_offset.value(), IntPtrConstant(kPointerSize)));
var_offset = IntPtrAdd(var_offset.value(), IntPtrConstant(kPointerSize));
Goto(&next_codepoint);
}
BIND(&done);
TNode<IntPtrT> new_length =
IntPtrDiv(IntPtrSub(var_offset.value(), first_offset),
IntPtrConstant(kPointerSize));
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(new_length, IntPtrConstant(0)));
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(length, new_length));
StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset,
SmiTag(new_length));
return UncheckedCast<JSArray>(array);
}

View File

@ -21,8 +21,8 @@ function Spread_OneByteShort() {
function Spread_OneByteShortTearDown() {
var expected = "A|l|p|h|a|b|e|t|-|S|o|u|p";
return assert(Array.isArray(result))
&& assertEquals(expected, result.join("|"));
assert(Array.isArray(result));
assertEquals(expected, result.join("|"));
}
// ----------------------------------------------------------------------------
@ -44,8 +44,8 @@ function Spread_TwoByteShort() {
function Spread_TwoByteShortTearDown() {
var expected = "\u5FCD|\u8005|\u306E|\u653B|\u6483";
return assert(Array.isArray(result))
&& assertEquals(expected, result.join("|"));
assert(Array.isArray(result));
assertEquals(expected, result.join("|"));
}
// ----------------------------------------------------------------------------
@ -69,8 +69,8 @@ function Spread_WithSurrogatePairsShort() {
function Spread_WithSurrogatePairsShortTearDown() {
var expected =
"\uD83C\uDF1F|\u5FCD|\u8005|\u306E|\u653B|\u6483|\uD83C\uDF1F";
return assert(Array.isArray(result))
&& assertEquals(expected, result.join("|"));
assert(Array.isArray(result));
assertEquals(expected, result.join("|"));
}
// ----------------------------------------------------------------------------
@ -92,7 +92,7 @@ function ForOf_OneByteShort() {
}
function ForOf_OneByteShortTearDown() {
return assertEquals(string, result);
assertEquals(string, result);
}
// ----------------------------------------------------------------------------
@ -114,7 +114,7 @@ function ForOf_TwoByteShort() {
}
function ForOf_TwoByteShortTearDown() {
return assertEquals(string, result);
assertEquals(string, result);
}
// ----------------------------------------------------------------------------
@ -137,7 +137,7 @@ function ForOf_WithSurrogatePairsShort() {
}
function ForOf_WithSurrogatePairsShortTearDown() {
return assertEquals(string, result);
assertEquals(string, result);
}
// ----------------------------------------------------------------------------
@ -159,7 +159,7 @@ function ForOf_OneByteLong() {
}
function ForOf_OneByteLongTearDown() {
return assertEquals(string, result);
assertEquals(string, result);
}
// ----------------------------------------------------------------------------
@ -181,7 +181,7 @@ function ForOf_TwoByteLong() {
}
function ForOf_TwoByteLongTearDown() {
return assertEquals(string, result);
assertEquals(string, result);
}
// ----------------------------------------------------------------------------
@ -204,5 +204,5 @@ function ForOf_WithSurrogatePairsLong() {
}
function ForOf_WithSurrogatePairsLongTearDown() {
return assertEquals(string, result);
assertEquals(string, result);
}

View File

@ -100,3 +100,12 @@ function TestSlicedStringRegression() {
var iterator = sliced_string[Symbol.iterator]();
}
TestSlicedStringRegression();
(function(){
var str = "\uD83C\uDF1F\u5FCD\u8005\u306E\u653B\u6483\uD83C\uDF1F";
var arr = [...str];
assertEquals(["\uD83C\uDF1F", "\u5FCD", "\u8005", "\u306E", "\u653B",
"\u6483", "\uD83C\uDF1F"], arr);
assertEquals(7, arr.length);
})();