Skip to content

Commit 97ab546

Browse files
committed
TA.slice Symbol.species returning an instance backed by an immutable buffer
1 parent 91a9452 commit 97ab546

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright (C) 2025 Richard Gibson. All rights reserved.
2+
// This code is governed by the BSD license found in the LICENSE file.
3+
4+
/*---
5+
esid: sec-%typedarray%.prototype.slice
6+
description: >
7+
Throws a TypeError exception when the receiver constructs an instance backed
8+
by an immutable buffer
9+
info: |
10+
%TypedArray%.prototype.slice ( start, end )
11+
1. Let O be the this value.
12+
2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
13+
3. Let srcArrayLength be TypedArrayLength(taRecord).
14+
4. Let relativeStart be ? ToIntegerOrInfinity(start).
15+
5. If relativeStart = -∞, let startIndex be 0.
16+
6. Else if relativeStart < 0, let startIndex be max(srcArrayLength + relativeStart, 0).
17+
7. Else, let startIndex be min(relativeStart, srcArrayLength).
18+
8. If end is undefined, let relativeEnd be srcArrayLength; else let relativeEnd be ? ToIntegerOrInfinity(end).
19+
9. If relativeEnd = -∞, let endIndex be 0.
20+
10. Else if relativeEnd < 0, let endIndex be max(srcArrayLength + relativeEnd, 0).
21+
11. Else, let endIndex be min(relativeEnd, srcArrayLength).
22+
12. Let countBytes be max(endIndex - startIndex, 0).
23+
13. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(countBytes) », ~write~).
24+
14. Assert: IsImmutableBuffer(A.[[ViewedArrayBuffer]]) is false.
25+
26+
TypedArraySpeciesCreate ( exemplar, argumentList [ , accessMode ] )
27+
1. If accessMode is not present, set accessMode to ~read~.
28+
2. Let defaultConstructor be the intrinsic object associated with the constructor name exemplar.[[TypedArrayName]] in Table 73.
29+
3. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
30+
4. Let result be ? TypedArrayCreateFromConstructor(constructor, argumentList, accessMode).
31+
32+
TypedArrayCreateFromConstructor ( constructor, argumentList [ , accessMode ] )
33+
1. If accessMode is not present, set accessMode to ~read~.
34+
2. Let newTypedArray be ? Construct(constructor, argumentList).
35+
3. Let taRecord be ? ValidateTypedArray(newTypedArray, seq-cst, accessMode).
36+
37+
ValidateTypedArray ( O, order [ , accessMode ] )
38+
1. If accessMode is not present, set accessMode to read.
39+
2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
40+
3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
41+
4. If accessMode is ~write~ and IsImmutableBuffer(O.[[ViewedArrayBuffer]]) is true, throw a TypeError exception.
42+
features: [TypedArray, immutable-arraybuffer]
43+
includes: [testTypedArray.js, compareArray.js]
44+
---*/
45+
46+
testWithAllTypedArrayConstructors((TA, makeCtorArg) => {
47+
var calls = [];
48+
49+
var ta = new TA(makeCtorArg(["1", "2"]));
50+
var constructor = {};
51+
Object.defineProperty(ta, "constructor", {
52+
get: function() {
53+
calls.push("get ta.constructor");
54+
return constructor;
55+
}
56+
});
57+
Object.defineProperty(constructor, Symbol.species, {
58+
get: function() {
59+
calls.push("get ta.constructor[Symbol.species]");
60+
var iab = (new TA(["3", "4"])).buffer.transferToImmutable();
61+
var result = new TA(iab);
62+
calls.push("construct result");
63+
return result;
64+
}
65+
});
66+
67+
var start = {
68+
valueOf() {
69+
calls.push("start.valueOf");
70+
return 0;
71+
}
72+
};
73+
var end = {
74+
valueOf() {
75+
calls.push("end.valueOf");
76+
return 2;
77+
}
78+
};
79+
80+
assert.throws(TypeError, function() {
81+
ta.slice(start, end);
82+
});
83+
var expectCalls = [
84+
"start.valueOf",
85+
"end.valueOf",
86+
"get ta.constructor",
87+
"get ta.constructor[Symbol.species]",
88+
"construct result"
89+
];
90+
assert.compareArray(calls, expectCalls, "Must read arguments before constructing the result.");
91+
});

0 commit comments

Comments
 (0)