diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262-host.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
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.js | 248 |
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(); +} |