summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/prs/3994/built-ins/Uint8Array
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/test262/prs/3994/built-ins/Uint8Array')
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js25
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js22
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js26
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js67
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js62
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js30
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js24
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js44
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js25
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js22
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js28
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js14
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js31
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js24
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js23
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js44
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js32
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js27
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js156
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js72
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js33
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js42
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js46
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js20
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js67
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js26
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js17
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js29
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js34
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js42
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js24
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js20
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js32
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/shell.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js20
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js42
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js51
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js36
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js203
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/browser.js0
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js19
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js29
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js18
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js203
-rw-r--r--js/src/tests/test262/prs/3994/built-ins/Uint8Array/shell.js0
77 files changed, 2317 insertions, 0 deletions
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js
new file mode 100644
index 0000000000..c893bf952a
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/alphabet.js
@@ -0,0 +1,25 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Conversion of base64 strings to Uint8Arrays exercising the alphabet option
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+assert.compareArray(Uint8Array.fromBase64('x+/y'), [199, 239, 242]);
+assert.compareArray(Uint8Array.fromBase64('x+/y', { alphabet: 'base64' }), [199, 239, 242]);
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('x+/y', { alphabet: 'base64url' });
+});
+
+assert.compareArray(Uint8Array.fromBase64('x-_y', { alphabet: 'base64url' }), [199, 239, 242]);
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('x-_y');
+});
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('x-_y', { alphabet: 'base64' });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js
new file mode 100644
index 0000000000..a0e843cfaf
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/descriptor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: >
+ Uint8Array.fromBase64 has default data property attributes.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array, 'fromBase64', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js
new file mode 100644
index 0000000000..0847653d63
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/ignores-receiver.js
@@ -0,0 +1,22 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Uint8Array.fromBase64 ignores its receiver
+features: [uint8array-base64, TypedArray]
+---*/
+
+var fromBase64 = Uint8Array.fromBase64;
+var noReceiver = fromBase64("Zg==");
+assert.sameValue(Object.getPrototypeOf(noReceiver), Uint8Array.prototype);
+
+class Subclass extends Uint8Array {
+ constructor() {
+ throw new Test262Error("subclass constructor called");
+ }
+}
+var fromSubclass = Subclass.fromBase64("Zg==");
+assert.sameValue(Object.getPrototypeOf(fromSubclass), Uint8Array.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js
new file mode 100644
index 0000000000..6c2d6eef4a
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/illegal-characters.js
@@ -0,0 +1,26 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Uint8Array.fromBase64 throws a SyntaxError when input has non-base64, non-ascii-whitespace characters
+features: [uint8array-base64, TypedArray]
+---*/
+
+var illegal = [
+ 'Zm.9v',
+ 'Zm9v^',
+ 'Zg==&',
+ 'Z−==', // U+2212 'Minus Sign'
+ 'Z+==', // U+FF0B 'Fullwidth Plus Sign'
+ 'Zg\u00A0==', // nbsp
+ 'Zg\u2009==', // thin space
+ 'Zg\u2028==', // line separator
+];
+illegal.forEach(function(value) {
+ assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64(value)
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js
new file mode 100644
index 0000000000..c78d15e869
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/last-chunk-handling.js
@@ -0,0 +1,67 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Handling of final chunks in Uint8Array.fromBase64
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+// padding
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg=='), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'strict' }), [101, 120, 97, 102]);
+
+// no padding
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg'), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]);
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'strict' });
+});
+
+// non-zero padding bits
+assert.compareArray(Uint8Array.fromBase64('ZXhhZh=='), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97, 102]);
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'strict' });
+});
+
+// non-zero padding bits, no padding
+assert.compareArray(Uint8Array.fromBase64('ZXhhZh'), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]);
+assert.compareArray(Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]);
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'strict' });
+});
+
+// partial padding
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg=');
+});
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'loose' });
+});
+assert.compareArray(Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]);
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'strict' });
+});
+
+// excess padding
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg===');
+});
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'loose' });
+});
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'stop-before-partial' });
+});
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'strict' });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js
new file mode 100644
index 0000000000..dab9b49f61
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/length.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: >
+ Uint8Array.fromBase64.length is 1.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.fromBase64, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js
new file mode 100644
index 0000000000..2bd6716863
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/name.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: >
+ Uint8Array.fromBase64.name is "fromBase64".
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.fromBase64, 'name', {
+ value: 'fromBase64',
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js
new file mode 100644
index 0000000000..7546b12b6b
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/nonconstructor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: >
+ Uint8Array.fromBase64 is not a constructor function.
+includes: [isConstructor.js]
+features: [uint8array-base64, TypedArray, Reflect.construct]
+---*/
+
+assert(!isConstructor(Uint8Array.fromBase64), "Uint8Array.fromBase64 is not a constructor");
+
+assert.throws(TypeError, function() {
+ new Uint8Array.fromBase64('');
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js
new file mode 100644
index 0000000000..e314a8f16f
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/option-coercion.js
@@ -0,0 +1,62 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Uint8Array.fromBase64 triggers effects of the "alphabet" and "lastChunkHandling" getters, but does not perform toString on the results
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+assert.throws(TypeError, function() {
+ Uint8Array.fromBase64("Zg==", { alphabet: Object("base64") });
+});
+
+assert.throws(TypeError, function() {
+ Uint8Array.fromBase64("Zg==", { lastChunkHandling: Object("loose") });
+});
+
+
+var toStringCalls = 0;
+var throwyToString = {
+ toString: function() {
+ toStringCalls += 1;
+ throw new Test262Error("toString called");
+ }
+};
+assert.throws(TypeError, function() {
+ Uint8Array.fromBase64("Zg==", { alphabet: throwyToString });
+});
+assert.sameValue(toStringCalls, 0);
+
+assert.throws(TypeError, function() {
+ Uint8Array.fromBase64("Zg==", { lastChunkHandling: throwyToString });
+});
+assert.sameValue(toStringCalls, 0);
+
+
+var alphabetAccesses = 0;
+var base64UrlOptions = {};
+Object.defineProperty(base64UrlOptions, "alphabet", {
+ get: function() {
+ alphabetAccesses += 1;
+ return "base64url";
+ }
+});
+var arr = Uint8Array.fromBase64("x-_y", base64UrlOptions);
+assert.compareArray(arr, [199, 239, 242]);
+assert.sameValue(alphabetAccesses, 1);
+
+var lastChunkHandlingAccesses = 0;
+var strictOptions = {};
+Object.defineProperty(strictOptions, "lastChunkHandling", {
+ get: function() {
+ lastChunkHandlingAccesses += 1;
+ return "strict";
+ }
+});
+var arr = Uint8Array.fromBase64("Zg==", strictOptions);
+assert.compareArray(arr, [102]);
+assert.sameValue(lastChunkHandlingAccesses, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js
new file mode 100644
index 0000000000..9d19507f9a
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/results.js
@@ -0,0 +1,30 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Conversion of base64 strings to Uint8Arrays
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+// standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10
+var standardBase64Vectors = [
+ ["", []],
+ ["Zg==", [102]],
+ ["Zm8=", [102, 111]],
+ ["Zm9v", [102, 111, 111]],
+ ["Zm9vYg==", [102, 111, 111, 98]],
+ ["Zm9vYmE=", [102, 111, 111, 98, 97]],
+ ["Zm9vYmFy", [102, 111, 111, 98, 97, 114]],
+];
+
+standardBase64Vectors.forEach(function (pair) {
+ var arr = Uint8Array.fromBase64(pair[0]);
+ assert.sameValue(Object.getPrototypeOf(arr), Uint8Array.prototype, "decoding " + pair[0]);
+ assert.sameValue(arr.length, pair[1].length, "decoding " + pair[0]);
+ assert.sameValue(arr.buffer.byteLength, pair[1].length, "decoding " + pair[0]);
+ assert.compareArray(arr, pair[1], "decoding " + pair[0]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js
new file mode 100644
index 0000000000..57292f8a98
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/string-coercion.js
@@ -0,0 +1,44 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Uint8Array.fromBase64 throws if its argument is not a string
+features: [uint8array-base64, TypedArray]
+---*/
+
+var toStringCalls = 0;
+var throwyToString = {
+ toString: function() {
+ toStringCalls += 1;
+ throw new Test262Error("toString called");
+ }
+};
+
+assert.throws(TypeError, function() {
+ Uint8Array.fromBase64(throwyToString);
+});
+assert.sameValue(toStringCalls, 0);
+
+
+var optionAccesses = 0;
+var touchyOptions = {};
+Object.defineProperty(touchyOptions, "alphabet", {
+ get: function() {
+ optionAccesses += 1;
+ throw new Test262Error("alphabet accessed");
+ }
+});
+Object.defineProperty(touchyOptions, "lastChunkHandling", {
+ get: function() {
+ optionAccesses += 1;
+ throw new Test262Error("lastChunkHandling accessed");
+ }
+});
+assert.throws(TypeError, function() {
+ Uint8Array.fromBase64(throwyToString, touchyOptions);
+});
+assert.sameValue(toStringCalls, 0);
+assert.sameValue(optionAccesses, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js
new file mode 100644
index 0000000000..87c79a6563
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromBase64/whitespace.js
@@ -0,0 +1,25 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.frombase64
+description: Uint8Array.fromBase64 ignores ASCII whitespace in the input
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var whitespaceKinds = [
+ ["Z g==", "space"],
+ ["Z\tg==", "tab"],
+ ["Z\x0Ag==", "LF"],
+ ["Z\x0Cg==", "FF"],
+ ["Z\x0Dg==", "CR"],
+];
+whitespaceKinds.forEach(function(pair) {
+ var arr = Uint8Array.fromBase64(pair[0]);
+ assert.sameValue(arr.length, 1);
+ assert.sameValue(arr.buffer.byteLength, 1);
+ assert.compareArray(arr, [102], "ascii whitespace: " + pair[1]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js
new file mode 100644
index 0000000000..3d53652054
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/descriptor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: >
+ Uint8Array.fromHex has default data property attributes.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array, 'fromHex', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js
new file mode 100644
index 0000000000..421a0278d7
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/ignores-receiver.js
@@ -0,0 +1,22 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: Uint8Array.fromHex ignores its receiver
+features: [uint8array-base64, TypedArray]
+---*/
+
+var fromHex = Uint8Array.fromHex;
+var noReceiver = fromHex("aa");
+assert.sameValue(Object.getPrototypeOf(noReceiver), Uint8Array.prototype);
+
+class Subclass extends Uint8Array {
+ constructor() {
+ throw new Test262Error("subclass constructor called");
+ }
+}
+var fromSubclass = Subclass.fromHex("aa");
+assert.sameValue(Object.getPrototypeOf(fromSubclass), Uint8Array.prototype);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js
new file mode 100644
index 0000000000..718801e4c7
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/illegal-characters.js
@@ -0,0 +1,28 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: Uint8Array.fromHex throws a SyntaxError when input has non-hex characters
+features: [uint8array-base64, TypedArray]
+---*/
+
+var illegal = [
+ 'a.a',
+ 'aa^',
+ 'a a',
+ 'a\ta',
+ 'a\x0Aa',
+ 'a\x0Ca',
+ 'a\x0Da',
+ 'a\u00A0a', // nbsp
+ 'a\u2009a', // thin space
+ 'a\u2028a', // line separator
+];
+illegal.forEach(function(value) {
+ assert.throws(SyntaxError, function() {
+ Uint8Array.fromHex(value)
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js
new file mode 100644
index 0000000000..9108a1c2c1
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/length.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: >
+ Uint8Array.fromHex.length is 1.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.fromHex, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js
new file mode 100644
index 0000000000..7d4e145349
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/name.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: >
+ Uint8Array.fromHex.name is "fromHex".
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.fromHex, 'name', {
+ value: 'fromHex',
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js
new file mode 100644
index 0000000000..6e34171e77
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/nonconstructor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: >
+ Uint8Array.fromHex is not a constructor function.
+includes: [isConstructor.js]
+features: [uint8array-base64, TypedArray, Reflect.construct]
+---*/
+
+assert(!isConstructor(Uint8Array.fromHex), "Uint8Array.fromHex is not a constructor");
+
+assert.throws(TypeError, function() {
+ new Uint8Array.fromHex('');
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js
new file mode 100644
index 0000000000..fe7860a083
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/odd-length-input.js
@@ -0,0 +1,14 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: Uint8Array.fromHex throws if given an odd number of input hex characters
+features: [uint8array-base64, TypedArray]
+---*/
+
+assert.throws(SyntaxError, function() {
+ Uint8Array.fromHex('a');
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js
new file mode 100644
index 0000000000..d40beab7cd
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/results.js
@@ -0,0 +1,31 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: Conversion of hex strings to Uint8Arrays
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var cases = [
+ ["", []],
+ ["66", [102]],
+ ["666f", [102, 111]],
+ ["666F", [102, 111]],
+ ["666f6f", [102, 111, 111]],
+ ["666F6f", [102, 111, 111]],
+ ["666f6f62", [102, 111, 111, 98]],
+ ["666f6f6261", [102, 111, 111, 98, 97]],
+ ["666f6f626172", [102, 111, 111, 98, 97, 114]],
+];
+
+cases.forEach(function (pair) {
+ var arr = Uint8Array.fromHex(pair[0]);
+ assert.sameValue(Object.getPrototypeOf(arr), Uint8Array.prototype, "decoding " + pair[0]);
+ assert.sameValue(arr.length, pair[1].length, "decoding " + pair[0]);
+ assert.sameValue(arr.buffer.byteLength, pair[1].length, "decoding " + pair[0]);
+ assert.compareArray(arr, pair[1], "decoding " + pair[0]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js
new file mode 100644
index 0000000000..eda1477282
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/shell.js
@@ -0,0 +1,24 @@
+// GENERATED, DO NOT EDIT
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js
new file mode 100644
index 0000000000..fea57227fc
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/fromHex/string-coercion.js
@@ -0,0 +1,23 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.fromhex
+description: Uint8Array.fromHex throws if its argument is not a string
+features: [uint8array-base64, TypedArray]
+---*/
+
+var toStringCalls = 0;
+var throwyToString = {
+ toString: function() {
+ toStringCalls += 1;
+ throw new Test262Error("toString called");
+ }
+};
+
+assert.throws(TypeError, function() {
+ Uint8Array.fromHex(throwyToString);
+});
+assert.sameValue(toStringCalls, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js
new file mode 100644
index 0000000000..bb4acdb8f2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/alphabet.js
@@ -0,0 +1,44 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Conversion of base64 strings to Uint8Arrays exercising the alphabet option
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var target = new Uint8Array([255, 255, 255, 255]);
+var result = target.setFromBase64('x+/y');
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [199, 239, 242, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255]);
+var result = target.setFromBase64('x+/y', { alphabet: 'base64' });
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [199, 239, 242, 255]);
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255]);
+ target.setFromBase64('x+/y', { alphabet: 'base64url' });
+});
+
+
+var target = new Uint8Array([255, 255, 255, 255]);
+var result = target.setFromBase64('x-_y', { alphabet: 'base64url' });
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [199, 239, 242, 255]);
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255]);
+ target.setFromBase64('x-_y');
+});
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255]);
+ target.setFromBase64('x-_y', { alphabet: 'base64' });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js
new file mode 100644
index 0000000000..bd319f7d43
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: >
+ Uint8Array.prototype.setFromBase64 has default data property attributes.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype, 'setFromBase64', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js
new file mode 100644
index 0000000000..3dd042bb02
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/detached-buffer.js
@@ -0,0 +1,32 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Uint8Array.prototype.setFromBase64 throws on detatched buffers
+includes: [detachArrayBuffer.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var target = new Uint8Array([255, 255, 255]);
+$DETACHBUFFER(target.buffer);
+assert.throws(TypeError, function() {
+ target.setFromBase64('Zg==');
+});
+
+var getterCalls = 0;
+var targetDetachingOptions = {};
+Object.defineProperty(targetDetachingOptions, 'alphabet', {
+ get: function() {
+ getterCalls += 1;
+ $DETACHBUFFER(target.buffer);
+ return "base64";
+ }
+});
+var target = new Uint8Array([255, 255, 255]);
+assert.throws(TypeError, function() {
+ target.setFromBase64('Zg==', targetDetachingOptions);
+});
+assert.sameValue(getterCalls, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js
new file mode 100644
index 0000000000..9c6b827df8
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/illegal-characters.js
@@ -0,0 +1,27 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Uint8Array.prototype.setFromBase64 throws a SyntaxError when input has non-base64, non-ascii-whitespace characters
+features: [uint8array-base64, TypedArray]
+---*/
+
+var illegal = [
+ 'Zm.9v',
+ 'Zm9v^',
+ 'Zg==&',
+ 'Z−==', // U+2212 'Minus Sign'
+ 'Z+==', // U+FF0B 'Fullwidth Plus Sign'
+ 'Zg\u00A0==', // nbsp
+ 'Zg\u2009==', // thin space
+ 'Zg\u2028==', // line separator
+];
+illegal.forEach(function(value) {
+ assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255]);
+ target.setFromBase64(value);
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js
new file mode 100644
index 0000000000..958a89b10e
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/last-chunk-handling.js
@@ -0,0 +1,156 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Handling of final chunks in target.setFromBase64
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+// padding
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg==');
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'loose' });
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'stop-before-partial' });
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'strict' });
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+
+// no padding
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg');
+assert.sameValue(result.read, 6);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg', { lastChunkHandling: 'loose' });
+assert.sameValue(result.read, 6);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg', { lastChunkHandling: 'stop-before-partial' });
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [101, 120, 97, 255, 255, 255]);
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg', { lastChunkHandling: 'strict' });
+});
+
+
+// non-zero padding bits
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZh==');
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'loose' });
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'stop-before-partial' });
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'strict' });
+});
+
+
+// non-zero padding bits, no padding
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZh');
+assert.sameValue(result.read, 6);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZh', { lastChunkHandling: 'loose' });
+assert.sameValue(result.read, 6);
+assert.sameValue(result.written, 4);
+assert.compareArray(target, [101, 120, 97, 102, 255, 255]);
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZh', { lastChunkHandling: 'stop-before-partial' });
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [101, 120, 97, 255, 255, 255]);
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZh', { lastChunkHandling: 'strict' });
+});
+
+
+// partial padding
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg=');
+});
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg=', { lastChunkHandling: 'loose' });
+});
+
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('ZXhhZg=', { lastChunkHandling: 'stop-before-partial' });
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [101, 120, 97, 255, 255, 255]);
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg=', { lastChunkHandling: 'strict' });
+});
+
+
+// excess padding
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg===');
+});
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg===', { lastChunkHandling: 'loose' });
+});
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg===', { lastChunkHandling: 'stop-before-partial' });
+});
+
+assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+ target.setFromBase64('ZXhhZg===', { lastChunkHandling: 'strict' });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js
new file mode 100644
index 0000000000..df97101a14
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/length.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: >
+ Uint8Array.prototype.setFromBase64.length is 1.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.setFromBase64, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js
new file mode 100644
index 0000000000..c38be74532
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/name.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: >
+ Uint8Array.prototype.setFromBase64.name is "setFromBase64".
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.setFromBase64, 'name', {
+ value: 'setFromBase64',
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js
new file mode 100644
index 0000000000..46f5078ff5
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: >
+ Uint8Array.prototype.setFromBase64 is not a constructor function.
+includes: [isConstructor.js]
+features: [uint8array-base64, TypedArray, Reflect.construct]
+---*/
+
+assert(!isConstructor(Uint8Array.prototype.setFromBase64), "Uint8Array.prototype.setFromBase64 is not a constructor");
+
+assert.throws(TypeError, function() {
+ var target = new Uint8Array(10);
+ new target.setFromBase64('');
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js
new file mode 100644
index 0000000000..90bd1e330d
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/option-coercion.js
@@ -0,0 +1,72 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Uint8Array.prototype.setFromBase64 triggers effects of the "alphabet" and "lastChunkHandling" getters, but does not perform toString on the results
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+assert.throws(TypeError, function() {
+ var target = new Uint8Array([255, 255, 255]);
+ target.setFromBase64("Zg==", { alphabet: Object("base64") });
+});
+
+assert.throws(TypeError, function() {
+ var target = new Uint8Array([255, 255, 255]);
+ target.setFromBase64("Zg==", { lastChunkHandling: Object("strict") });
+});
+
+
+var toStringCalls = 0;
+var throwyToString = {
+ toString: function() {
+ toStringCalls += 1;
+ throw new Test262Error("toString called");
+ }
+};
+assert.throws(TypeError, function() {
+ var target = new Uint8Array([255, 255, 255]);
+ target.setFromBase64("Zg==", { alphabet: throwyToString });
+});
+assert.sameValue(toStringCalls, 0);
+
+assert.throws(TypeError, function() {
+ var target = new Uint8Array([255, 255, 255]);
+ target.setFromBase64("Zg==", { lastChunkHandling: throwyToString });
+});
+assert.sameValue(toStringCalls, 0);
+
+
+var alphabetAccesses = 0;
+var base64UrlOptions = {};
+Object.defineProperty(base64UrlOptions, "alphabet", {
+ get: function() {
+ alphabetAccesses += 1;
+ return "base64url";
+ }
+});
+var target = new Uint8Array([255, 255, 255, 255]);
+var result = target.setFromBase64("x-_y", base64UrlOptions);
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [199, 239, 242, 255]);
+assert.sameValue(alphabetAccesses, 1);
+
+var lastChunkHandlingAccesses = 0;
+var strictOptions = {};
+Object.defineProperty(strictOptions, "lastChunkHandling", {
+ get: function() {
+ lastChunkHandlingAccesses += 1;
+ return "strict";
+ }
+});
+var target = new Uint8Array([255, 255, 255, 255]);
+var result = target.setFromBase64("Zg==", strictOptions);
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 1);
+assert.compareArray(target, [102, 255, 255, 255]);
+assert.sameValue(lastChunkHandlingAccesses, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js
new file mode 100644
index 0000000000..2c39bab318
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/results.js
@@ -0,0 +1,33 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Conversion of base64 strings to Uint8Arrays
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+// standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10
+var standardBase64Vectors = [
+ ["", []],
+ ["Zg==", [102]],
+ ["Zm8=", [102, 111]],
+ ["Zm9v", [102, 111, 111]],
+ ["Zm9vYg==", [102, 111, 111, 98]],
+ ["Zm9vYmE=", [102, 111, 111, 98, 97]],
+ ["Zm9vYmFy", [102, 111, 111, 98, 97, 114]],
+];
+
+standardBase64Vectors.forEach(function (pair) {
+ var allFF = [255, 255, 255, 255, 255, 255, 255, 255];
+ var target = new Uint8Array(allFF);
+ var result = target.setFromBase64(pair[0]);
+ assert.sameValue(result.read, pair[0].length);
+ assert.sameValue(result.written, pair[1].length);
+
+ var expected = pair[1].concat(allFF.slice(pair[1].length))
+ assert.compareArray(target, expected, "decoding " + pair[0]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js
new file mode 100644
index 0000000000..a7590326c3
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/shell.js
@@ -0,0 +1,42 @@
+// GENERATED, DO NOT EDIT
+// file: detachArrayBuffer.js
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ A function used in the process of asserting correctness of TypedArray objects.
+
+ $262.detachArrayBuffer is defined by a host.
+defines: [$DETACHBUFFER]
+---*/
+
+function $DETACHBUFFER(buffer) {
+ if (!$262 || typeof $262.detachArrayBuffer !== "function") {
+ throw new Test262Error("No method available to detach an ArrayBuffer");
+ }
+ $262.detachArrayBuffer(buffer);
+}
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js
new file mode 100644
index 0000000000..7c479a78cd
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/string-coercion.js
@@ -0,0 +1,46 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Uint8Array.prototype.setFromBase64 throws if its first argument is not a string
+features: [uint8array-base64, TypedArray]
+---*/
+
+var toStringCalls = 0;
+var throwyToString = {
+ toString: function() {
+ toStringCalls += 1;
+ throw new Test262Error("toString called");
+ }
+};
+
+assert.throws(TypeError, function() {
+ var target = new Uint8Array(10);
+ target.setFromBase64(throwyToString);
+});
+assert.sameValue(toStringCalls, 0);
+
+
+var optionAccesses = 0;
+var touchyOptions = {};
+Object.defineProperty(touchyOptions, "alphabet", {
+ get: function() {
+ optionAccesses += 1;
+ throw new Test262Error("alphabet accessed");
+ }
+});
+Object.defineProperty(touchyOptions, "lastChunkHandling", {
+ get: function() {
+ optionAccesses += 1;
+ throw new Test262Error("lastChunkHandling accessed");
+ }
+});
+assert.throws(TypeError, function() {
+ var target = new Uint8Array(10);
+ target.setFromBase64(throwyToString, touchyOptions);
+});
+assert.sameValue(toStringCalls, 0);
+assert.sameValue(optionAccesses, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js
new file mode 100644
index 0000000000..ffffd227b9
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/subarray.js
@@ -0,0 +1,20 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Uint8Array.prototype.setFromBase64 takes into account the offset of the target Uint8Array
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var base = new Uint8Array([255, 255, 255, 255, 255, 255, 255]);
+var subarray = base.subarray(2, 5);
+
+var result = subarray.setFromBase64('Zm9vYmFy');
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(subarray, [102, 111, 111]);
+assert.compareArray(base, [255, 255, 102, 111, 111, 255, 255]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js
new file mode 100644
index 0000000000..4e38423621
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/target-size.js
@@ -0,0 +1,67 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Uint8Array.prototype.setFromBase64 behavior when target buffer is small
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+// buffer too small
+var target = new Uint8Array([255, 255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmFy');
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [102, 111, 111, 255, 255]);
+
+// buffer too small, padded
+var target = new Uint8Array([255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmE=');
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [102, 111, 111, 255]);
+
+// buffer exact
+var target = new Uint8Array([255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmFy');
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 6);
+assert.compareArray(target, [102, 111, 111, 98, 97, 114]);
+
+// buffer exact, padded
+var target = new Uint8Array([255, 255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmE=');
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 5);
+assert.compareArray(target, [102, 111, 111, 98, 97]);
+
+// buffer exact, not padded
+var target = new Uint8Array([255, 255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmE');
+assert.sameValue(result.read, 7);
+assert.sameValue(result.written, 5);
+assert.compareArray(target, [102, 111, 111, 98, 97]);
+
+// buffer exact, padded, stop-before-partial
+var target = new Uint8Array([255, 255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmE=', { lastChunkHandling: 'stop-before-partial' });
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 5);
+assert.compareArray(target, [102, 111, 111, 98, 97]);
+
+// buffer exact, not padded, stop-before-partial
+var target = new Uint8Array([255, 255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmE', { lastChunkHandling: 'stop-before-partial' });
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [102, 111, 111, 255, 255]);
+
+// buffer too large
+var target = new Uint8Array([255, 255, 255, 255, 255, 255, 255]);
+var result = target.setFromBase64('Zm9vYmFy');
+assert.sameValue(result.read, 8);
+assert.sameValue(result.written, 6);
+assert.compareArray(target, [102, 111, 111, 98, 97, 114, 255]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js
new file mode 100644
index 0000000000..a09673d2bd
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromBase64/whitespace.js
@@ -0,0 +1,26 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfrombase64
+description: Uint8Array.prototype.setFromBase64 ignores ASCII whitespace in the input
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var whitespaceKinds = [
+ ["Z g==", "space"],
+ ["Z\tg==", "tab"],
+ ["Z\x0Ag==", "LF"],
+ ["Z\x0Cg==", "FF"],
+ ["Z\x0Dg==", "CR"],
+];
+whitespaceKinds.forEach(function(pair) {
+ var target = new Uint8Array([255, 255, 255]);
+ var result = target.setFromBase64(pair[0]);
+ assert.sameValue(result.read, 5);
+ assert.sameValue(result.written, 1);
+ assert.compareArray(target, [102, 255, 255], "ascii whitespace: " + pair[1]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js
new file mode 100644
index 0000000000..3d1a4c996a
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/descriptor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: >
+ Uint8Array.prototype.setFromHex has default data property attributes.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype, 'setFromHex', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js
new file mode 100644
index 0000000000..5ba8e15727
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/detached-buffer.js
@@ -0,0 +1,17 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: Uint8Array.prototype.setFromHex throws on detatched buffers
+includes: [detachArrayBuffer.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var target = new Uint8Array([255, 255, 255]);
+$DETACHBUFFER(target.buffer);
+assert.throws(TypeError, function() {
+ target.setFromHex('aa');
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js
new file mode 100644
index 0000000000..1c30b4cffd
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/illegal-characters.js
@@ -0,0 +1,29 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: Uint8Array.prototype.setFromHex throws a SyntaxError when input has non-hex characters
+features: [uint8array-base64, TypedArray]
+---*/
+
+var illegal = [
+ 'a.a',
+ 'aa^',
+ 'a a',
+ 'a\ta',
+ 'a\x0Aa',
+ 'a\x0Ca',
+ 'a\x0Da',
+ 'a\u00A0a', // nbsp
+ 'a\u2009a', // thin space
+ 'a\u2028a', // line separator
+];
+illegal.forEach(function(value) {
+ assert.throws(SyntaxError, function() {
+ var target = new Uint8Array([255, 255, 255, 255, 255]);
+ target.setFromHex(value);
+ });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js
new file mode 100644
index 0000000000..b0b56ef761
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/length.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: >
+ Uint8Array.prototype.setFromHex.length is 1.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.setFromHex, 'length', {
+ value: 1,
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js
new file mode 100644
index 0000000000..cbc06e6f3d
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/name.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: >
+ Uint8Array.prototype.setFromHex.name is "setFromHex".
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.setFromHex, 'name', {
+ value: 'setFromHex',
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js
new file mode 100644
index 0000000000..196b962bdf
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: >
+ Uint8Array.prototype.setFromHex is not a constructor function.
+includes: [isConstructor.js]
+features: [uint8array-base64, TypedArray, Reflect.construct]
+---*/
+
+assert(!isConstructor(Uint8Array.prototype.setFromHex), "target.setFromHex is not a constructor");
+
+assert.throws(TypeError, function() {
+ var target = new Uint8Array(10);
+ new target.setFromHex('');
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js
new file mode 100644
index 0000000000..c7749c6257
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/results.js
@@ -0,0 +1,34 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: Conversion of hex strings to Uint8Arrays
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var cases = [
+ ["", []],
+ ["66", [102]],
+ ["666f", [102, 111]],
+ ["666F", [102, 111]],
+ ["666f6f", [102, 111, 111]],
+ ["666F6f", [102, 111, 111]],
+ ["666f6f62", [102, 111, 111, 98]],
+ ["666f6f6261", [102, 111, 111, 98, 97]],
+ ["666f6f626172", [102, 111, 111, 98, 97, 114]],
+];
+
+cases.forEach(function (pair) {
+ var allFF = [255, 255, 255, 255, 255, 255, 255, 255];
+ var target = new Uint8Array(allFF);
+ var result = target.setFromHex(pair[0]);
+ assert.sameValue(result.read, pair[0].length);
+ assert.sameValue(result.written, pair[1].length);
+
+ var expected = pair[1].concat(allFF.slice(pair[1].length))
+ assert.compareArray(target, expected, "decoding " + pair[0]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js
new file mode 100644
index 0000000000..a7590326c3
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/shell.js
@@ -0,0 +1,42 @@
+// GENERATED, DO NOT EDIT
+// file: detachArrayBuffer.js
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ A function used in the process of asserting correctness of TypedArray objects.
+
+ $262.detachArrayBuffer is defined by a host.
+defines: [$DETACHBUFFER]
+---*/
+
+function $DETACHBUFFER(buffer) {
+ if (!$262 || typeof $262.detachArrayBuffer !== "function") {
+ throw new Test262Error("No method available to detach an ArrayBuffer");
+ }
+ $262.detachArrayBuffer(buffer);
+}
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js
new file mode 100644
index 0000000000..9a6f5f84c0
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/string-coercion.js
@@ -0,0 +1,24 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: Uint8Array.prototype.setFromHex throws if its first argument is not a string
+features: [uint8array-base64, TypedArray]
+---*/
+
+var toStringCalls = 0;
+var throwyToString = {
+ toString: function() {
+ toStringCalls += 1;
+ throw new Test262Error("toString called");
+ }
+};
+
+assert.throws(TypeError, function() {
+ var target = new Uint8Array(10);
+ target.setFromHex(throwyToString);
+});
+assert.sameValue(toStringCalls, 0);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js
new file mode 100644
index 0000000000..45879d8cb3
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/subarray.js
@@ -0,0 +1,20 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: Uint8Array.prototype.setFromHex takes into account the offset of the target Uint8Array
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var base = new Uint8Array([255, 255, 255, 255, 255, 255, 255]);
+var subarray = base.subarray(2, 5);
+
+var result = subarray.setFromHex('aabbcc');
+assert.sameValue(result.read, 6);
+assert.sameValue(result.written, 3);
+assert.compareArray(subarray, [170, 187, 204]);
+assert.compareArray(base, [255, 255, 170, 187, 204, 255, 255]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js
new file mode 100644
index 0000000000..d73fa1749d
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/setFromHex/target-size.js
@@ -0,0 +1,32 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.setfromhex
+description: Uint8Array.prototype.setFromHex behavior when target buffer is small
+includes: [compareArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+// buffer too small
+var target = new Uint8Array([255, 255]);
+var result = target.setFromHex('aabbcc');
+assert.sameValue(result.read, 4);
+assert.sameValue(result.written, 2);
+assert.compareArray(target, [170, 187]);
+
+// buffer exact
+var target = new Uint8Array([255, 255, 255]);
+var result = target.setFromHex('aabbcc');
+assert.sameValue(result.read, 6);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [170, 187, 204]);
+
+// buffer too large
+var target = new Uint8Array([255, 255, 255, 255]);
+var result = target.setFromHex('aabbcc');
+assert.sameValue(result.read, 6);
+assert.sameValue(result.written, 3);
+assert.compareArray(target, [170, 187, 204, 255]);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/shell.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js
new file mode 100644
index 0000000000..7edf0a379e
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/alphabet.js
@@ -0,0 +1,20 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: Conversion of Uint8Arrays to base64 strings exercising the alphabet option
+features: [uint8array-base64, TypedArray]
+---*/
+
+assert.sameValue((new Uint8Array([199, 239, 242])).toBase64(), "x+/y");
+
+assert.sameValue((new Uint8Array([199, 239, 242])).toBase64({ alphabet: 'base64' }), "x+/y");
+
+assert.sameValue((new Uint8Array([199, 239, 242])).toBase64({ alphabet: 'base64url' }), "x-_y");
+
+assert.throws(TypeError, function() {
+ (new Uint8Array([199, 239, 242])).toBase64({ alphabet: 'other' });
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js
new file mode 100644
index 0000000000..9c34719bf1
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/descriptor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: >
+ Uint8Array.prototype.toBase64 has default data property attributes.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype, 'toBase64', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js
new file mode 100644
index 0000000000..0904454743
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/detached-buffer.js
@@ -0,0 +1,42 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: Uint8Array.prototype.toBase64 checks for detachedness after side-effects are finished
+includes: [detachArrayBuffer.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var array = new Uint8Array(2);
+var getterCalls = 0;
+var receiverDetachingOptions = {};
+Object.defineProperty(receiverDetachingOptions, "alphabet", {
+ get: function() {
+ getterCalls += 1;
+ $DETACHBUFFER(array.buffer);
+ return "base64";
+ }
+});
+assert.throws(TypeError, function() {
+ array.toBase64(receiverDetachingOptions);
+});
+assert.sameValue(getterCalls, 1);
+
+
+var detached = new Uint8Array(2);
+$DETACHBUFFER(detached.buffer);
+var getterCalls = 0;
+var sideEffectingOptions = {};
+Object.defineProperty(sideEffectingOptions, "alphabet", {
+ get: function() {
+ getterCalls += 1;
+ return "base64";
+ }
+});
+assert.throws(TypeError, function() {
+ detached.toBase64(sideEffectingOptions);
+});
+assert.sameValue(getterCalls, 1);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js
new file mode 100644
index 0000000000..9e4aabb9ed
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/length.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: >
+ Uint8Array.prototype.toBase64.length is 0.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.toBase64, 'length', {
+ value: 0,
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js
new file mode 100644
index 0000000000..2510648b76
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/name.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: >
+ Uint8Array.prototype.toBase64.name is "toBase64".
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.toBase64, 'name', {
+ value: 'toBase64',
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js
new file mode 100644
index 0000000000..79280e2d5d
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: >
+ Uint8Array.prototype.toBase64 is not a constructor function.
+includes: [isConstructor.js]
+features: [uint8array-base64, TypedArray, Reflect.construct]
+---*/
+
+assert(!isConstructor(Uint8Array.prototype.toBase64), "Uint8Array.prototype.toBase64 is not a constructor");
+
+var uint8Array = new Uint8Array(8);
+assert.throws(TypeError, function() {
+ new uint8Array.toBase64();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js
new file mode 100644
index 0000000000..054a3a5e0d
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/option-coercion.js
@@ -0,0 +1,51 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: Uint8Array.prototype.toBase64 triggers effects of the "alphabet" getter, but does not perform toString on the result
+features: [uint8array-base64, TypedArray]
+---*/
+
+assert.throws(TypeError, function() {
+ (new Uint8Array(2)).toBase64({ alphabet: Object("base64") });
+});
+
+
+var toStringCalls = 0;
+var throwyToString = {
+ toString: function() {
+ toStringCalls += 1;
+ throw new Test262Error("toString called on alphabet value");
+ }
+};
+assert.throws(TypeError, function() {
+ (new Uint8Array(2)).toBase64({ alphabet: throwyToString });
+});
+assert.sameValue(toStringCalls, 0);
+
+var alphabetAccesses = 0;
+var base64UrlOptions = {};
+Object.defineProperty(base64UrlOptions, "alphabet", {
+ get: function() {
+ alphabetAccesses += 1;
+ return "base64url";
+ }
+});
+assert.sameValue((new Uint8Array([199, 239, 242])).toBase64(base64UrlOptions), "x-_y");
+assert.sameValue(alphabetAccesses, 1);
+
+// side-effects from the getter on the receiver are reflected in the result
+var array = new Uint8Array([0]);
+var receiverMutatingOptions = {};
+Object.defineProperty(receiverMutatingOptions, "alphabet", {
+ get: function() {
+ array[0] = 255;
+ return "base64";
+ }
+});
+var result = array.toBase64(receiverMutatingOptions);
+assert.sameValue(result, "/w==");
+assert.sameValue(array[0], 255);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js
new file mode 100644
index 0000000000..53352ce4a5
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/receiver-not-uint8array.js
@@ -0,0 +1,36 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: Uint8Array.prototype.toBase64 throws if the receiver is not a Uint8Array
+includes: [testTypedArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var toBase64 = Uint8Array.prototype.toBase64;
+
+var options = {};
+Object.defineProperty(options, "alphabet", {
+ get: function() {
+ throw new Test262Error("options.alphabet accessed despite incompatible receiver");
+ }
+});
+
+testWithTypedArrayConstructors(function(TA) {
+ if (TA === Uint8Array) return;
+ var sample = new TA(2);
+ assert.throws(TypeError, function() {
+ Uint8Array.prototype.toBase64.call(sample, options);
+ });
+});
+
+assert.throws(TypeError, function() {
+ Uint8Array.prototype.toBase64.call([], options);
+});
+
+assert.throws(TypeError, function() {
+ toBase64(options);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js
new file mode 100644
index 0000000000..5ce75170b7
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/results.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tobase64
+description: Conversion of Uint8Arrays to base64 strings
+features: [uint8array-base64, TypedArray]
+---*/
+
+// standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10
+assert.sameValue((new Uint8Array([])).toBase64(), "");
+assert.sameValue((new Uint8Array([102])).toBase64(), "Zg==");
+assert.sameValue((new Uint8Array([102, 111])).toBase64(), "Zm8=");
+assert.sameValue((new Uint8Array([102, 111, 111])).toBase64(), "Zm9v");
+assert.sameValue((new Uint8Array([102, 111, 111, 98])).toBase64(), "Zm9vYg==");
+assert.sameValue((new Uint8Array([102, 111, 111, 98, 97])).toBase64(), "Zm9vYmE=");
+assert.sameValue((new Uint8Array([102, 111, 111, 98, 97, 114])).toBase64(), "Zm9vYmFy");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js
new file mode 100644
index 0000000000..2af708ed59
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toBase64/shell.js
@@ -0,0 +1,203 @@
+// GENERATED, DO NOT EDIT
+// file: detachArrayBuffer.js
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ A function used in the process of asserting correctness of TypedArray objects.
+
+ $262.detachArrayBuffer is defined by a host.
+defines: [$DETACHBUFFER]
+---*/
+
+function $DETACHBUFFER(buffer) {
+ if (!$262 || typeof $262.detachArrayBuffer !== "function") {
+ throw new Test262Error("No method available to detach an ArrayBuffer");
+ }
+ $262.detachArrayBuffer(buffer);
+}
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
+
+// file: testTypedArray.js
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of functions used to assert the correctness of TypedArray objects.
+defines:
+ - floatArrayConstructors
+ - nonClampedIntArrayConstructors
+ - intArrayConstructors
+ - typedArrayConstructors
+ - TypedArray
+ - testWithTypedArrayConstructors
+ - nonAtomicsFriendlyTypedArrayConstructors
+ - testWithAtomicsFriendlyTypedArrayConstructors
+ - testWithNonAtomicsFriendlyTypedArrayConstructors
+ - testTypedArrayConversions
+---*/
+
+var floatArrayConstructors = [
+ Float64Array,
+ Float32Array
+];
+
+var nonClampedIntArrayConstructors = [
+ Int32Array,
+ Int16Array,
+ Int8Array,
+ Uint32Array,
+ Uint16Array,
+ Uint8Array
+];
+
+var intArrayConstructors = nonClampedIntArrayConstructors.concat([Uint8ClampedArray]);
+
+// Float16Array is a newer feature
+// adding it to this list unconditionally would cause implementations lacking it to fail every test which uses it
+if (typeof Float16Array !== 'undefined') {
+ floatArrayConstructors.push(Float16Array);
+}
+
+/**
+ * Array containing every non-bigint typed array constructor.
+ */
+
+var typedArrayConstructors = floatArrayConstructors.concat(intArrayConstructors);
+
+/**
+ * The %TypedArray% intrinsic constructor function.
+ */
+var TypedArray = Object.getPrototypeOf(Int8Array);
+
+/**
+ * Callback for testing a typed array constructor.
+ *
+ * @callback typedArrayConstructorCallback
+ * @param {Function} Constructor the constructor object to test with.
+ */
+
+/**
+ * Calls the provided function for every typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithTypedArrayConstructors(f, selected) {
+ var constructors = selected || typedArrayConstructors;
+ for (var i = 0; i < constructors.length; ++i) {
+ var constructor = constructors[i];
+ try {
+ f(constructor);
+ } catch (e) {
+ e.message += " (Testing with " + constructor.name + ".)";
+ throw e;
+ }
+ }
+}
+
+var nonAtomicsFriendlyTypedArrayConstructors = floatArrayConstructors.concat([Uint8ClampedArray]);
+/**
+ * Calls the provided function for every non-"Atomics Friendly" typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithNonAtomicsFriendlyTypedArrayConstructors(f) {
+ testWithTypedArrayConstructors(f, nonAtomicsFriendlyTypedArrayConstructors);
+}
+
+/**
+ * Calls the provided function for every "Atomics Friendly" typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithAtomicsFriendlyTypedArrayConstructors(f) {
+ testWithTypedArrayConstructors(f, [
+ Int32Array,
+ Int16Array,
+ Int8Array,
+ Uint32Array,
+ Uint16Array,
+ Uint8Array,
+ ]);
+}
+
+/**
+ * Helper for conversion operations on TypedArrays, the expected values
+ * properties are indexed in order to match the respective value for each
+ * TypedArray constructor
+ * @param {Function} fn - the function to call for each constructor and value.
+ * will be called with the constructor, value, expected
+ * value, and a initial value that can be used to avoid
+ * a false positive with an equivalent expected value.
+ */
+function testTypedArrayConversions(byteConversionValues, fn) {
+ var values = byteConversionValues.values;
+ var expected = byteConversionValues.expected;
+
+ testWithTypedArrayConstructors(function(TA) {
+ var name = TA.name.slice(0, -5);
+
+ return values.forEach(function(value, index) {
+ var exp = expected[name][index];
+ var initial = 0;
+ if (exp === 0) {
+ initial = 1;
+ }
+ fn(TA, value, exp, initial);
+ });
+ });
+}
+
+/**
+ * Checks if the given argument is one of the float-based TypedArray constructors.
+ *
+ * @param {constructor} ctor - the value to check
+ * @returns {boolean}
+ */
+function isFloatTypedArrayConstructor(arg) {
+ return floatArrayConstructors.indexOf(arg) !== -1;
+}
+
+/**
+ * Determines the precision of the given float-based TypedArray constructor.
+ *
+ * @param {constructor} ctor - the value to check
+ * @returns {string} "half", "single", or "double" for Float16Array, Float32Array, and Float64Array respectively.
+ */
+function floatTypedArrayConstructorPrecision(FA) {
+ if (typeof Float16Array !== "undefined" && FA === Float16Array) {
+ return "half";
+ } else if (FA === Float32Array) {
+ return "single";
+ } else if (FA === Float64Array) {
+ return "double";
+ } else {
+ throw new Error("Malformed test - floatTypedArrayConstructorPrecision called with non-float TypedArray");
+ }
+}
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/browser.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/browser.js
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js
new file mode 100644
index 0000000000..fa1eba15de
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/descriptor.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tohex
+description: >
+ Uint8Array.prototype.toHex has default data property attributes.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype, 'toHex', {
+ enumerable: false,
+ writable: true,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js
new file mode 100644
index 0000000000..e0126f6725
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/detached-buffer.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tohex
+description: Uint8Array.prototype.toHex throws if called on a detached buffer
+includes: [detachArrayBuffer.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var array = new Uint8Array(2);
+$DETACHBUFFER(array.buffer);
+assert.throws(TypeError, function() {
+ array.toHex();
+});
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js
new file mode 100644
index 0000000000..9c7d00d693
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/length.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tohex
+description: >
+ Uint8Array.prototype.toHex.length is 0.
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.toHex, 'length', {
+ value: 0,
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js
new file mode 100644
index 0000000000..af2e1ef1d4
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/name.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tohex
+description: >
+ Uint8Array.prototype.toHex.name is "toHex".
+includes: [propertyHelper.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+verifyProperty(Uint8Array.prototype.toHex, 'name', {
+ value: 'toHex',
+ enumerable: false,
+ writable: false,
+ configurable: true
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js
new file mode 100644
index 0000000000..2d0f9fc00f
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/nonconstructor.js
@@ -0,0 +1,19 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tohex
+description: >
+ Uint8Array.prototype.toHex is not a constructor function.
+includes: [isConstructor.js]
+features: [uint8array-base64, TypedArray, Reflect.construct]
+---*/
+
+assert(!isConstructor(Uint8Array.prototype.toHex), "Uint8Array.prototype.toHex is not a constructor");
+
+var uint8Array = new Uint8Array(8);
+assert.throws(TypeError, function() {
+ new uint8Array.toHex();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js
new file mode 100644
index 0000000000..1409cca969
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/receiver-not-uint8array.js
@@ -0,0 +1,29 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tohex
+description: Uint8Array.prototype.toHex throws if the receiver is not a Uint8Array
+includes: [testTypedArray.js]
+features: [uint8array-base64, TypedArray]
+---*/
+
+var toHex = Uint8Array.prototype.toHex;
+
+testWithTypedArrayConstructors(function(TA) {
+ if (TA === Uint8Array) return;
+ var sample = new TA(2);
+ assert.throws(TypeError, function() {
+ Uint8Array.prototype.toHex.call(sample);
+ });
+});
+
+assert.throws(TypeError, function() {
+ Uint8Array.prototype.toHex.call([]);
+});
+
+assert.throws(TypeError, function() {
+ toHex();
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js
new file mode 100644
index 0000000000..fb8c31096f
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/results.js
@@ -0,0 +1,18 @@
+// |reftest| shell-option(--enable-uint8array-base64) skip-if(!Uint8Array.fromBase64||!xulRuntime.shell) -- uint8array-base64 is not enabled unconditionally, requires shell-options
+// Copyright (C) 2024 Kevin Gibbons. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-uint8array.prototype.tohex
+description: Conversion of Uint8Arrays to hex strings
+features: [uint8array-base64, TypedArray]
+---*/
+
+assert.sameValue((new Uint8Array([])).toHex(), "");
+assert.sameValue((new Uint8Array([102])).toHex(), "66");
+assert.sameValue((new Uint8Array([102, 111])).toHex(), "666f");
+assert.sameValue((new Uint8Array([102, 111, 111])).toHex(), "666f6f");
+assert.sameValue((new Uint8Array([102, 111, 111, 98])).toHex(), "666f6f62");
+assert.sameValue((new Uint8Array([102, 111, 111, 98, 97])).toHex(), "666f6f6261");
+assert.sameValue((new Uint8Array([102, 111, 111, 98, 97, 114])).toHex(), "666f6f626172");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js
new file mode 100644
index 0000000000..2af708ed59
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/prototype/toHex/shell.js
@@ -0,0 +1,203 @@
+// GENERATED, DO NOT EDIT
+// file: detachArrayBuffer.js
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ A function used in the process of asserting correctness of TypedArray objects.
+
+ $262.detachArrayBuffer is defined by a host.
+defines: [$DETACHBUFFER]
+---*/
+
+function $DETACHBUFFER(buffer) {
+ if (!$262 || typeof $262.detachArrayBuffer !== "function") {
+ throw new Test262Error("No method available to detach an ArrayBuffer");
+ }
+ $262.detachArrayBuffer(buffer);
+}
+
+// file: isConstructor.js
+// Copyright (C) 2017 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: |
+ Test if a given function is a constructor function.
+defines: [isConstructor]
+features: [Reflect.construct]
+---*/
+
+function isConstructor(f) {
+ if (typeof f !== "function") {
+ throw new Test262Error("isConstructor invoked with a non-function value");
+ }
+
+ try {
+ Reflect.construct(function(){}, [], f);
+ } catch (e) {
+ return false;
+ }
+ return true;
+}
+
+// file: testTypedArray.js
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+description: |
+ Collection of functions used to assert the correctness of TypedArray objects.
+defines:
+ - floatArrayConstructors
+ - nonClampedIntArrayConstructors
+ - intArrayConstructors
+ - typedArrayConstructors
+ - TypedArray
+ - testWithTypedArrayConstructors
+ - nonAtomicsFriendlyTypedArrayConstructors
+ - testWithAtomicsFriendlyTypedArrayConstructors
+ - testWithNonAtomicsFriendlyTypedArrayConstructors
+ - testTypedArrayConversions
+---*/
+
+var floatArrayConstructors = [
+ Float64Array,
+ Float32Array
+];
+
+var nonClampedIntArrayConstructors = [
+ Int32Array,
+ Int16Array,
+ Int8Array,
+ Uint32Array,
+ Uint16Array,
+ Uint8Array
+];
+
+var intArrayConstructors = nonClampedIntArrayConstructors.concat([Uint8ClampedArray]);
+
+// Float16Array is a newer feature
+// adding it to this list unconditionally would cause implementations lacking it to fail every test which uses it
+if (typeof Float16Array !== 'undefined') {
+ floatArrayConstructors.push(Float16Array);
+}
+
+/**
+ * Array containing every non-bigint typed array constructor.
+ */
+
+var typedArrayConstructors = floatArrayConstructors.concat(intArrayConstructors);
+
+/**
+ * The %TypedArray% intrinsic constructor function.
+ */
+var TypedArray = Object.getPrototypeOf(Int8Array);
+
+/**
+ * Callback for testing a typed array constructor.
+ *
+ * @callback typedArrayConstructorCallback
+ * @param {Function} Constructor the constructor object to test with.
+ */
+
+/**
+ * Calls the provided function for every typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithTypedArrayConstructors(f, selected) {
+ var constructors = selected || typedArrayConstructors;
+ for (var i = 0; i < constructors.length; ++i) {
+ var constructor = constructors[i];
+ try {
+ f(constructor);
+ } catch (e) {
+ e.message += " (Testing with " + constructor.name + ".)";
+ throw e;
+ }
+ }
+}
+
+var nonAtomicsFriendlyTypedArrayConstructors = floatArrayConstructors.concat([Uint8ClampedArray]);
+/**
+ * Calls the provided function for every non-"Atomics Friendly" typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithNonAtomicsFriendlyTypedArrayConstructors(f) {
+ testWithTypedArrayConstructors(f, nonAtomicsFriendlyTypedArrayConstructors);
+}
+
+/**
+ * Calls the provided function for every "Atomics Friendly" typed array constructor.
+ *
+ * @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
+ * @param {Array} selected - An optional Array with filtered typed arrays
+ */
+function testWithAtomicsFriendlyTypedArrayConstructors(f) {
+ testWithTypedArrayConstructors(f, [
+ Int32Array,
+ Int16Array,
+ Int8Array,
+ Uint32Array,
+ Uint16Array,
+ Uint8Array,
+ ]);
+}
+
+/**
+ * Helper for conversion operations on TypedArrays, the expected values
+ * properties are indexed in order to match the respective value for each
+ * TypedArray constructor
+ * @param {Function} fn - the function to call for each constructor and value.
+ * will be called with the constructor, value, expected
+ * value, and a initial value that can be used to avoid
+ * a false positive with an equivalent expected value.
+ */
+function testTypedArrayConversions(byteConversionValues, fn) {
+ var values = byteConversionValues.values;
+ var expected = byteConversionValues.expected;
+
+ testWithTypedArrayConstructors(function(TA) {
+ var name = TA.name.slice(0, -5);
+
+ return values.forEach(function(value, index) {
+ var exp = expected[name][index];
+ var initial = 0;
+ if (exp === 0) {
+ initial = 1;
+ }
+ fn(TA, value, exp, initial);
+ });
+ });
+}
+
+/**
+ * Checks if the given argument is one of the float-based TypedArray constructors.
+ *
+ * @param {constructor} ctor - the value to check
+ * @returns {boolean}
+ */
+function isFloatTypedArrayConstructor(arg) {
+ return floatArrayConstructors.indexOf(arg) !== -1;
+}
+
+/**
+ * Determines the precision of the given float-based TypedArray constructor.
+ *
+ * @param {constructor} ctor - the value to check
+ * @returns {string} "half", "single", or "double" for Float16Array, Float32Array, and Float64Array respectively.
+ */
+function floatTypedArrayConstructorPrecision(FA) {
+ if (typeof Float16Array !== "undefined" && FA === Float16Array) {
+ return "half";
+ } else if (FA === Float32Array) {
+ return "single";
+ } else if (FA === Float64Array) {
+ return "double";
+ } else {
+ throw new Error("Malformed test - floatTypedArrayConstructorPrecision called with non-float TypedArray");
+ }
+}
diff --git a/js/src/tests/test262/prs/3994/built-ins/Uint8Array/shell.js b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/prs/3994/built-ins/Uint8Array/shell.js