Commit 1335b1ec authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[d8] Exit with error code upon unhandled promise rejection

With this CL d8 exits with an error code if there is an unhandled
promise rejection, e.g. due tue a failed assertion in a promise. Up
until now these assertions were just ignored.

Bug: v8:10556
Change-Id: I25f20e4be45a2de130562deb15f6a144f0ac976f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2238569Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68503}
parent 3fd18f12
......@@ -12,6 +12,7 @@
#include <iomanip>
#include <iterator>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>
......@@ -464,6 +465,7 @@ std::map<v8::Isolate*, int> Shell::isolate_running_streaming_tasks_;
base::LazyMutex Shell::cached_code_mutex_;
std::map<std::string, std::unique_ptr<ScriptCompiler::CachedData>>
Shell::cached_code_map_;
std::atomic<int> Shell::unhandled_promise_rejections_{0};
Global<Context> Shell::evaluation_context_;
ArrayBuffer::Allocator* Shell::array_buffer_allocator;
......@@ -665,7 +667,10 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
StoreInCodeCache(isolate, source, cached_data);
delete cached_data;
}
if (process_message_queue && !EmptyMessageQueues(isolate)) success = false;
if (process_message_queue) {
if (!EmptyMessageQueues(isolate)) success = false;
if (!HandleUnhandledPromiseRejections(isolate)) success = false;
}
data->realm_current_ = data->realm_switch_;
}
Local<Value> result;
......@@ -1161,6 +1166,45 @@ MaybeLocal<Context> PerIsolateData::GetTimeoutContext() {
return result;
}
void PerIsolateData::RemoveUnhandledPromise(Local<Promise> promise) {
// Remove handled promises from the list
DCHECK_EQ(promise->GetIsolate(), isolate_);
for (auto it = unhandled_promises_.begin(); it != unhandled_promises_.end();
++it) {
v8::Local<v8::Promise> unhandled_promise = std::get<0>(*it).Get(isolate_);
if (unhandled_promise == promise) {
unhandled_promises_.erase(it--);
}
}
}
void PerIsolateData::AddUnhandledPromise(Local<Promise> promise,
Local<Message> message,
Local<Value> exception) {
DCHECK_EQ(promise->GetIsolate(), isolate_);
unhandled_promises_.push_back(
std::make_tuple(v8::Global<v8::Promise>(isolate_, promise),
v8::Global<v8::Message>(isolate_, message),
v8::Global<v8::Value>(isolate_, exception)));
}
size_t PerIsolateData::GetUnhandledPromiseCount() {
return unhandled_promises_.size();
}
int PerIsolateData::HandleUnhandledPromiseRejections() {
int unhandled_promises_count = 0;
v8::HandleScope scope(isolate_);
for (auto& tuple : unhandled_promises_) {
Local<v8::Message> message = std::get<1>(tuple).Get(isolate_);
Local<v8::Value> value = std::get<2>(tuple).Get(isolate_);
Shell::ReportException(isolate_, message, value);
unhandled_promises_count++;
}
unhandled_promises_.clear();
return unhandled_promises_count;
}
PerIsolateData::RealmScope::RealmScope(PerIsolateData* data) : data_(data) {
data_->realm_count_ = 1;
data_->realm_current_ = 0;
......@@ -2159,8 +2203,50 @@ static void PrintMessageCallback(Local<Message> message, Local<Value> error) {
printf("%s:%i: %s\n", filename_string, linenum, msg_string);
}
void Shell::PromiseRejectCallback(v8::PromiseRejectMessage data) {
if (options.ignore_unhandled_promises) return;
if (data.GetEvent() == v8::kPromiseRejectAfterResolved ||
data.GetEvent() == v8::kPromiseResolveAfterResolved) {
// Ignore reject/resolve after resolved.
return;
}
v8::Local<v8::Promise> promise = data.GetPromise();
v8::Isolate* isolate = promise->GetIsolate();
PerIsolateData* isolate_data = PerIsolateData::Get(isolate);
if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) {
isolate_data->RemoveUnhandledPromise(promise);
return;
}
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
bool capture_exceptions =
i_isolate->get_capture_stack_trace_for_uncaught_exceptions();
isolate->SetCaptureStackTraceForUncaughtExceptions(true);
v8::Local<Value> exception = data.GetValue();
v8::Local<Message> message;
// Assume that all objects are stack-traces.
if (exception->IsObject()) {
message = v8::Exception::CreateMessage(isolate, exception);
}
if (!exception->IsNativeError() &&
(message.IsEmpty() || message->GetStackTrace().IsEmpty())) {
// If there is no real Error object, manually throw and catch a stack trace.
v8::TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
isolate->ThrowException(v8::Exception::Error(
v8::String::NewFromUtf8Literal(isolate, "Unhandled Promise.")));
message = try_catch.Message();
exception = try_catch.Exception();
}
isolate->SetCaptureStackTraceForUncaughtExceptions(capture_exceptions);
isolate_data->AddUnhandledPromise(promise, message, exception);
}
void Shell::Initialize(Isolate* isolate, D8Console* console,
bool isOnMainThread) {
isolate->SetPromiseRejectCallback(PromiseRejectCallback);
if (isOnMainThread) {
// Set up counters
if (i::FLAG_map_counters[0] != '\0') {
......@@ -2968,9 +3054,7 @@ void Worker::ExecuteInThread() {
in_semaphore_.Wait();
std::unique_ptr<SerializationData> data;
if (!in_queue_.Dequeue(&data)) continue;
if (!data) {
break;
}
if (!data) break;
v8::TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
HandleScope scope(isolate);
......@@ -2983,6 +3067,7 @@ void Worker::ExecuteInThread() {
USE(result);
}
}
// TODO(cbruni): Check for unhandled promises here.
}
}
}
......@@ -3083,6 +3168,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
// Ignore any -f flags for compatibility with other stand-alone
// JavaScript engines.
continue;
} else if (strcmp(argv[i], "--ignore-unhandled-promises") == 0) {
options.ignore_unhandled_promises = true;
argv[i] = nullptr;
} else if (strcmp(argv[i], "--isolate") == 0) {
options.num_isolates++;
} else if (strcmp(argv[i], "--throws") == 0) {
......@@ -3240,6 +3328,7 @@ int Shell::RunMain(Isolate* isolate, bool last_run) {
PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
if (!options.isolate_sources[0].Execute(isolate)) success = false;
if (!CompleteMessageLoop(isolate)) success = false;
if (!HandleUnhandledPromiseRejections(isolate)) success = false;
}
if (!use_existing_context) {
DisposeModuleEmbedderData(context);
......@@ -3267,6 +3356,11 @@ int Shell::RunMain(Isolate* isolate, bool last_run) {
}
}
WaitForRunningWorkers();
if (Shell::unhandled_promise_rejections_.load() > 0) {
printf("%i pending unhandled Promise rejection(s) detected.\n",
Shell::unhandled_promise_rejections_.load());
success = false;
}
// In order to finish successfully, success must be != expected_to_throw.
return success == Shell::options.expected_to_throw ? 1 : 0;
}
......@@ -3389,6 +3483,15 @@ void Shell::PostBlockingBackgroundTask(std::unique_ptr<Task> task) {
g_default_platform->CallBlockingTaskOnWorkerThread(std::move(task));
}
bool Shell::HandleUnhandledPromiseRejections(Isolate* isolate) {
if (options.ignore_unhandled_promises) return true;
PerIsolateData* data = PerIsolateData::Get(isolate);
int count = data->HandleUnhandledPromiseRejections();
Shell::unhandled_promise_rejections_.store(
Shell::unhandled_promise_rejections_.load() + count);
return count == 0;
}
class Serializer : public ValueSerializer::Delegate {
public:
explicit Serializer(Isolate* isolate)
......
......@@ -234,6 +234,12 @@ class PerIsolateData {
AsyncHooks* GetAsyncHooks() { return async_hooks_wrapper_; }
void RemoveUnhandledPromise(Local<Promise> promise);
void AddUnhandledPromise(Local<Promise> promise, Local<Message> message,
Local<Value> exception);
int HandleUnhandledPromiseRejections();
size_t GetUnhandledPromiseCount();
private:
friend class Shell;
friend class RealmScope;
......@@ -245,6 +251,8 @@ class PerIsolateData {
Global<Value> realm_shared_;
std::queue<Global<Function>> set_timeout_callbacks_;
std::queue<Global<Context>> set_timeout_contexts_;
std::vector<std::tuple<Global<Promise>, Global<Message>, Global<Value>>>
unhandled_promises_;
AsyncHooks* async_hooks_wrapper_;
int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args,
......@@ -272,6 +280,7 @@ class ShellOptions {
bool interactive_shell = false;
bool test_shell = false;
bool expected_to_throw = false;
bool ignore_unhandled_promises = false;
bool mock_arraybuffer_allocator = false;
size_t mock_arraybuffer_allocator_limit = 0;
bool multi_mapped_mock_allocator = false;
......@@ -332,6 +341,8 @@ class Shell : public i::AllStatic {
static bool EmptyMessageQueues(Isolate* isolate);
static bool CompleteMessageLoop(Isolate* isolate);
static bool HandleUnhandledPromiseRejections(Isolate* isolate);
static void PostForegroundTask(Isolate* isolate, std::unique_ptr<Task> task);
static void PostBlockingBackgroundTask(std::unique_ptr<Task> task);
......@@ -472,6 +483,8 @@ class Shell : public i::AllStatic {
static void Initialize(Isolate* isolate, D8Console* console,
bool isOnMainThread = true);
static void PromiseRejectCallback(v8::PromiseRejectMessage reject_message);
private:
static Global<Context> evaluation_context_;
static base::OnceType quit_once_;
......@@ -521,6 +534,7 @@ class Shell : public i::AllStatic {
static base::LazyMutex cached_code_mutex_;
static std::map<std::string, std::unique_ptr<ScriptCompiler::CachedData>>
cached_code_map_;
static std::atomic<int> unhandled_promise_rejections_;
};
} // namespace v8
......
......@@ -2516,6 +2516,10 @@ void Isolate::SetCaptureStackTraceForUncaughtExceptions(
stack_trace_for_uncaught_exceptions_options_ = options;
}
bool Isolate::get_capture_stack_trace_for_uncaught_exceptions() const {
return capture_stack_trace_for_uncaught_exceptions_;
}
void Isolate::SetAbortOnUncaughtExceptionCallback(
v8::Isolate::AbortOnUncaughtExceptionCallback callback) {
abort_on_uncaught_exception_callback_ = callback;
......
......@@ -733,6 +733,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void SetCaptureStackTraceForUncaughtExceptions(
bool capture, int frame_limit, StackTrace::StackTraceOptions options);
bool get_capture_stack_trace_for_uncaught_exceptions() const;
void SetAbortOnUncaughtExceptionCallback(
v8::Isolate::AbortOnUncaughtExceptionCallback callback);
......
......@@ -1448,7 +1448,6 @@ DEFINE_BOOL(dump_counters, false, "Dump counters on exit")
DEFINE_BOOL(dump_counters_nvp, false,
"Dump counters as name-value pairs on exit")
DEFINE_BOOL(use_external_strings, false, "Use external strings for source code")
DEFINE_STRING(map_counters, "", "Map counters to a file")
DEFINE_BOOL(mock_arraybuffer_allocator, false,
"Use a mock ArrayBuffer allocator for testing.")
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and a
// Promise p3 created by Promise.all has no catch handler, and is rejected
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-promise-any
// Flags: --harmony-promise-any --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and a
// Promise p3 created by Promise.any has no catch handler, and is rejected
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and a
// Promise p3 created by Promise.race has no catch handler, and is rejected
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we listen to all exceptions and
// there is a catch handler for the exception thrown in a Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// there is only a default reject handler for the to-be-rejected Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test exercises code paths for catching exceptions in the promise constructor
// in conjunction with deoptimization.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// the Promise is rejected in the Promise constructor.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we listen to all exceptions and
// there is a catch handler for the to-be-rejected Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the to-be-rejected Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// there is no catch handler for the to-be-rejected Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// there is only a default reject handler for the to-be-rejected Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// an exception is thrown in the Promise constructor.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we listen to all exceptions and
// there is no catch handler for the exception thrown in a Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// there is a catch handler for the exception thrown in a Promise.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// the Promise is rejected within a try-catch in the Promise constructor.
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Test debug events when we only listen to uncaught exceptions and
// an exception is thrown in the Promise constructor, but caught in an
......
......@@ -2,6 +2,8 @@
// 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 listenerComplete = false;
......
......@@ -2,6 +2,8 @@
// 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
var exception = null;
......
......@@ -2,6 +2,8 @@
// 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;
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Files: test/debugger/debug/es8/async-debug-caught-exception-cases.js
runPart(0);
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Files: test/debugger/debug/es8/async-debug-caught-exception-cases.js
runPart(1);
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Files: test/debugger/debug/es8/async-debug-caught-exception-cases.js
runPart(2);
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
// Files: test/debugger/debug/es8/async-debug-caught-exception-cases.js
runPart(3);
......@@ -2,6 +2,8 @@
// 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
var exception = null;
......
......@@ -2,6 +2,7 @@
// 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
function overflow() {
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
var Debug = debug.Debug;
var expected = ["debugger;", "var x = y;", "debugger;", "var x = y;"];
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
var Debug = debug.Debug;
var expected = ["debugger;",
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
var Debug = debug.Debug;
var expected = ["debugger;", "var x = y;", "debugger;", "var x = y;"];
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --enable-inspector
// Flags: --allow-natives-syntax --enable-inspector --ignore-unhandled-promises
const Debug = debug.Debug;
Debug.setListener(() => {});
......
......@@ -4,6 +4,6 @@
//
// MODULE
//
// Flags: --harmony-top-level-await
// Flags: --harmony-top-level-await --ignore-unhandled-promises
import "modules-skip-1-top-level-await-fail.mjs"
......@@ -4,6 +4,6 @@
//
// MODULE
//
// Flags: --harmony-top-level-await
// Flags: --harmony-top-level-await --ignore-unhandled-promises
import "modules-skip-2-top-level-await-fail.mjs"
// Copyright 2020 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.
load('test/mjsunit/mjsunit.js');
Promise.resolve().then(() => {
assertEquals('foo', 'bar');
});
undefined:0: Failure: expected <"foo"> found <"bar">
Stack: MjsUnitAssertionError
at assertEquals test/mjsunit/mjsunit.js {NUMBER}:{NUMBER}
at *%(basename)s 8:3
MjsUnitAssertionError
at assertEquals test/mjsunit/mjsunit.js {NUMBER}:{NUMBER}
at *%(basename)s 8:3
1 pending unhandled Promise rejection(s) detected.
......@@ -43,8 +43,8 @@
var value;
function foo(x) { return new Promise((resolve, reject) => reject(x)); }
%PrepareFunctionForOptimization(foo);
foo(1);
foo(1);
foo(1).catch(() => { /* ignore */ });
foo(1).catch(() => { /* ignore */ });
%OptimizeFunctionOnNextCall(foo);
foo(1).catch(v => value = v);
setTimeout(_ => assertEquals(1, value));
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --ignore-unhandled-promises
// We have to patch mjsunit because normal assertion failures just throw
// exceptions which are swallowed in a then clause.
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --always-opt
// Flags: --always-opt --ignore-unhandled-promises
var __caught = 0;
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --ignore-unhandled-promises
async function f() {
var a = [...new Int8Array([, ...new Uint8Array(65536)])];
......
......@@ -3,7 +3,7 @@
// found in the LICENSE file.
// A non-callable reject function throws eagerly
var log = [];
var p = new Promise(function(resolve, reject) {
log.push("resolve");
resolve();
......
......@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --ignore-unhandled-promises
// Make sure we don't rely on functions patchable by monkeys.
var call = Function.prototype.call.call.bind(Function.prototype.call)
......
......@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --ignore-unhandled-promises
// Check for correct interleaving of Promises and async/await
(function () {
const iterations = 10;
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --ignore-unhandled-promises
'use strict';
......
......@@ -9,21 +9,24 @@ var ran = false;
var x = {
get toString() { return undefined; }
};
import(x);
import(x).then(assertUnreachable,
(e) => assertInstanceof(e, TypeError));
var x = {
toString() {
throw new Error('42 is the answer');
}
};
import(x);
import(x).then(assertUnreachable,
(e) => assertEquals(e.message, '42 is the answer'))
var x = {
get toString() {
throw new Error('42 is the answer');
}
};
import(x);
import(x).then(assertUnreachable,
(e) => assertEquals(e.message, '42 is the answer'))
async function test1() {
try {
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-dynamic-import --harmony-top-level-await
// Flags: --harmony-dynamic-import --harmony-top-level-await --ignore-unhandled-promises
let ran = false;
let m = import('modules-skip-2.mjs');
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-dynamic-import --harmony-top-level-await
// Flags: --harmony-dynamic-import --harmony-top-level-await --ignore-unhandled-promises
let ran = false;
try {
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-dynamic-import --harmony-top-level-await
// Flags: --harmony-dynamic-import --harmony-top-level-await --ignore-unhandled-promises
let ran = false;
try {
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --harmony-promise-all-settled
// Flags: --allow-natives-syntax --harmony-promise-all-settled --ignore-unhandled-promises
class MyError extends Error {}
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --ignore-unhandled-promises
load('test/mjsunit/test-async.js');
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
import("./modules-skip-reset1.js").then(() => %AbortJS("must throw"));
import("./modules-skip-reset3.js").then(() => %AbortJS("must throw"));
import("./modules-skip-reset1.js").then(
() => assertUnreachable("must throw"), () => {});
import("./modules-skip-reset3.js").then(
() => assertUnreachable("must throw"), () => {});
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --ignore-unhandled-promises
let count = 0;
class MyPromise extends Promise {
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --harmony-dynamic-import
// Flags: --harmony-dynamic-import --ignore-unhandled-promises
__v_1 = {
};
......@@ -10,7 +10,7 @@ function __f_8() {
try {
__f_8();
} catch(e) {
import(__v_1);
import(__v_1).then();
}
}
__f_8();
......@@ -4,5 +4,9 @@
// Flags: --harmony-dynamic-import
eval(`import('modules-skip-2.js');`);
eval(`eval(import('modules-skip-2.js'));`);
eval(`import('modules-skip-2.js');`).then(
assertUnreachable,
() => { /* ignore */});
eval(`eval(import('modules-skip-2.js'));`).then(
assertUnreachable,
() => { /* ignore */});
......@@ -23,4 +23,6 @@ let myIterable = {
}
};
MyPromise.race(myIterable);
MyPromise.race(myIterable).then(
assertUnreachable,
(e) => { assertEquals(e, "then throws")});
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --expose-async-hooks
// Flags: --allow-natives-syntax --expose-async-hooks --ignore-unhandled-promises
async function* foo() {
await 1;
......
......@@ -3,4 +3,5 @@
// found in the LICENSE file.
Promise.resolve = function() { return {}; };
Promise.race([function() {}]);
Promise.race([function() {}]).then(
() => assertUnreachable(), () => { /* ignore */})
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --ignore-unhandled-promises
(async function test() {
try {
import('does_not_exist.mjs');
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --stack-size=50
// Flags: --allow-natives-syntax --stack-size=50 --ignore-unhandled-promises
let i = 0;
function f() {
......
......@@ -14,4 +14,5 @@ binary.emit_bytes([kUnknownSectionCode, 2, 1, 0]);
binary.emit_bytes([kUnknownSectionCode, 2, 1, 0]);
binary.emit_bytes([ kExprEnd]);
let buffer = binary.trunc_buffer();
WebAssembly.compile(buffer);
WebAssembly.compile(buffer).then(
() => assertUnreachable(), () => {/* ignore */});
......@@ -11,4 +11,4 @@ builder.addFunction(undefined, kSig_v_i) .addBodyWithEnd([
// Intentionally add just a numeric opcode prefix without the index byte.
const b = builder.toBuffer();
WebAssembly.compile(b);
WebAssembly.compile(b).then(() => assertUnreachable(), () => { /* ignore */ })
......@@ -9,7 +9,9 @@ Object.defineProperty(v11.__proto__, 0, {
},
set: function() {
try {
WebAssembly.instantiate();
WebAssembly.instantiate().then(
() => assertUnreachable(),
() => { /* ignore */ });
v11[0] = 0;
} catch (e) {
assertTrue(e instanceof RangeError);
......
......@@ -16,4 +16,5 @@ for (let i = 0; i < 100; ++i) {
chain = chain.then(() => WebAssembly.instantiate(buffer));
}
chain.then(({module, instance}) => instance.exports.fun1155())
.then(res => print('Result of executing fun1155: ' + res));
.then(res => print('Result of executing fun1155: ' + res))
.catch(() => {/* ignore */});
......@@ -8,4 +8,4 @@ var {proxy, revoke} = Proxy.revocable({}, {});
revoke();
let builder = new WasmModuleBuilder();
builder.addImport('m', 'q', kSig_v_v);
WebAssembly.instantiate(builder.toModule(), proxy);
WebAssembly.instantiate(builder.toModule(), proxy).catch(error => {});
......@@ -218,6 +218,7 @@ class TestCase(testcase.D8TestCase):
def _get_suite_flags(self):
return (
["--ignore-unhandled-promises"] +
(["--throws"] if "negative" in self.test_record else []) +
(["--allow-natives-syntax"]
if "detachArrayBuffer.js" in self.test_record.get("includes", [])
......
......@@ -21,7 +21,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --harmony
// Flags: --harmony --ignore-unhandled-promises
'use strict';
description('Test Promise.prototype.catch.');
......
......@@ -21,7 +21,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --harmony
// Flags: --harmony --ignore-unhandled-promises
'use strict';
description('Test Promise.all');
......
......@@ -21,7 +21,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --harmony
// Flags: --harmony --ignore-unhandled-promises
'use strict';
description('Test Promise.race');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment