[builtins] add exception predictions for AsyncFromSyncIterator methods
Add a mechanic to set these Builtin exception predictions per-Isolate rather than per-Context in the Bootstrapper. Also add Debugger tests which would fail without these prediction modes set. Does not yet test for AsyncFromSyncIteratorPrototypeReturn, as this requires AsyncGenerators and `yield*` to be hit. BUG=chromium:691875 R=yangguo@chromium.org, jgruber@chromium.org, gsathya@chromium.org Change-Id: Ic2d2aba3870cce2f7321080f4278875edf253c76 Reviewed-on: https://chromium-review.googlesource.com/451967 Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Caitlin Potter <caitp@igalia.com> Cr-Commit-Position: refs/heads/master@{#43742}
This commit is contained in:
parent
b2efe57cdf
commit
326d4f436d
@ -167,6 +167,12 @@ void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
|
||||
for (int i = 0; i < builtin_count; i++) {
|
||||
Code::cast(builtins_[i])->set_builtin_index(i);
|
||||
}
|
||||
|
||||
#define EXCEPTION_PREDICTION(Name, type) \
|
||||
Code::cast(builtins_[k##Name])->set_##type(true);
|
||||
|
||||
BUILTIN_EXCEPTION_PREDICTION_LIST(EXCEPTION_PREDICTION)
|
||||
#undef EXCEPTION_PREDICTION
|
||||
}
|
||||
|
||||
// Mark as initialized.
|
||||
|
@ -854,6 +854,11 @@ class Isolate;
|
||||
/* proposal-async-iteration/#sec-async-iterator-value-unwrap-functions */ \
|
||||
TFJ(AsyncIteratorValueUnwrap, 1)
|
||||
|
||||
#define BUILTIN_EXCEPTION_PREDICTION_LIST(V) \
|
||||
V(AsyncFromSyncIteratorPrototypeNext, is_promise_rejection) \
|
||||
V(AsyncFromSyncIteratorPrototypeReturn, is_promise_rejection) \
|
||||
V(AsyncFromSyncIteratorPrototypeThrow, is_promise_rejection)
|
||||
|
||||
#define IGNORE_BUILTIN(...)
|
||||
|
||||
#define BUILTIN_LIST_ALL(V) BUILTIN_LIST(V, V, V, V, V, V, V)
|
||||
|
@ -0,0 +1,57 @@
|
||||
Checks that async chains for for-await-of are correct.
|
||||
|
||||
Running test: testBasic
|
||||
Debugger (test.js:10:2)
|
||||
Basic (test.js:48:4)
|
||||
-- async function (test.js:46:20)--
|
||||
Basic (test.js:46:20)
|
||||
(anonymous) (testBasic.js:0:0)
|
||||
|
||||
|
||||
Running test: testUncaughtReject
|
||||
Debugger (test.js:10:2)
|
||||
-- async function (test.js:52:29)--
|
||||
UncaughtReject (test.js:52:29)
|
||||
(anonymous) (testUncaughtReject.js:0:0)
|
||||
|
||||
|
||||
Running test: testUncaughtThrow
|
||||
Debugger (test.js:10:2)
|
||||
-- async function (test.js:61:28)--
|
||||
UncaughtThrow (test.js:61:28)
|
||||
(anonymous) (testUncaughtThrow.js:0:0)
|
||||
|
||||
|
||||
Running test: testCaughtReject
|
||||
Debugger (test.js:10:2)
|
||||
CaughtReject (test.js:76:4)
|
||||
-- async function (test.js:70:27)--
|
||||
CaughtReject (test.js:70:27)
|
||||
(anonymous) (testCaughtReject.js:0:0)
|
||||
|
||||
|
||||
Running test: testCaughtThrow
|
||||
Debugger (test.js:10:2)
|
||||
CaughtThrow (test.js:86:4)
|
||||
-- async function (test.js:80:26)--
|
||||
CaughtThrow (test.js:80:26)
|
||||
(anonymous) (testCaughtThrow.js:0:0)
|
||||
|
||||
|
||||
Running test: testUncaughtRejectOnBreak
|
||||
|
||||
Running test: testUncaughtThrowOnBreak
|
||||
Debugger (test.js:10:2)
|
||||
-- async function (test.js:99:35)--
|
||||
UncaughtThrowOnBreak (test.js:99:35)
|
||||
(anonymous) (testUncaughtThrowOnBreak.js:0:0)
|
||||
|
||||
|
||||
Running test: testCaughtRejectOnBreak
|
||||
|
||||
Running test: testCaughtThrowOnBreak
|
||||
Debugger (test.js:10:2)
|
||||
CaughtThrowOnBreak (test.js:124:4)
|
||||
-- async function (test.js:118:33)--
|
||||
CaughtThrowOnBreak (test.js:118:33)
|
||||
(anonymous) (testCaughtThrowOnBreak.js:0:0)
|
164
test/inspector/debugger/async-for-await-of-promise-stack.js
Normal file
164
test/inspector/debugger/async-for-await-of-promise-stack.js
Normal file
@ -0,0 +1,164 @@
|
||||
// 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: --harmony-async-iteration
|
||||
|
||||
InspectorTest.log('Checks that async chains for for-await-of are correct.');
|
||||
|
||||
InspectorTest.addScript(`
|
||||
|
||||
function Debugger(value) {
|
||||
debugger;
|
||||
}
|
||||
|
||||
function Reject(reason) {
|
||||
var reject;
|
||||
var promise = new Promise(function(resolvefn, rejectfn) {
|
||||
reject = rejectfn;
|
||||
});
|
||||
setTimeout(reject.bind(undefined, reason), 0);
|
||||
return promise;
|
||||
}
|
||||
|
||||
function Throw(reason) {
|
||||
return {
|
||||
get then() { throw reason; }
|
||||
};
|
||||
}
|
||||
|
||||
function ThrowOnReturn(items) {
|
||||
var it = items[Symbol.iterator]();
|
||||
return {
|
||||
[Symbol.iterator]() { return this; },
|
||||
next(v) { return it.next(v); },
|
||||
return(v) { throw new Error("boop"); }
|
||||
};
|
||||
}
|
||||
|
||||
function RejectOnReturn(items) {
|
||||
var it = items[Symbol.iterator]();
|
||||
return {
|
||||
[Symbol.iterator]() { return this; },
|
||||
next(v) { return it.next(v); },
|
||||
return(v) { return Reject(new Error("boop")); }
|
||||
};
|
||||
}
|
||||
|
||||
async function Basic() {
|
||||
for await (let x of ["a"]) {
|
||||
Debugger();
|
||||
}
|
||||
}
|
||||
|
||||
async function UncaughtReject() {
|
||||
async function loop() {
|
||||
for await (let x of [Reject(new Error("boop"))]) {
|
||||
Debugger();
|
||||
}
|
||||
}
|
||||
return loop().catch(Debugger);
|
||||
}
|
||||
|
||||
async function UncaughtThrow() {
|
||||
async function loop() {
|
||||
for await (let x of [Throw(new Error("boop"))]) {
|
||||
Debugger();
|
||||
}
|
||||
}
|
||||
return loop().catch(Debugger);
|
||||
}
|
||||
|
||||
async function CaughtReject() {
|
||||
try {
|
||||
for await (let x of [Reject(new Error("boop"))]) {
|
||||
Debugger(x);
|
||||
}
|
||||
} catch (e) {
|
||||
Debugger(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function CaughtThrow() {
|
||||
try {
|
||||
for await (let x of [Throw(new Error("boop"))]) {
|
||||
Debugger(x);
|
||||
}
|
||||
} catch (e) {
|
||||
Debugger(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function UncaughtRejectOnBreak() {
|
||||
async function loop() {
|
||||
for await (let x of RejectOnReturn(["0", "1"])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return loop().catch(Debugger);
|
||||
}
|
||||
|
||||
async function UncaughtThrowOnBreak() {
|
||||
async function loop() {
|
||||
for await (let x of ThrowOnReturn(["0", "1"])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return loop().catch(Debugger);
|
||||
}
|
||||
|
||||
async function CaughtRejectOnBreak() {
|
||||
try {
|
||||
for await (let x of RejectOnReturn(["0", "1"])) {
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
Debugger(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function CaughtThrowOnBreak() {
|
||||
try {
|
||||
for await (let x of ThrowOnReturn(["0", "1"])) {
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
Debugger(e);
|
||||
}
|
||||
}
|
||||
//# sourceURL=test.js`, 7, 129);
|
||||
|
||||
InspectorTest.setupScriptMap();
|
||||
Protocol.Debugger.onPaused(message => {
|
||||
InspectorTest.logCallFrames(message.params.callFrames);
|
||||
InspectorTest.logAsyncStackTrace(message.params.asyncStackTrace);
|
||||
InspectorTest.log('');
|
||||
Protocol.Debugger.resume();
|
||||
});
|
||||
|
||||
Protocol.Debugger.enable();
|
||||
Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 });
|
||||
var testList = [
|
||||
'Basic',
|
||||
'UncaughtReject',
|
||||
'UncaughtThrow',
|
||||
'CaughtReject',
|
||||
'CaughtThrow',
|
||||
'UncaughtRejectOnBreak',
|
||||
'UncaughtThrowOnBreak',
|
||||
'CaughtRejectOnBreak',
|
||||
'CaughtThrowOnBreak',
|
||||
]
|
||||
InspectorTest.runTestSuite(testList.map(name => {
|
||||
return eval(`
|
||||
(function test${capitalize(name)}(next) {
|
||||
Protocol.Runtime.evaluate({ expression: \`${name}()
|
||||
//# sourceURL=test${capitalize(name)}.js\`, awaitPromise: true})
|
||||
.then(next);
|
||||
})
|
||||
`);
|
||||
}));
|
||||
|
||||
function capitalize(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
Loading…
Reference in New Issue
Block a user