summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/ion/fromcharcode-charcodeat-zero.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/ion/fromcharcode-charcodeat-zero.js')
-rw-r--r--js/src/jit-test/tests/ion/fromcharcode-charcodeat-zero.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/ion/fromcharcode-charcodeat-zero.js b/js/src/jit-test/tests/ion/fromcharcode-charcodeat-zero.js
new file mode 100644
index 0000000000..b8a5cb6b56
--- /dev/null
+++ b/js/src/jit-test/tests/ion/fromcharcode-charcodeat-zero.js
@@ -0,0 +1,82 @@
+function toCharCodes(str) {
+ return [...str].map(s => s.length === 1 ? [s.charCodeAt(0)] : [s.charCodeAt(0), s.charCodeAt(1)])
+ .flat();
+}
+
+function test() {
+ // [Ascii; Latin-1, non-Ascii; non-Latin-1; non-BMP]
+ const constant = "Aaรรกฤ€ฤ๐€๐š";
+ const charCodes = toCharCodes(constant);
+
+ // Create a linear, but non-constant string with the same contents.
+ const linear = String.fromCharCode(...charCodes);
+ assertEq(linear, constant);
+
+ // Optimisation applies for |MCharCodeAt(MFromCharCode(MCharCodeAt(str, idx)), 0|.
+ for (let i = 0; i < 500; ++i) {
+ let idx = i & 3;
+
+ // str[idx] is compiled to |MFromCharCode(MCharCodeAt(str, idx))|.
+ assertEq(constant[idx].charCodeAt(0), charCodes[idx]);
+ assertEq(linear[idx].charCodeAt(0), charCodes[idx]);
+
+ // str.charAt(idx) is compiled to |MFromCharCode(MCharCodeAt(str, idx))|.
+ assertEq(constant.charAt(idx).charCodeAt(0), charCodes[idx]);
+ assertEq(linear.charAt(idx).charCodeAt(0), charCodes[idx]);
+ }
+}
+for (let i = 0; i < 4; ++i) {
+ test();
+}
+
+function testNonConstantIndex() {
+ // [Ascii; Latin-1, non-Ascii; non-Latin-1; non-BMP]
+ const constant = "Aaรรกฤ€ฤ๐€๐š";
+ const charCodes = toCharCodes(constant);
+
+ // Create a linear, but non-constant string with the same contents.
+ const linear = String.fromCharCode(...charCodes);
+ assertEq(linear, constant);
+
+ // No optimisation when the index isn't a constant zero.
+ let indices = [0, 1, 2, 3];
+ for (let i = 0; i < 500; ++i) {
+ let idx = i & 3;
+
+ // Always zero, but too complicated to infer at compile time.
+ let zero = indices[idx] - idx;
+
+ assertEq(constant[idx].charCodeAt(zero), charCodes[idx]);
+ assertEq(linear[idx].charCodeAt(zero), charCodes[idx]);
+
+ assertEq(constant.charAt(idx).charCodeAt(zero), charCodes[idx]);
+ assertEq(linear.charAt(idx).charCodeAt(zero), charCodes[idx]);
+ }
+}
+for (let i = 0; i < 4; ++i) {
+ testNonConstantIndex();
+}
+
+function testOOB() {
+ // [Ascii; Latin-1, non-Ascii; non-Latin-1; non-BMP]
+ const constant = "Aaรรกฤ€ฤ๐€๐š";
+ const charCodes = toCharCodes(constant);
+
+ // Create a linear, but non-constant string with the same contents.
+ const linear = String.fromCharCode(...charCodes);
+ assertEq(linear, constant);
+
+ // No optimisation when the index is out-of-bounds.
+ for (let i = 0; i < 500; ++i) {
+ let idx = i & 3;
+
+ assertEq(constant[idx].charCodeAt(1), NaN);
+ assertEq(linear[idx].charCodeAt(1), NaN);
+
+ assertEq(constant.charAt(idx).charCodeAt(1), NaN);
+ assertEq(linear.charAt(idx).charCodeAt(1), NaN);
+ }
+}
+for (let i = 0; i < 4; ++i) {
+ testOOB();
+}