summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262-host.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/tests/test262-host.js
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262-host.js')
-rw-r--r--js/src/tests/test262-host.js248
1 files changed, 248 insertions, 0 deletions
diff --git a/js/src/tests/test262-host.js b/js/src/tests/test262-host.js
new file mode 100644
index 0000000000..8b4fe89c8a
--- /dev/null
+++ b/js/src/tests/test262-host.js
@@ -0,0 +1,248 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// https://github.com/tc39/test262/blob/main/INTERPRETING.md#host-defined-functions
+;(function createHostObject(global) {
+ "use strict";
+
+ // Save built-in functions and constructors.
+ var FunctionToString = global.Function.prototype.toString;
+ var ReflectApply = global.Reflect.apply;
+ var Atomics = global.Atomics;
+ var Error = global.Error;
+ var SharedArrayBuffer = global.SharedArrayBuffer;
+ var Int32Array = global.Int32Array;
+
+ // Save built-in shell functions.
+ var NewGlobal = global.newGlobal;
+ var setSharedArrayBuffer = global.setSharedArrayBuffer;
+ var getSharedArrayBuffer = global.getSharedArrayBuffer;
+ var evalInWorker = global.evalInWorker;
+ var monotonicNow = global.monotonicNow;
+ var gc = global.gc;
+ var clearKeptObjects = global.clearKeptObjects;
+
+ var hasCreateIsHTMLDDA = "createIsHTMLDDA" in global;
+ var hasThreads = ("helperThreadCount" in global ? global.helperThreadCount() > 0 : true);
+ var hasMailbox = typeof setSharedArrayBuffer === "function" && typeof getSharedArrayBuffer === "function";
+ var hasEvalInWorker = typeof evalInWorker === "function";
+
+ if (!hasCreateIsHTMLDDA && !("document" in global && "all" in global.document))
+ throw new Error("no [[IsHTMLDDA]] object available for testing");
+
+ var IsHTMLDDA = hasCreateIsHTMLDDA
+ ? global.createIsHTMLDDA()
+ : global.document.all;
+
+ // The $262.agent framework is not appropriate for browsers yet, and some
+ // test cases can't work in browsers (they block the main thread).
+
+ var shellCode = hasMailbox && hasEvalInWorker;
+ var sabTestable = Atomics && SharedArrayBuffer && hasThreads && shellCode;
+
+ global.$262 = {
+ __proto__: null,
+ createRealm() {
+ var newGlobalObject = NewGlobal();
+ var createHostObjectFn = ReflectApply(FunctionToString, createHostObject, []);
+ newGlobalObject.Function(`${createHostObjectFn} createHostObject(this);`)();
+ return newGlobalObject.$262;
+ },
+ detachArrayBuffer: global.detachArrayBuffer,
+ evalScript: global.evaluateScript || global.evaluate,
+ global,
+ IsHTMLDDA,
+ gc() {
+ gc();
+ },
+ clearKeptObjects() {
+ clearKeptObjects();
+ },
+ agent: (function () {
+
+ // SpiderMonkey complication: With run-time argument --no-threads
+ // our test runner will not properly filter test cases that can't be
+ // run because agents can't be started, and so we do a little
+ // filtering here: We will quietly succeed and exit if an agent test
+ // should not have been run because threads cannot be started.
+ //
+ // Firefox complication: The test cases that use $262.agent can't
+ // currently work in the browser, so for now we rely on them not
+ // being run at all.
+
+ if (!sabTestable) {
+ let {reportCompare, quit} = global;
+
+ function notAvailable() {
+ // See comment above.
+ if (!hasThreads && shellCode) {
+ reportCompare(0, 0);
+ quit(0);
+ }
+ throw new Error("Agents not available");
+ }
+
+ return {
+ start(script) { notAvailable() },
+ broadcast(sab, id) { notAvailable() },
+ getReport() { notAvailable() },
+ sleep(s) { notAvailable() },
+ monotonicNow,
+ }
+ }
+
+ // The SpiderMonkey implementation uses a designated shared buffer _ia
+ // for coordination, and spinlocks for everything except sleeping.
+
+ var _MSG_LOC = 0; // Low bit set: broadcast available; High bits: seq #
+ var _ID_LOC = 1; // ID sent with broadcast
+ var _ACK_LOC = 2; // Worker increments this to ack that broadcast was received
+ var _RDY_LOC = 3; // Worker increments this to ack that worker is up and running
+ var _LOCKTXT_LOC = 4; // Writer lock for the text buffer: 0=open, 1=closed
+ var _NUMTXT_LOC = 5; // Count of messages in text buffer
+ var _NEXT_LOC = 6; // First free location in the buffer
+ var _SLEEP_LOC = 7; // Used for sleeping
+
+ var _FIRST = 10; // First location of first message
+
+ var _ia = new Int32Array(new SharedArrayBuffer(65536));
+ _ia[_NEXT_LOC] = _FIRST;
+
+ var _worker_prefix =
+// BEGIN WORKER PREFIX
+`if (typeof $262 === 'undefined')
+ $262 = {};
+$262.agent = (function (global) {
+ var ReflectApply = global.Reflect.apply;
+ var StringCharCodeAt = global.String.prototype.charCodeAt;
+ var {
+ add: Atomics_add,
+ compareExchange: Atomics_compareExchange,
+ load: Atomics_load,
+ store: Atomics_store,
+ wait: Atomics_wait,
+ } = global.Atomics;
+
+ var {getSharedArrayBuffer} = global;
+
+ var _ia = new Int32Array(getSharedArrayBuffer());
+ var agent = {
+ receiveBroadcast(receiver) {
+ var k;
+ while (((k = Atomics_load(_ia, ${_MSG_LOC})) & 1) === 0)
+ ;
+ var received_sab = getSharedArrayBuffer();
+ var received_id = Atomics_load(_ia, ${_ID_LOC});
+ Atomics_add(_ia, ${_ACK_LOC}, 1);
+ while (Atomics_load(_ia, ${_MSG_LOC}) === k)
+ ;
+ receiver(received_sab, received_id);
+ },
+
+ report(msg) {
+ while (Atomics_compareExchange(_ia, ${_LOCKTXT_LOC}, 0, 1) === 1)
+ ;
+ msg = "" + msg;
+ var i = _ia[${_NEXT_LOC}];
+ _ia[i++] = msg.length;
+ for ( let j=0 ; j < msg.length ; j++ )
+ _ia[i++] = ReflectApply(StringCharCodeAt, msg, [j]);
+ _ia[${_NEXT_LOC}] = i;
+ Atomics_add(_ia, ${_NUMTXT_LOC}, 1);
+ Atomics_store(_ia, ${_LOCKTXT_LOC}, 0);
+ },
+
+ sleep(s) {
+ Atomics_wait(_ia, ${_SLEEP_LOC}, 0, s);
+ },
+
+ leaving() {},
+
+ monotonicNow: global.monotonicNow,
+ };
+ Atomics_add(_ia, ${_RDY_LOC}, 1);
+ return agent;
+})(this);`;
+// END WORKER PREFIX
+
+ var _numWorkers = 0;
+ var _numReports = 0;
+ var _reportPtr = _FIRST;
+ var {
+ add: Atomics_add,
+ load: Atomics_load,
+ store: Atomics_store,
+ wait: Atomics_wait,
+ } = Atomics;
+ var StringFromCharCode = global.String.fromCharCode;
+
+ return {
+ start(script) {
+ setSharedArrayBuffer(_ia.buffer);
+ var oldrdy = Atomics_load(_ia, _RDY_LOC);
+ evalInWorker(_worker_prefix + script);
+ while (Atomics_load(_ia, _RDY_LOC) === oldrdy)
+ ;
+ _numWorkers++;
+ },
+
+ broadcast(sab, id) {
+ setSharedArrayBuffer(sab);
+ Atomics_store(_ia, _ID_LOC, id);
+ Atomics_store(_ia, _ACK_LOC, 0);
+ Atomics_add(_ia, _MSG_LOC, 1);
+ while (Atomics_load(_ia, _ACK_LOC) < _numWorkers)
+ ;
+ Atomics_add(_ia, _MSG_LOC, 1);
+ },
+
+ getReport() {
+ if (_numReports === Atomics_load(_ia, _NUMTXT_LOC))
+ return null;
+ var s = "";
+ var i = _reportPtr;
+ var len = _ia[i++];
+ for ( let j=0 ; j < len ; j++ )
+ s += StringFromCharCode(_ia[i++]);
+ _reportPtr = i;
+ _numReports++;
+ return s;
+ },
+
+ sleep(s) {
+ Atomics_wait(_ia, _SLEEP_LOC, 0, s);
+ },
+
+ monotonicNow,
+ };
+ })()
+ };
+})(this);
+
+var $mozAsyncTestDone = false;
+function $DONE(failure) {
+ // This function is generally called from within a Promise handler, so any
+ // exception thrown by this method will be swallowed and most likely
+ // ignored by the Promise machinery.
+ if ($mozAsyncTestDone) {
+ reportFailure("$DONE() already called");
+ return;
+ }
+ $mozAsyncTestDone = true;
+
+ if (failure)
+ reportFailure(failure);
+ else
+ reportCompare(0, 0);
+
+ if (typeof jsTestDriverEnd === "function") {
+ gDelayTestDriverEnd = false;
+ jsTestDriverEnd();
+ }
+}
+
+// Some tests in test262 leave promise rejections unhandled.
+if ("ignoreUnhandledRejections" in this) {
+ ignoreUnhandledRejections();
+}