Skip to content

Commit 26717f7

Browse files
gibson042ptomato
authored andcommitted
[immutable-arraybuffer] TypedArray static functions
1 parent f0cb0de commit 26717f7

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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%.from
6+
description: >
7+
Throws a TypeError if species constructor returns an immutable ArrayBuffer.
8+
info: |
9+
%TypedArray%.from ( source [ , mapper [ , thisArg ] ] )
10+
1. Let C be the this value.
11+
2. If IsConstructor(C) is false, throw a TypeError exception.
12+
3. If mapper is undefined, then
13+
a. Let mapping be false.
14+
4. Else,
15+
a. If IsCallable(mapper) is false, throw a TypeError exception.
16+
b. Let mapping be true.
17+
5. Let usingIterator be ? GetMethod(source, %Symbol.iterator%).
18+
6. If usingIterator is not undefined, then
19+
a. Let values be ? IteratorToList(? GetIteratorFromMethod(source, usingIterator)).
20+
b. Let len be the number of elements in values.
21+
c. Let targetObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) », write).
22+
d. Let k be 0.
23+
e. Repeat, while k < len,
24+
i. Let Pk be ! ToString(𝔽(k)).
25+
ii. Let kValue be the first element of values.
26+
iii. Remove the first element from values.
27+
iv. If mapping is true, then
28+
1. Let mappedValue be ? Call(mapper, thisArg, « kValue, 𝔽(k) »).
29+
v. Else,
30+
1. Let mappedValue be kValue.
31+
vi. Perform ? Set(targetObj, Pk, mappedValue, true).
32+
vii. Set k to k + 1.
33+
f. Assert: values is now an empty List.
34+
g. Return targetObj.
35+
7. NOTE: source is not an iterable object, so assume it is already an array-like object.
36+
8. Let arrayLike be ! ToObject(source).
37+
9. Let len be ? LengthOfArrayLike(arrayLike).
38+
10. Let targetObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) », write).
39+
11. Let k be 0.
40+
12. Repeat, while k < len,
41+
a. Let Pk be ! ToString(𝔽(k)).
42+
b. Let kValue be ? Get(arrayLike, Pk).
43+
c. If mapping is true, then
44+
i. Let mappedValue be ? Call(mapper, thisArg, « kValue, 𝔽(k) »).
45+
features: [Symbol.iterator, TypedArray, immutable-arraybuffer]
46+
includes: [testTypedArray.js, compareArray.js]
47+
---*/
48+
49+
testWithAllTypedArrayConstructors((TA, makeCtorArg) => {
50+
var calls = [];
51+
var expectCalls = [];
52+
53+
var custom = new TA(makeCtorArg(2));
54+
var ctor = function(len) {
55+
calls.push("construct(" + len + ")");
56+
return custom;
57+
};
58+
var mapper = function(value, index) {
59+
calls.push("map index " + index);
60+
return value + value;
61+
};
62+
63+
// arraylike source
64+
calls = [];
65+
var srcArraylike = {
66+
get length() {
67+
calls.push("get source.length");
68+
return 1;
69+
},
70+
get 0() {
71+
calls.push("get source[0]");
72+
return "8";
73+
}
74+
};
75+
Object.defineProperty(srcArraylike, Symbol.iterator, {
76+
get: function() {
77+
calls.push("get source[Symbol.iterator]");
78+
return undefined;
79+
}
80+
});
81+
assert.throws(TypeError, function() {
82+
TA.from.call(ctor, srcArraylike, mapper);
83+
}, "arraylike source");
84+
expectCalls = [
85+
"get source[Symbol.iterator]",
86+
"get source.length",
87+
"construct(1)"
88+
];
89+
assert.compareArray(calls, expectCalls,
90+
"Must construct the result before visiting arraylike source elements.");
91+
92+
// iterable source
93+
calls = [];
94+
var srcIterable = Object.defineProperty({}, Symbol.iterator, {
95+
get: function() {
96+
calls.push("get source[Symbol.iterator]");
97+
function getIterator() {
98+
calls.push("call source[Symbol.iterator]");
99+
var itor = {
100+
get next() {
101+
calls.push("get source iterator.next");
102+
var iterationResults = [
103+
{ done: false, value: "4", msg: "yield 4" },
104+
{ done: true, value: "8", msg: "done" },
105+
{ done: true, value: "9", msg: "unexpected" }
106+
];
107+
function next() {
108+
var result = iterationResults.shift();
109+
calls.push("source iterator " + result.msg);
110+
var resultSpy = {
111+
get done() {
112+
calls.push("get iterationResult.done " + result.done);
113+
return result.done;
114+
},
115+
get value() {
116+
calls.push("get iterationResult.value " + result.value);
117+
return result.value;
118+
}
119+
};
120+
return resultSpy;
121+
};
122+
return next;
123+
}
124+
};
125+
return itor;
126+
}
127+
return getIterator;
128+
}
129+
});
130+
assert.throws(TypeError, function() {
131+
TA.from.call(ctor, srcIterable, mapper);
132+
}, "iterable source");
133+
expectCalls = [
134+
"get source[Symbol.iterator]",
135+
"call source[Symbol.iterator]",
136+
"get source iterator.next",
137+
"source iterator yield 4",
138+
"get iterationResult.done false",
139+
"get iterationResult.value 4",
140+
"source iterator done",
141+
"get iterationResult.done true",
142+
"construct(1)"
143+
];
144+
assert.compareArray(calls, expectCalls,
145+
"Must construct the result before visiting iterable source elements.");
146+
}, null, ["immutable"]);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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%.of
6+
description: >
7+
Throws a TypeError if species constructor returns an immutable ArrayBuffer.
8+
info: |
9+
%TypedArray%.of ( ...items )
10+
1. Let len be the number of elements in items.
11+
2. Let C be the this value.
12+
3. If IsConstructor(C) is false, throw a TypeError exception.
13+
4. Let newObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) », write).
14+
5. Let k be 0.
15+
6. Repeat, while k < len,
16+
a. Let kValue be items[k].
17+
b. Let Pk be ! ToString(𝔽(k)).
18+
c. Perform ? Set(newObj, Pk, kValue, true).
19+
d. Set k to k + 1.
20+
features: [Symbol.iterator, TypedArray, immutable-arraybuffer]
21+
includes: [testTypedArray.js, compareArray.js]
22+
---*/
23+
24+
testWithAllTypedArrayConstructors((TA, makeCtorArg) => {
25+
var calls = [];
26+
27+
var custom = new TA(makeCtorArg(2));
28+
var ctor = function(len) {
29+
calls.push("construct(" + len + ")");
30+
return custom;
31+
};
32+
33+
var a = {
34+
valueOf() {
35+
calls.push("a.valueOf");
36+
return "1";
37+
}
38+
};
39+
var b = {
40+
valueOf() {
41+
calls.push("b.valueOf");
42+
return "2";
43+
}
44+
};
45+
assert.throws(TypeError, function() {
46+
TA.of.call(ctor, a, b);
47+
}, "iterable source");
48+
assert.compareArray(calls, ["construct(2)"]);
49+
}, null, ["immutable"]);

0 commit comments

Comments
 (0)