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:
parent
4ae6b581b0
commit
902d21dd66
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user