diff options
Diffstat (limited to 'js/src/jit-test/tests/promise/job-realm.js')
-rw-r--r-- | js/src/jit-test/tests/promise/job-realm.js | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/promise/job-realm.js b/js/src/jit-test/tests/promise/job-realm.js new file mode 100644 index 0000000000..c50c3d8c2a --- /dev/null +++ b/js/src/jit-test/tests/promise/job-realm.js @@ -0,0 +1,363 @@ +// `debugGetQueuedJobs` is available only in debug build. +if (!getBuildConfiguration().debug) { + quit(); +} + +function testOne(func) { + assertEq(debugGetQueuedJobs().length, 0); + + func(); + + drainJobQueue(); + + assertEq(debugGetQueuedJobs().length, 0); + + if (func.length == 1) { + func({sameCompartmentAs: globalThis}); + + drainJobQueue(); + + assertEq(debugGetQueuedJobs().length, 0); + } +} + +function assertGlobal(obj, expectedGlobal) { + const global = objectGlobal(obj); + if (global) { + assertEq(global === expectedGlobal, true); + } else { + // obj is a wrapper. + // expectedGlobal should be other global than this. + assertEq(expectedGlobal !== globalThis, true); + } +} + +testOne(() => { + // Just creating a promise shouldn't enqueue any jobs. + Promise.resolve(10); + assertEq(debugGetQueuedJobs().length, 0); +}); + +testOne(() => { + // Calling then should create a job for each. + Promise.resolve(10).then(() => {}); + Promise.resolve(10).then(() => {}); + Promise.resolve(10).then(() => {}); + + assertEq(debugGetQueuedJobs().length, 3); +}); + +testOne(() => { + // The reaction job should use the function's realm. + Promise.resolve(10).then(() => {}); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the function's realm. + var g = newGlobal(newGlobalOptions); + g.eval(` +Promise.resolve(10).then(() => {}); +`); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the function's realm. + var g = newGlobal(newGlobalOptions); + g.Promise.resolve(10).then(g.eval(`() => {}`)); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the function's realm. + var g = newGlobal(newGlobalOptions); + g.Promise.resolve(10).then(() => {}); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the bound function's target function's realm. + var g = newGlobal(newGlobalOptions); + g.Promise.resolve(10) + .then(Function.prototype.bind.call(g.eval(`() => {}`), this)); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the bound function's target function's realm. + var g = newGlobal(newGlobalOptions); + g.Promise.resolve(10) + .then(g.Function.prototype.bind.call(() => {}, g)); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the bound function's target function's realm, + // recursively + var g = newGlobal(newGlobalOptions); + g.Promise.resolve(10) + .then( + g.Function.prototype.bind.call( + Function.prototype.bind.call( + g.Function.prototype.bind.call( + () => {}, + g), + this), + g) + ); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the bound function's target function's realm, + // recursively + var g = newGlobal(newGlobalOptions); + Promise.resolve(10) + .then( + g.Function.prototype.bind.call( + Function.prototype.bind.call( + g.Function.prototype.bind.call( + Function.prototype.bind.call( + g.eval(`() => {}`), + this), + g), + this), + g) + ); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the proxy's target function's realm. + var g = newGlobal(newGlobalOptions); + g.handler = () => {}; + g.eval(` +Promise.resolve(10).then(new Proxy(handler, {})); +`); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the proxy's target function's realm. + var g = newGlobal(newGlobalOptions); + g.eval(` +var handler = () => {}; +`); + Promise.resolve(10).then(new Proxy(g.handler, {})); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + + +testOne(newGlobalOptions => { + // The reaction job should use the proxy's target function's realm, + // recursively. + var g = newGlobal(newGlobalOptions); + g.handler = () => {}; + g.outerProxy = Proxy; + g.eval(` +Promise.resolve(10).then( + new outerProxy(new Proxy(new outerProxy(new Proxy(handler, {}), {}), {}), {}) +); +`); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The reaction job should use the proxy's target function's realm, + // recursively. + var g = newGlobal(newGlobalOptions); + g.eval(` +var handler = () => {}; +`); + Promise.resolve(10) + .then(new Proxy(new g.Proxy(new Proxy(g.handler, {}), {}), {})); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(() => { + // The thenable job should use the `then` function's realm. + Promise.resolve({ + then: () => {} + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the `then` function's realm. + var g = newGlobal(newGlobalOptions); + Promise.resolve(g.eval(` +({ + then: () => {} +}); +`)); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the `then` function's realm. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: g.eval(`() => {}`), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the bound function's target function's realm. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: Function.prototype.bind.call(g.eval(`() => {}`), this), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the bound function's target function's realm. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: g.Function.prototype.bind.call(() => {}, g), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the bound function's target function's realm, + // recursively. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: Function.prototype.bind.call( + g.Function.prototype.bind.call( + Function.prototype.bind.call( + g.eval(`() => {}`), + this), + g), + this) + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the bound function's target function's realm, + // recursively. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: g.Function.prototype.bind.call( + Function.prototype.bind.call( + g.Function.prototype.bind.call( + () => {}, + g), + this), + g), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the proxy's target function's realm. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: new Proxy(g.eval(`() => {}`), {}), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the proxy's target function's realm. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: new g.Proxy(() => {}, {}), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the proxy's target function's realm, + // recursively. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: new Proxy(new g.Proxy(new Proxy(g.eval(`() => {}`), {}), {}), {}), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], g); +}); + +testOne(newGlobalOptions => { + // The thenable job should use the proxy's target function's realm, + // recursively. + var g = newGlobal(newGlobalOptions); + Promise.resolve({ + then: new g.Proxy(new Proxy(new g.Proxy(() => {}, {}), {}), {}), + }); + + var jobs = debugGetQueuedJobs(); + assertEq(jobs.length, 1); + assertGlobal(jobs[0], globalThis); +}); + +print("ok"); |