blob: 3307b6ca5cfeb95ab0e542053bea0ac6660c0467 [file] [log] [blame]
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
Debug = debug.Debug
let events = 0;
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Exception) return;
events++;
}
async function thrower() {
throw "a"; // Exception a
}
var reject = () => Promise.reject("b"); // Exception b
async function awaitReturn() { await 1; return; }
async function scalar() { return 1; }
function nothing() { return 1; }
function rejectConstructor() {
return new Promise((resolve, reject) => reject("c")); // Exception c
}
async function argThrower(x = (() => { throw "d"; })()) { } // Exception d
async function awaitThrow() {
await undefined;
throw "e"; // Exception e
}
function constructorThrow() {
return new Promise((resolve, reject) =>
Promise.resolve().then(() =>
reject("f") // Exception f
)
);
}
function suppressThrow() {
return thrower();
}
async function caught(producer) {
try {
await producer();
} catch (e) {
}
}
async function uncaught(producer) {
await producer();
}
async function indirectUncaught(producer) {
await uncaught(producer);
}
async function indirectCaught(producer) {
try {
await uncaught(producer);
} catch (e) {
}
}
function dotCatch(producer) {
Promise.resolve(producer()).catch(() => {});
}
function indirectReturnDotCatch(producer) {
(async() => producer())().catch(() => {});
}
function indirectAwaitDotCatch(producer) {
(async() => await producer())().catch(() => {});
}
function nestedDotCatch(producer) {
Promise.resolve(producer()).then().catch(() => {});
}
async function indirectAwaitCatch(producer) {
try {
await (() => producer())();
} catch (e) {
}
}
function switchCatch(producer) {
let resolve;
let promise = new Promise(r => resolve = r);
async function localCaught() {
try {
await promise; // force switching to localUncaught and back
await producer();
} catch (e) { }
}
async function localUncaught() {
await undefined;
resolve();
}
localCaught();
localUncaught();
}
function switchDotCatch(producer) {
let resolve;
let promise = new Promise(r => resolve = r);
async function localCaught() {
await promise; // force switching to localUncaught and back
await producer();
}
async function localUncaught() {
await undefined;
resolve();
}
localCaught().catch(() => {});
localUncaught();
}
let catches = [caught,
indirectCaught,
indirectAwaitCatch,
switchCatch,
switchDotCatch];
let noncatches = [uncaught, indirectUncaught];
let lateCatches = [dotCatch,
indirectReturnDotCatch,
indirectAwaitDotCatch,
nestedDotCatch];
let throws = [thrower, reject, argThrower, suppressThrow];
let nonthrows = [awaitReturn, scalar, nothing];
let lateThrows = [awaitThrow, constructorThrow];
let uncatchable = [rejectConstructor];
let cases = [];
for (let producer of throws.concat(lateThrows)) {
for (let consumer of catches) {
cases.push({ producer, consumer, expectedEvents: 1, caught: true });
cases.push({ producer, consumer, expectedEvents: 0, caught: false });
}
}
for (let producer of throws.concat(lateThrows)) {
for (let consumer of noncatches) {
cases.push({ producer, consumer, expectedEvents: 1, caught: true });
cases.push({ producer, consumer, expectedEvents: 1, caught: false });
}
}
for (let producer of nonthrows) {
for (let consumer of catches.concat(noncatches, lateCatches)) {
cases.push({ producer, consumer, expectedEvents: 0, caught: true });
cases.push({ producer, consumer, expectedEvents: 0, caught: false });
}
}
for (let producer of uncatchable) {
for (let consumer of catches.concat(noncatches, lateCatches)) {
cases.push({ producer, consumer, expectedEvents: 1, caught: true });
cases.push({ producer, consumer, expectedEvents: 1, caught: false });
}
}
for (let producer of lateThrows) {
for (let consumer of lateCatches) {
cases.push({ producer, consumer, expectedEvents: 1, caught: true });
cases.push({ producer, consumer, expectedEvents: 0, caught: false });
}
}
for (let producer of throws) {
for (let consumer of lateCatches) {
cases.push({ producer, consumer, expectedEvents: 1, caught: true });
cases.push({ producer, consumer, expectedEvents: 1, caught: false });
}
}
function runPart(n) {
let subcases = cases.slice(n * cases.length / 4,
((n + 1) * cases.length) / 4);
for (let {producer, consumer, expectedEvents, caught} of subcases) {
Debug.setListener(listener);
if (caught) {
Debug.setBreakOnException();
} else {
Debug.setBreakOnUncaughtException();
}
events = 0;
consumer(producer);
%PerformMicrotaskCheckpoint();
Debug.setListener(null);
if (caught) {
Debug.clearBreakOnException();
} else {
Debug.clearBreakOnUncaughtException();
}
if (expectedEvents != events) {
%AbortJS(`producer ${producer} consumer ${consumer} expectedEvents ` +
`${expectedEvents} caught ${caught} events ${events}`);
}
}
}