Skip to content

Commit 3e74b28

Browse files
committed
Fix Typedarray.slice fastpath when the content type is matching
This patch fixes #4888. The implementation is based on PR #4898, only resolved the conflicts and applied requested changes. Co-authored-by: Robert Fancsik [email protected] JerryScript-DCO-1.0-Signed-off-by: Gergo Csizi [email protected]
1 parent 59649fc commit 3e74b28

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed

jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,14 +1711,35 @@ ecma_builtin_typedarray_prototype_slice (ecma_value_t this_arg, /**< this argume
17111711

17121712
uint8_t *dst_buffer_p = ecma_typedarray_get_buffer (&new_typedarray_info);
17131713

1714-
JERRY_ASSERT (new_typedarray_info.offset == 0);
1715-
17161714
src_buffer_p += relative_start << info_p->shift;
17171715

17181716
if (info_p->id == new_typedarray_info.id)
17191717
{
17201718
// 22.2.3.23. Step 22. h-i.
1721-
memcpy (dst_buffer_p, src_buffer_p, count << info_p->shift);
1719+
1720+
if (JERRY_LIKELY (new_typedarray_info.offset == 0))
1721+
{
1722+
if (info_p->array_buffer_p == new_typedarray_info.array_buffer_p)
1723+
{
1724+
return new_typedarray;
1725+
}
1726+
1727+
memcpy (dst_buffer_p, src_buffer_p, count << info_p->shift);
1728+
}
1729+
else
1730+
{
1731+
uint32_t byte_shift = (uint32_t) (1 << info_p->shift);
1732+
1733+
while (count)
1734+
{
1735+
memmove (dst_buffer_p, src_buffer_p, byte_shift);
1736+
1737+
dst_buffer_p += byte_shift;
1738+
src_buffer_p += byte_shift;
1739+
1740+
count--;
1741+
}
1742+
}
17221743
}
17231744
else
17241745
{

tests/jerry/array-slice.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
let buf = new ArrayBuffer(10);
16+
let a1 = new Int8Array(buf, 0, 5);
17+
a1.fill(1);
18+
a1.constructor = {
19+
[Symbol.species]: function (len) {
20+
return new Int8Array(buf, 5, 5);
21+
}
22+
};
23+
let a2 = a1.slice(2,4);
24+
res = new Int8Array(buf, 0, 10);
25+
26+
//Expected: 1, 1, 1, 1, 1, 1, 1, 0, 0, 0
27+
for (let i = 0; i < 10; i++) {
28+
if (i < 7) {
29+
assert(res[i] === 1);
30+
} else {
31+
assert(res[i] === 0);
32+
}
33+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
var ab = new Int8Array(20).map((v, i) => i + 1).buffer;
16+
var ta = new Int8Array(ab, 0, 10);
17+
ta.constructor = {
18+
[Symbol.species]: function (len) {
19+
return new Int8Array(ab, 1, len);
20+
}
21+
};
22+
23+
var tb = ta.slice();
24+
25+
for (let e of ta) {
26+
assert(e === 1);
27+
}
28+
29+
for (let e of tb) {
30+
assert(e === 1);
31+
}

0 commit comments

Comments
 (0)