Bug 1885337 - Part 3: Import tests from test262 PR. r=spidermonkey-reviewers,dminor
[gecko.git] / js / src / tests / test262 / prs / 3994 / shell.js
blob9adb7aa9141ccf0a146d44520e92a9749f45c4e5
1 // GENERATED, DO NOT EDIT
2 // file: assert.js
3 // Copyright (C) 2017 Ecma International.  All rights reserved.
4 // This code is governed by the BSD license found in the LICENSE file.
5 /*---
6 description: |
7     Collection of assertion functions used throughout test262
8 defines: [assert]
9 ---*/
12 function assert(mustBeTrue, message) {
13   if (mustBeTrue === true) {
14     return;
15   }
17   if (message === undefined) {
18     message = 'Expected true but got ' + assert._toString(mustBeTrue);
19   }
20   throw new Test262Error(message);
23 assert._isSameValue = function (a, b) {
24   if (a === b) {
25     // Handle +/-0 vs. -/+0
26     return a !== 0 || 1 / a === 1 / b;
27   }
29   // Handle NaN vs. NaN
30   return a !== a && b !== b;
33 assert.sameValue = function (actual, expected, message) {
34   try {
35     if (assert._isSameValue(actual, expected)) {
36       return;
37     }
38   } catch (error) {
39     throw new Test262Error(message + ' (_isSameValue operation threw) ' + error);
40     return;
41   }
43   if (message === undefined) {
44     message = '';
45   } else {
46     message += ' ';
47   }
49   message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(expected) + '») to be true';
51   throw new Test262Error(message);
54 assert.notSameValue = function (actual, unexpected, message) {
55   if (!assert._isSameValue(actual, unexpected)) {
56     return;
57   }
59   if (message === undefined) {
60     message = '';
61   } else {
62     message += ' ';
63   }
65   message += 'Expected SameValue(«' + assert._toString(actual) + '», «' + assert._toString(unexpected) + '») to be false';
67   throw new Test262Error(message);
70 assert.throws = function (expectedErrorConstructor, func, message) {
71   var expectedName, actualName;
72   if (typeof func !== "function") {
73     throw new Test262Error('assert.throws requires two arguments: the error constructor ' +
74       'and a function to run');
75     return;
76   }
77   if (message === undefined) {
78     message = '';
79   } else {
80     message += ' ';
81   }
83   try {
84     func();
85   } catch (thrown) {
86     if (typeof thrown !== 'object' || thrown === null) {
87       message += 'Thrown value was not an object!';
88       throw new Test262Error(message);
89     } else if (thrown.constructor !== expectedErrorConstructor) {
90       expectedName = expectedErrorConstructor.name;
91       actualName = thrown.constructor.name;
92       if (expectedName === actualName) {
93         message += 'Expected a ' + expectedName + ' but got a different error constructor with the same name';
94       } else {
95         message += 'Expected a ' + expectedName + ' but got a ' + actualName;
96       }
97       throw new Test262Error(message);
98     }
99     return;
100   }
102   message += 'Expected a ' + expectedErrorConstructor.name + ' to be thrown but no exception was thrown at all';
103   throw new Test262Error(message);
106 assert._toString = function (value) {
107   try {
108     if (value === 0 && 1 / value === -Infinity) {
109       return '-0';
110     }
112     return String(value);
113   } catch (err) {
114     if (err.name === 'TypeError') {
115       return Object.prototype.toString.call(value);
116     }
118     throw err;
119   }
122 // file: compareArray.js
123 // Copyright (C) 2017 Ecma International.  All rights reserved.
124 // This code is governed by the BSD license found in the LICENSE file.
125 /*---
126 description: |
127     Compare the contents of two arrays
128 defines: [compareArray]
129 ---*/
131 function compareArray(a, b) {
132   if (b.length !== a.length) {
133     return false;
134   }
136   for (var i = 0; i < a.length; i++) {
137     if (!compareArray.isSameValue(b[i], a[i])) {
138       return false;
139     }
140   }
141   return true;
144 compareArray.isSameValue = function(a, b) {
145   if (a === 0 && b === 0) return 1 / a === 1 / b;
146   if (a !== a && b !== b) return true;
148   return a === b;
151 compareArray.format = function(arrayLike) {
152   return `[${[].map.call(arrayLike, String).join(', ')}]`;
155 assert.compareArray = function(actual, expected, message) {
156   message  = message === undefined ? '' : message;
158   if (typeof message === 'symbol') {
159     message = message.toString();
160   }
162   assert(actual != null, `First argument shouldn't be nullish. ${message}`);
163   assert(expected != null, `Second argument shouldn't be nullish. ${message}`);
164   var format = compareArray.format;
165   var result = compareArray(actual, expected);
167   // The following prevents actual and expected from being iterated and evaluated
168   // more than once unless absolutely necessary.
169   if (!result) {
170     assert(false, `Expected ${format(actual)} and ${format(expected)} to have the same contents. ${message}`);
171   }
174 // file: propertyHelper.js
175 // Copyright (C) 2017 Ecma International.  All rights reserved.
176 // This code is governed by the BSD license found in the LICENSE file.
177 /*---
178 description: |
179     Collection of functions used to safely verify the correctness of
180     property descriptors.
181 defines:
182   - verifyProperty
183   - verifyEqualTo # deprecated
184   - verifyWritable # deprecated
185   - verifyNotWritable # deprecated
186   - verifyEnumerable # deprecated
187   - verifyNotEnumerable # deprecated
188   - verifyConfigurable # deprecated
189   - verifyNotConfigurable # deprecated
190 ---*/
192 // @ts-check
195  * @param {object} obj
196  * @param {string|symbol} name
197  * @param {PropertyDescriptor|undefined} desc
198  * @param {object} [options]
199  * @param {boolean} [options.restore]
200  */
201 function verifyProperty(obj, name, desc, options) {
202   assert(
203     arguments.length > 2,
204     'verifyProperty should receive at least 3 arguments: obj, name, and descriptor'
205   );
207   var originalDesc = Object.getOwnPropertyDescriptor(obj, name);
208   var nameStr = String(name);
210   // Allows checking for undefined descriptor if it's explicitly given.
211   if (desc === undefined) {
212     assert.sameValue(
213       originalDesc,
214       undefined,
215       "obj['" + nameStr + "'] descriptor should be undefined"
216     );
218     // desc and originalDesc are both undefined, problem solved;
219     return true;
220   }
222   assert(
223     Object.prototype.hasOwnProperty.call(obj, name),
224     "obj should have an own property " + nameStr
225   );
227   assert.notSameValue(
228     desc,
229     null,
230     "The desc argument should be an object or undefined, null"
231   );
233   assert.sameValue(
234     typeof desc,
235     "object",
236     "The desc argument should be an object or undefined, " + String(desc)
237   );
239   var names = Object.getOwnPropertyNames(desc);
240   for (var i = 0; i < names.length; i++) {
241     assert(
242       names[i] === "value" ||
243         names[i] === "writable" ||
244         names[i] === "enumerable" ||
245         names[i] === "configurable" ||
246         names[i] === "get" ||
247         names[i] === "set",
248       "Invalid descriptor field: " + names[i],
249     );
250   }
252   var failures = [];
254   if (Object.prototype.hasOwnProperty.call(desc, 'value')) {
255     if (!isSameValue(desc.value, originalDesc.value)) {
256       failures.push("descriptor value should be " + desc.value);
257     }
258     if (!isSameValue(desc.value, obj[name])) {
259       failures.push("object value should be " + desc.value);
260     }
261   }
263   if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) {
264     if (desc.enumerable !== originalDesc.enumerable ||
265         desc.enumerable !== isEnumerable(obj, name)) {
266       failures.push('descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
267     }
268   }
270   if (Object.prototype.hasOwnProperty.call(desc, 'writable')) {
271     if (desc.writable !== originalDesc.writable ||
272         desc.writable !== isWritable(obj, name)) {
273       failures.push('descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
274     }
275   }
277   if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) {
278     if (desc.configurable !== originalDesc.configurable ||
279         desc.configurable !== isConfigurable(obj, name)) {
280       failures.push('descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
281     }
282   }
284   assert(!failures.length, failures.join('; '));
286   if (options && options.restore) {
287     Object.defineProperty(obj, name, originalDesc);
288   }
290   return true;
293 function isConfigurable(obj, name) {
294   var hasOwnProperty = Object.prototype.hasOwnProperty;
295   try {
296     delete obj[name];
297   } catch (e) {
298     if (!(e instanceof TypeError)) {
299       throw new Test262Error("Expected TypeError, got " + e);
300     }
301   }
302   return !hasOwnProperty.call(obj, name);
305 function isEnumerable(obj, name) {
306   var stringCheck = false;
308   if (typeof name === "string") {
309     for (var x in obj) {
310       if (x === name) {
311         stringCheck = true;
312         break;
313       }
314     }
315   } else {
316     // skip it if name is not string, works for Symbol names.
317     stringCheck = true;
318   }
320   return stringCheck &&
321     Object.prototype.hasOwnProperty.call(obj, name) &&
322     Object.prototype.propertyIsEnumerable.call(obj, name);
325 function isSameValue(a, b) {
326   if (a === 0 && b === 0) return 1 / a === 1 / b;
327   if (a !== a && b !== b) return true;
329   return a === b;
332 var __isArray = Array.isArray;
333 function isWritable(obj, name, verifyProp, value) {
334   var unlikelyValue = __isArray(obj) && name === "length" ?
335     Math.pow(2, 32) - 1 :
336     "unlikelyValue";
337   var newValue = value || unlikelyValue;
338   var hadValue = Object.prototype.hasOwnProperty.call(obj, name);
339   var oldValue = obj[name];
340   var writeSucceeded;
342   try {
343     obj[name] = newValue;
344   } catch (e) {
345     if (!(e instanceof TypeError)) {
346       throw new Test262Error("Expected TypeError, got " + e);
347     }
348   }
350   writeSucceeded = isSameValue(obj[verifyProp || name], newValue);
352   // Revert the change only if it was successful (in other cases, reverting
353   // is unnecessary and may trigger exceptions for certain property
354   // configurations)
355   if (writeSucceeded) {
356     if (hadValue) {
357       obj[name] = oldValue;
358     } else {
359       delete obj[name];
360     }
361   }
363   return writeSucceeded;
367  * Deprecated; please use `verifyProperty` in new tests.
368  */
369 function verifyEqualTo(obj, name, value) {
370   if (!isSameValue(obj[name], value)) {
371     throw new Test262Error("Expected obj[" + String(name) + "] to equal " + value +
372            ", actually " + obj[name]);
373   }
377  * Deprecated; please use `verifyProperty` in new tests.
378  */
379 function verifyWritable(obj, name, verifyProp, value) {
380   if (!verifyProp) {
381     assert(Object.getOwnPropertyDescriptor(obj, name).writable,
382          "Expected obj[" + String(name) + "] to have writable:true.");
383   }
384   if (!isWritable(obj, name, verifyProp, value)) {
385     throw new Test262Error("Expected obj[" + String(name) + "] to be writable, but was not.");
386   }
390  * Deprecated; please use `verifyProperty` in new tests.
391  */
392 function verifyNotWritable(obj, name, verifyProp, value) {
393   if (!verifyProp) {
394     assert(!Object.getOwnPropertyDescriptor(obj, name).writable,
395          "Expected obj[" + String(name) + "] to have writable:false.");
396   }
397   if (isWritable(obj, name, verifyProp)) {
398     throw new Test262Error("Expected obj[" + String(name) + "] NOT to be writable, but was.");
399   }
403  * Deprecated; please use `verifyProperty` in new tests.
404  */
405 function verifyEnumerable(obj, name) {
406   assert(Object.getOwnPropertyDescriptor(obj, name).enumerable,
407        "Expected obj[" + String(name) + "] to have enumerable:true.");
408   if (!isEnumerable(obj, name)) {
409     throw new Test262Error("Expected obj[" + String(name) + "] to be enumerable, but was not.");
410   }
414  * Deprecated; please use `verifyProperty` in new tests.
415  */
416 function verifyNotEnumerable(obj, name) {
417   assert(!Object.getOwnPropertyDescriptor(obj, name).enumerable,
418        "Expected obj[" + String(name) + "] to have enumerable:false.");
419   if (isEnumerable(obj, name)) {
420     throw new Test262Error("Expected obj[" + String(name) + "] NOT to be enumerable, but was.");
421   }
425  * Deprecated; please use `verifyProperty` in new tests.
426  */
427 function verifyConfigurable(obj, name) {
428   assert(Object.getOwnPropertyDescriptor(obj, name).configurable,
429        "Expected obj[" + String(name) + "] to have configurable:true.");
430   if (!isConfigurable(obj, name)) {
431     throw new Test262Error("Expected obj[" + String(name) + "] to be configurable, but was not.");
432   }
436  * Deprecated; please use `verifyProperty` in new tests.
437  */
438 function verifyNotConfigurable(obj, name) {
439   assert(!Object.getOwnPropertyDescriptor(obj, name).configurable,
440        "Expected obj[" + String(name) + "] to have configurable:false.");
441   if (isConfigurable(obj, name)) {
442     throw new Test262Error("Expected obj[" + String(name) + "] NOT to be configurable, but was.");
443   }
446 // file: sta.js
447 // Copyright (c) 2012 Ecma International.  All rights reserved.
448 // This code is governed by the BSD license found in the LICENSE file.
449 /*---
450 description: |
451     Provides both:
453     - An error class to avoid false positives when testing for thrown exceptions
454     - A function to explicitly throw an exception using the Test262Error class
455 defines: [Test262Error, $DONOTEVALUATE]
456 ---*/
459 function Test262Error(message) {
460   this.message = message || "";
463 Test262Error.prototype.toString = function () {
464   return "Test262Error: " + this.message;
467 Test262Error.thrower = function (message) {
468   throw new Test262Error(message);
471 function $DONOTEVALUATE() {
472   throw "Test262: This statement should not be evaluated.";
475 // file: test262-host.js
476 // This Source Code Form is subject to the terms of the Mozilla Public
477 // License, v. 2.0. If a copy of the MPL was not distributed with this
478 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
480 // https://github.com/tc39/test262/blob/main/INTERPRETING.md#host-defined-functions
481 ;(function createHostObject(global) {
482     "use strict";
484     // Save built-in functions and constructors.
485     var FunctionToString = global.Function.prototype.toString;
486     var ReflectApply = global.Reflect.apply;
487     var Atomics = global.Atomics;
488     var Error = global.Error;
489     var SharedArrayBuffer = global.SharedArrayBuffer;
490     var Int32Array = global.Int32Array;
492     // Save built-in shell functions.
493     var NewGlobal = global.newGlobal;
494     var setSharedArrayBuffer = global.setSharedArrayBuffer;
495     var getSharedArrayBuffer = global.getSharedArrayBuffer;
496     var evalInWorker = global.evalInWorker;
497     var monotonicNow = global.monotonicNow;
498     var gc = global.gc;
499     var clearKeptObjects = global.clearKeptObjects;
501     var hasCreateIsHTMLDDA = "createIsHTMLDDA" in global;
502     var hasThreads = ("helperThreadCount" in global ? global.helperThreadCount() > 0 : true);
503     var hasMailbox = typeof setSharedArrayBuffer === "function" && typeof getSharedArrayBuffer === "function";
504     var hasEvalInWorker = typeof evalInWorker === "function";
506     if (!hasCreateIsHTMLDDA && !("document" in global && "all" in global.document))
507         throw new Error("no [[IsHTMLDDA]] object available for testing");
509     var IsHTMLDDA = hasCreateIsHTMLDDA
510                     ? global.createIsHTMLDDA()
511                     : global.document.all;
513     // The $262.agent framework is not appropriate for browsers yet, and some
514     // test cases can't work in browsers (they block the main thread).
516     var shellCode = hasMailbox && hasEvalInWorker;
517     var sabTestable = Atomics && SharedArrayBuffer && hasThreads && shellCode;
519     global.$262 = {
520         __proto__: null,
521         createRealm() {
522             var newGlobalObject = NewGlobal();
523             var createHostObjectFn = ReflectApply(FunctionToString, createHostObject, []);
524             newGlobalObject.Function(`${createHostObjectFn} createHostObject(this);`)();
525             return newGlobalObject.$262;
526         },
527         detachArrayBuffer: global.detachArrayBuffer,
528         evalScript: global.evaluateScript || global.evaluate,
529         global,
530         IsHTMLDDA,
531         gc() {
532             gc();
533         },
534         clearKeptObjects() {
535             clearKeptObjects();
536         },
537         agent: (function () {
539             // SpiderMonkey complication: With run-time argument --no-threads
540             // our test runner will not properly filter test cases that can't be
541             // run because agents can't be started, and so we do a little
542             // filtering here: We will quietly succeed and exit if an agent test
543             // should not have been run because threads cannot be started.
544             //
545             // Firefox complication: The test cases that use $262.agent can't
546             // currently work in the browser, so for now we rely on them not
547             // being run at all.
549             if (!sabTestable) {
550                 let {reportCompare, quit} = global;
552                 function notAvailable() {
553                     // See comment above.
554                     if (!hasThreads && shellCode) {
555                         reportCompare(0, 0);
556                         quit(0);
557                     }
558                     throw new Error("Agents not available");
559                 }
561                 return {
562                     start(script) { notAvailable() },
563                     broadcast(sab, id) { notAvailable() },
564                     getReport() { notAvailable() },
565                     sleep(s) { notAvailable() },
566                     monotonicNow,
567                 }
568             }
570             // The SpiderMonkey implementation uses a designated shared buffer _ia
571             // for coordination, and spinlocks for everything except sleeping.
573             var _MSG_LOC = 0;           // Low bit set: broadcast available; High bits: seq #
574             var _ID_LOC = 1;            // ID sent with broadcast
575             var _ACK_LOC = 2;           // Worker increments this to ack that broadcast was received
576             var _RDY_LOC = 3;           // Worker increments this to ack that worker is up and running
577             var _LOCKTXT_LOC = 4;       // Writer lock for the text buffer: 0=open, 1=closed
578             var _NUMTXT_LOC = 5;        // Count of messages in text buffer
579             var _NEXT_LOC = 6;          // First free location in the buffer
580             var _SLEEP_LOC = 7;         // Used for sleeping
582             var _FIRST = 10;            // First location of first message
584             var _ia = new Int32Array(new SharedArrayBuffer(65536));
585             _ia[_NEXT_LOC] = _FIRST;
587             var _worker_prefix =
588 // BEGIN WORKER PREFIX
589 `if (typeof $262 === 'undefined')
590     $262 = {};
591 $262.agent = (function (global) {
592     var ReflectApply = global.Reflect.apply;
593     var StringCharCodeAt = global.String.prototype.charCodeAt;
594     var {
595         add: Atomics_add,
596         compareExchange: Atomics_compareExchange,
597         load: Atomics_load,
598         store: Atomics_store,
599         wait: Atomics_wait,
600     } = global.Atomics;
602     var {getSharedArrayBuffer} = global;
604     var _ia = new Int32Array(getSharedArrayBuffer());
605     var agent = {
606         receiveBroadcast(receiver) {
607             var k;
608             while (((k = Atomics_load(_ia, ${_MSG_LOC})) & 1) === 0)
609                 ;
610             var received_sab = getSharedArrayBuffer();
611             var received_id = Atomics_load(_ia, ${_ID_LOC});
612             Atomics_add(_ia, ${_ACK_LOC}, 1);
613             while (Atomics_load(_ia, ${_MSG_LOC}) === k)
614                 ;
615             receiver(received_sab, received_id);
616         },
618         report(msg) {
619             while (Atomics_compareExchange(_ia, ${_LOCKTXT_LOC}, 0, 1) === 1)
620                 ;
621             msg = "" + msg;
622             var i = _ia[${_NEXT_LOC}];
623             _ia[i++] = msg.length;
624             for ( let j=0 ; j < msg.length ; j++ )
625                 _ia[i++] = ReflectApply(StringCharCodeAt, msg, [j]);
626             _ia[${_NEXT_LOC}] = i;
627             Atomics_add(_ia, ${_NUMTXT_LOC}, 1);
628             Atomics_store(_ia, ${_LOCKTXT_LOC}, 0);
629         },
631         sleep(s) {
632             Atomics_wait(_ia, ${_SLEEP_LOC}, 0, s);
633         },
635         leaving() {},
637         monotonicNow: global.monotonicNow,
638     };
639     Atomics_add(_ia, ${_RDY_LOC}, 1);
640     return agent;
641 })(this);`;
642 // END WORKER PREFIX
644             var _numWorkers = 0;
645             var _numReports = 0;
646             var _reportPtr = _FIRST;
647             var {
648                 add: Atomics_add,
649                 load: Atomics_load,
650                 store: Atomics_store,
651                 wait: Atomics_wait,
652             } = Atomics;
653             var StringFromCharCode = global.String.fromCharCode;
655             return {
656                 start(script) {
657                     setSharedArrayBuffer(_ia.buffer);
658                     var oldrdy = Atomics_load(_ia, _RDY_LOC);
659                     evalInWorker(_worker_prefix + script);
660                     while (Atomics_load(_ia, _RDY_LOC) === oldrdy)
661                         ;
662                     _numWorkers++;
663                 },
665                 broadcast(sab, id) {
666                     setSharedArrayBuffer(sab);
667                     Atomics_store(_ia, _ID_LOC, id);
668                     Atomics_store(_ia, _ACK_LOC, 0);
669                     Atomics_add(_ia, _MSG_LOC, 1);
670                     while (Atomics_load(_ia, _ACK_LOC) < _numWorkers)
671                         ;
672                     Atomics_add(_ia, _MSG_LOC, 1);
673                 },
675                 getReport() {
676                     if (_numReports === Atomics_load(_ia, _NUMTXT_LOC))
677                         return null;
678                     var s = "";
679                     var i = _reportPtr;
680                     var len = _ia[i++];
681                     for ( let j=0 ; j < len ; j++ )
682                         s += StringFromCharCode(_ia[i++]);
683                     _reportPtr = i;
684                     _numReports++;
685                     return s;
686                 },
688                 sleep(s) {
689                     Atomics_wait(_ia, _SLEEP_LOC, 0, s);
690                 },
692                 monotonicNow,
693             };
694         })()
695     };
696 })(this);
698 var $mozAsyncTestDone = false;
699 function $DONE(failure) {
700     // This function is generally called from within a Promise handler, so any
701     // exception thrown by this method will be swallowed and most likely
702     // ignored by the Promise machinery.
703     if ($mozAsyncTestDone) {
704         reportFailure("$DONE() already called");
705         return;
706     }
707     $mozAsyncTestDone = true;
709     if (failure)
710         reportFailure(failure);
711     else
712         reportCompare(0, 0);
714     if (typeof jsTestDriverEnd === "function") {
715         gDelayTestDriverEnd = false;
716         jsTestDriverEnd();
717     }
720 // Some tests in test262 leave promise rejections unhandled.
721 if ("ignoreUnhandledRejections" in this) {
722   ignoreUnhandledRejections();