Commit 902d21dd authored by Hai Dang's avatar Hai Dang Committed by Commit Bot

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: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56944}
parent 4ae6b581
...@@ -2531,9 +2531,9 @@ TNode<JSArray> StringBuiltinsAssembler::StringToList(TNode<Context> context, ...@@ -2531,9 +2531,9 @@ TNode<JSArray> StringBuiltinsAssembler::StringToList(TNode<Context> context,
const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag;
TNode<IntPtrT> first_to_element_offset = TNode<IntPtrT> first_to_element_offset =
ElementOffsetFromIndex(IntPtrConstant(0), kind, INTPTR_PARAMETERS, 0); ElementOffsetFromIndex(IntPtrConstant(0), kind, INTPTR_PARAMETERS, 0);
VARIABLE( TNode<IntPtrT> first_offset =
var_offset, MachineType::PointerRepresentation(), IntPtrAdd(first_to_element_offset, IntPtrConstant(first_element_offset));
IntPtrAdd(first_to_element_offset, IntPtrConstant(first_element_offset))); TVARIABLE(IntPtrT, var_offset, first_offset);
TVARIABLE(IntPtrT, var_position, IntPtrConstant(0)); TVARIABLE(IntPtrT, var_position, IntPtrConstant(0));
Label done(this), next_codepoint(this, {&var_position, &var_offset}); Label done(this), next_codepoint(this, {&var_position, &var_offset});
...@@ -2554,12 +2554,19 @@ TNode<JSArray> StringBuiltinsAssembler::StringToList(TNode<Context> context, ...@@ -2554,12 +2554,19 @@ TNode<JSArray> StringBuiltinsAssembler::StringToList(TNode<Context> context,
TNode<IntPtrT> ch_length = LoadStringLengthAsWord(value); TNode<IntPtrT> ch_length = LoadStringLengthAsWord(value);
var_position = IntPtrAdd(var_position.value(), ch_length); var_position = IntPtrAdd(var_position.value(), ch_length);
// Increment the array offset and continue the loop. // Increment the array offset and continue the loop.
var_offset.Bind( var_offset = IntPtrAdd(var_offset.value(), IntPtrConstant(kPointerSize));
IntPtrAdd(var_offset.value(), IntPtrConstant(kPointerSize)));
Goto(&next_codepoint); Goto(&next_codepoint);
} }
BIND(&done); 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); return UncheckedCast<JSArray>(array);
} }
......
...@@ -21,8 +21,8 @@ function Spread_OneByteShort() { ...@@ -21,8 +21,8 @@ function Spread_OneByteShort() {
function Spread_OneByteShortTearDown() { function Spread_OneByteShortTearDown() {
var expected = "A|l|p|h|a|b|e|t|-|S|o|u|p"; var expected = "A|l|p|h|a|b|e|t|-|S|o|u|p";
return assert(Array.isArray(result)) assert(Array.isArray(result));
&& assertEquals(expected, result.join("|")); assertEquals(expected, result.join("|"));
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -44,8 +44,8 @@ function Spread_TwoByteShort() { ...@@ -44,8 +44,8 @@ function Spread_TwoByteShort() {
function Spread_TwoByteShortTearDown() { function Spread_TwoByteShortTearDown() {
var expected = "\u5FCD|\u8005|\u306E|\u653B|\u6483"; var expected = "\u5FCD|\u8005|\u306E|\u653B|\u6483";
return assert(Array.isArray(result)) assert(Array.isArray(result));
&& assertEquals(expected, result.join("|")); assertEquals(expected, result.join("|"));
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -69,8 +69,8 @@ function Spread_WithSurrogatePairsShort() { ...@@ -69,8 +69,8 @@ function Spread_WithSurrogatePairsShort() {
function Spread_WithSurrogatePairsShortTearDown() { function Spread_WithSurrogatePairsShortTearDown() {
var expected = var expected =
"\uD83C\uDF1F|\u5FCD|\u8005|\u306E|\u653B|\u6483|\uD83C\uDF1F"; "\uD83C\uDF1F|\u5FCD|\u8005|\u306E|\u653B|\u6483|\uD83C\uDF1F";
return assert(Array.isArray(result)) assert(Array.isArray(result));
&& assertEquals(expected, result.join("|")); assertEquals(expected, result.join("|"));
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -92,7 +92,7 @@ function ForOf_OneByteShort() { ...@@ -92,7 +92,7 @@ function ForOf_OneByteShort() {
} }
function ForOf_OneByteShortTearDown() { function ForOf_OneByteShortTearDown() {
return assertEquals(string, result); assertEquals(string, result);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -114,7 +114,7 @@ function ForOf_TwoByteShort() { ...@@ -114,7 +114,7 @@ function ForOf_TwoByteShort() {
} }
function ForOf_TwoByteShortTearDown() { function ForOf_TwoByteShortTearDown() {
return assertEquals(string, result); assertEquals(string, result);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -137,7 +137,7 @@ function ForOf_WithSurrogatePairsShort() { ...@@ -137,7 +137,7 @@ function ForOf_WithSurrogatePairsShort() {
} }
function ForOf_WithSurrogatePairsShortTearDown() { function ForOf_WithSurrogatePairsShortTearDown() {
return assertEquals(string, result); assertEquals(string, result);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -159,7 +159,7 @@ function ForOf_OneByteLong() { ...@@ -159,7 +159,7 @@ function ForOf_OneByteLong() {
} }
function ForOf_OneByteLongTearDown() { function ForOf_OneByteLongTearDown() {
return assertEquals(string, result); assertEquals(string, result);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -181,7 +181,7 @@ function ForOf_TwoByteLong() { ...@@ -181,7 +181,7 @@ function ForOf_TwoByteLong() {
} }
function ForOf_TwoByteLongTearDown() { function ForOf_TwoByteLongTearDown() {
return assertEquals(string, result); assertEquals(string, result);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
...@@ -204,5 +204,5 @@ function ForOf_WithSurrogatePairsLong() { ...@@ -204,5 +204,5 @@ function ForOf_WithSurrogatePairsLong() {
} }
function ForOf_WithSurrogatePairsLongTearDown() { function ForOf_WithSurrogatePairsLongTearDown() {
return assertEquals(string, result); assertEquals(string, result);
} }
...@@ -100,3 +100,12 @@ function TestSlicedStringRegression() { ...@@ -100,3 +100,12 @@ function TestSlicedStringRegression() {
var iterator = sliced_string[Symbol.iterator](); var iterator = sliced_string[Symbol.iterator]();
} }
TestSlicedStringRegression(); 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);
})();
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