Bug 1874683 - Part 10: Inline String.prototype.at in CacheIR. r=jandem
[gecko.git] / js / src / jit-test / tests / cacheir / string-at-oob.js
blobb7e71db87f24ab1e638c14b4ef7929d30e0336d6
1 // Test String.prototype.at with out-of-bounds indices.
3 function* characters(...ranges) {
4   for (let [start, end] of ranges) {
5     for (let i = start; i <= end; ++i) {
6       yield i;
7     }
8   }
11 const empty = [];
13 const ascii = [...characters(
14   [0x41, 0x5A], // A..Z
15   [0x61, 0x7A], // a..z
16 )];
18 const latin1 = [...characters(
19   [0xC0, 0xFF], // À..ÿ
20 )];
22 const twoByte = [...characters(
23   [0x100, 0x17E], // Ā..ž
24 )];
26 function atomize(s) {
27   return Object.keys({[s]: 0})[0];
30 function codePoints() {
31   return [empty, ascii, latin1, twoByte];
34 function toRope(s) {
35   // Ropes have at least two characters.
36   if (s.length < 2) {
37     return s;
38   }
39   if (s.length === 2) {
40     return newRope(s[0], s[1]);
41   }
42   return newRope(s[0], s.substring(1));
45 function makeStrings() {
46   let strings = codePoints()
47   .map(codePoints => String.fromCodePoint(...codePoints))
48   .flatMap(x => [
49     x,
50     toRope(x),
51     newString(x, {twoByte: true}),
52     atomize(x),
53   ]);
54   return strings;
57 function testNegativeIndexConstant() {
58   let strings = makeStrings();
59   for (let i = 0; i < 200; ++i) {
60     let str = strings[i % strings.length];
61     let ch = str.at(-1000);
62     assertEq(ch, undefined);
63   }
65 for (let i = 0; i < 2; ++i) {
66   testNegativeIndexConstant();
69 function testNegativeIndexVariable() {
70   let indices = [-1000, -2000];
71   let strings = makeStrings();
72   for (let i = 0; i < 200; ++i) {
73     let str = strings[i % strings.length];
74     let ch = str.at(indices[i & 1]);
75     assertEq(ch, undefined);
76   }
78 for (let i = 0; i < 2; ++i) {
79   testNegativeIndexVariable();
82 function testNegativeOrValidIndex() {
83   let indices = [-1000, 0];
84   let strings = makeStrings();
86   // Number of string kinds created in makeStrings.
87   const N = 4;
89   let cpoints = codePoints();
90   assertEq(strings.length, cpoints.length * N);
92   for (let i = 0; i < 200; ++i) {
93     let str = strings[i % strings.length];
94     let index = indices[i & 1];
95     let ch = str.at(index);
97     let cp = cpoints[Math.trunc((i % strings.length) / N)];
98     assertEq(ch, (0 <= index && index < cp.length ? String.fromCodePoint(cp[index]) : undefined));
99   }
101 for (let i = 0; i < 2; ++i) {
102   testNegativeOrValidIndex();
105 function testTooLargeIndexConstant() {
106   let strings = makeStrings();
107   for (let i = 0; i < 200; ++i) {
108     let str = strings[i % strings.length];
109     let ch = str.at(1000);
110     assertEq(ch, undefined);
111   }
113 for (let i = 0; i < 2; ++i) {
114   testTooLargeIndexConstant();
117 function testTooLargeIndexVariable() {
118   let indices = [1000, 2000];
119   let strings = makeStrings();
120   for (let i = 0; i < 200; ++i) {
121     let str = strings[i % strings.length];
122     let ch = str.at(indices[i & 1]);
123     assertEq(ch, undefined);
124   }
126 for (let i = 0; i < 2; ++i) {
127   testTooLargeIndexVariable();
130 function testTooLargeOrValidIndex() {
131   let indices = [1000, 0];
132   let strings = makeStrings();
134   // Number of string kinds created in makeStrings.
135   const N = 4;
137   let cpoints = codePoints();
138   assertEq(strings.length, cpoints.length * N);
140   for (let i = 0; i < 200; ++i) {
141     let str = strings[i % strings.length];
142     let index = indices[i & 1];
143     let ch = str.at(index);
145     let cp = cpoints[Math.trunc((i % strings.length) / N)];
146     assertEq(ch, (0 <= index && index < cp.length ? String.fromCodePoint(cp[index]) : undefined));
147   }
149 for (let i = 0; i < 2; ++i) {
150   testTooLargeOrValidIndex();