зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1622184 - Add a public method to mark a settled Promise as handled; r=arai
Differential Revision: https://phabricator.services.mozilla.com/D67103 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
527311ae4e
Коммит
e14c3f5ed1
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
#include "js/Promise.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "jspubtd.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
@ -180,6 +181,15 @@ class Promise : public nsISupports, public SupportsWeakPtr<Promise> {
|
|||
// specializations in the .cpp for
|
||||
// the T values we support.
|
||||
|
||||
// Mark a settled promise as already handled so that rejections will not
|
||||
// be reported as unhandled.
|
||||
void SetSettledPromiseIsHandled() {
|
||||
AutoEntryScript aes(mGlobal, "Set settled promise handled");
|
||||
JSContext* cx = aes.cx();
|
||||
JS::RootedObject promiseObj(cx, mPromiseObj);
|
||||
JS::SetSettledPromiseIsHandled(cx, promiseObj);
|
||||
}
|
||||
|
||||
// WebIDL
|
||||
|
||||
nsIGlobalObject* GetParentObject() const { return GetGlobalObject(); }
|
||||
|
|
|
@ -355,6 +355,14 @@ extern JS_PUBLIC_API JS::Value GetPromiseResult(JS::HandleObject promise);
|
|||
*/
|
||||
extern JS_PUBLIC_API bool GetPromiseIsHandled(JS::HandleObject promise);
|
||||
|
||||
/*
|
||||
* Given a settled (i.e. fulfilled or rejected, not pending) promise, sets
|
||||
* |promise.[[PromiseIsHandled]]| to true and removes it from the list of
|
||||
* unhandled rejected promises.
|
||||
*/
|
||||
extern JS_PUBLIC_API void SetSettledPromiseIsHandled(JSContext* cx,
|
||||
JS::HandleObject promise);
|
||||
|
||||
/**
|
||||
* Returns a js::SavedFrame linked list of the stack that lead to the given
|
||||
* Promise's allocation.
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef builtin_Promise_inl_h
|
||||
#define builtin_Promise_inl_h
|
||||
|
||||
#include "js/Promise.h" // JS::PromiseState
|
||||
|
||||
#include "mozilla/Assertions.h" // MOZ_ASSERT
|
||||
|
||||
#include "js/RootingAPI.h" // JS::Handle
|
||||
#include "vm/JSContext.h" // JSContext
|
||||
#include "vm/PromiseObject.h" // js::PromiseObject
|
||||
|
||||
namespace js {
|
||||
|
||||
/**
|
||||
* Given a settled (i.e. fulfilled or rejected, not pending) promise, sets
|
||||
* |promise.[[PromiseIsHandled]]| to true and removes it from the list of
|
||||
* unhandled rejected promises.
|
||||
*
|
||||
* NOTE: If you need to set |promise.[[PromiseIsHandled]]| on a pending promise,
|
||||
* use |PromiseObject::setHandled()| directly.
|
||||
*/
|
||||
inline void SetSettledPromiseIsHandled(
|
||||
JSContext* cx, JS::Handle<PromiseObject*> unwrappedPromise) {
|
||||
MOZ_ASSERT(unwrappedPromise->state() != JS::PromiseState::Pending);
|
||||
unwrappedPromise->setHandled();
|
||||
cx->runtime()->removeUnhandledRejectedPromise(cx, unwrappedPromise);
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // builtin_Promise_inl_h
|
|
@ -14,7 +14,7 @@
|
|||
#include "mozilla/Assertions.h" // MOZ_ASSERT
|
||||
#include "mozilla/Attributes.h" // MOZ_MUST_USE
|
||||
|
||||
#include "js/Promise.h" // JS::{Resolve,Reject}Promise, JS::PromiseState
|
||||
#include "js/Promise.h" // JS::{Resolve,Reject}Promise
|
||||
#include "js/RootingAPI.h" // JS::Rooted, JS::{,Mutable}Handle
|
||||
#include "js/Value.h" // JS::UndefinedHandleValue, JS::Value
|
||||
#include "vm/Compartment.h" // JS::Compartment
|
||||
|
@ -110,21 +110,6 @@ inline MOZ_MUST_USE bool RejectUnwrappedPromiseWithError(
|
|||
return RejectUnwrappedPromiseWithError(cx, &promise, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a settled (i.e. fulfilled or rejected, not pending) promise, sets
|
||||
* |promise.[[PromiseIsHandled]]| to true and removes it from the list of
|
||||
* unhandled rejected promises.
|
||||
*
|
||||
* NOTE: If you need to set |promise.[[PromiseIsHandled]]| on a pending promise,
|
||||
* use |PromiseObject::setHandled()| directly.
|
||||
*/
|
||||
inline void SetSettledPromiseIsHandled(
|
||||
JSContext* cx, JS::Handle<PromiseObject*> unwrappedPromise) {
|
||||
MOZ_ASSERT(unwrappedPromise->state() != JS::PromiseState::Pending);
|
||||
unwrappedPromise->setHandled();
|
||||
cx->runtime()->removeUnhandledRejectedPromise(cx, unwrappedPromise);
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // builtin_streams_MiscellaneousOperations_inl_h
|
||||
|
|
|
@ -33,7 +33,8 @@
|
|||
#include "vm/Realm.h" // JS::Realm
|
||||
#include "vm/StringType.h" // js::PropertyName
|
||||
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::{Reject,Resolve}UnwrappedPromiseWithUndefined, js::SetSettledPromiseIsHandled
|
||||
#include "builtin/Promise-inl.h" // js::SetSettledPromiseIsHandled
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::{Reject,Resolve}UnwrappedPromiseWithUndefined
|
||||
#include "builtin/streams/ReadableStreamReader-inl.h" // js::js::UnwrapReaderFromStream{,NoThrow}
|
||||
#include "vm/Compartment-inl.h" // JS::Compartment::wrap
|
||||
#include "vm/JSContext-inl.h" // JSContext::check
|
||||
|
@ -354,7 +355,7 @@ MOZ_MUST_USE bool js::ReadableStreamErrorInternal(
|
|||
// 3.8.5 ReadableStreamReaderGenericRelease step 6 sets
|
||||
// stream.[[reader]] to undefined.
|
||||
Rooted<JSObject*> closedPromise(cx, unwrappedReader->closedPromise());
|
||||
SetSettledPromiseIsHandled(cx, closedPromise.as<PromiseObject>());
|
||||
js::SetSettledPromiseIsHandled(cx, closedPromise.as<PromiseObject>());
|
||||
|
||||
if (unwrappedStream->mode() == JS::ReadableStreamMode::ExternalSource) {
|
||||
// Make sure we're in the stream's compartment.
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "vm/PromiseObject.h" // js::PromiseObject
|
||||
#include "vm/Runtime.h" // JSRuntime
|
||||
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::SetSettledPromiseIsHandled
|
||||
#include "builtin/Promise-inl.h" // js::SetSettledPromiseIsHandled
|
||||
#include "vm/Compartment-inl.h" // JS::Compartment::wrap, js::UnwrapInternalSlot
|
||||
#include "vm/List-inl.h" // js::StoreNewListInFixedSlot
|
||||
#include "vm/Realm-inl.h" // js::AutoRealm
|
||||
|
@ -113,7 +113,7 @@ MOZ_MUST_USE bool js::ReadableStreamReaderGenericInitialize(
|
|||
}
|
||||
|
||||
// Step c. Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
|
||||
SetSettledPromiseIsHandled(cx, promise);
|
||||
js::SetSettledPromiseIsHandled(cx, promise);
|
||||
}
|
||||
|
||||
if (!promise) {
|
||||
|
@ -211,7 +211,7 @@ MOZ_MUST_USE bool js::ReadableStreamReaderGenericRelease(
|
|||
}
|
||||
|
||||
// Step 5: Set reader.[[closedPromise]].[[PromiseIsHandled]] to true.
|
||||
SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
|
||||
js::SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
|
||||
|
||||
// Step 6: Set reader.[[ownerReadableStream]].[[reader]] to undefined.
|
||||
unwrappedStream->clearReader();
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "vm/JSContext.h" // JSContext
|
||||
#include "vm/PromiseObject.h" // js::PromiseObject
|
||||
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::SetSettledPromiseIsHandled
|
||||
#include "builtin/Promise-inl.h" // js::SetSettledPromiseIsHandled
|
||||
#include "vm/Compartment-inl.h" // JS::Compartment::wrap, js::UnwrapAndTypeCheck{Argument,This}
|
||||
#include "vm/JSObject-inl.h" // js::NewObjectWithClassProto
|
||||
#include "vm/NativeObject-inl.h" // js::ThrowIfNotConstructing
|
||||
|
@ -147,7 +147,7 @@ MOZ_MUST_USE WritableStreamDefaultWriter* js::CreateWritableStreamDefaultWriter(
|
|||
writer->setReadyPromise(promise);
|
||||
|
||||
// Step 7.b: Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
|
||||
SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
|
||||
js::SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
|
||||
|
||||
// Step 7.c: Set this.[[closedPromise]] to a new promise.
|
||||
JSObject* closedPromise = PromiseObject::createSkippingExecutor(cx);
|
||||
|
@ -175,7 +175,7 @@ MOZ_MUST_USE WritableStreamDefaultWriter* js::CreateWritableStreamDefaultWriter(
|
|||
writer->setReadyPromise(promise);
|
||||
|
||||
// Step 9.d: Set this.[[readyPromise]].[[PromiseIsHandled]] to true.
|
||||
SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
|
||||
js::SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
|
||||
|
||||
// Step 9.e: Set this.[[closedPromise]] to a promise rejected with
|
||||
// storedError.
|
||||
|
@ -187,7 +187,7 @@ MOZ_MUST_USE WritableStreamDefaultWriter* js::CreateWritableStreamDefaultWriter(
|
|||
writer->setClosedPromise(promise);
|
||||
|
||||
// Step 9.f: Set this.[[closedPromise]].[[PromiseIsHandled]] to true.
|
||||
SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
|
||||
js::SetSettledPromiseIsHandled(cx, promise.as<PromiseObject>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
#include "vm/List.h" // js::ListObject
|
||||
#include "vm/PromiseObject.h" // js::PromiseObject
|
||||
|
||||
#include "builtin/Promise-inl.h" // js::SetSettledPromiseIsHandled
|
||||
#include "builtin/streams/HandlerFunction-inl.h" // js::NewHandler, js::TargetFromHandler
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::ResolveUnwrappedPromiseWithUndefined, js::RejectUnwrappedPromiseWithError, js::SetSettledPromiseIsHandled
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::ResolveUnwrappedPromiseWithUndefined, js::RejectUnwrappedPromiseWithError
|
||||
#include "builtin/streams/WritableStream-inl.h" // js::UnwrapWriterFromStream
|
||||
#include "builtin/streams/WritableStreamDefaultWriter-inl.h" // js::WritableStreamDefaultWriter::closedPromise
|
||||
#include "vm/Compartment-inl.h" // JS::Compartment::wrap, js::UnwrapAndDowncastObject
|
||||
|
@ -862,7 +863,7 @@ MOZ_MUST_USE bool js::WritableStreamRejectCloseAndClosedPromiseIfNeeded(
|
|||
return false;
|
||||
}
|
||||
|
||||
SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
|
||||
js::SetSettledPromiseIsHandled(cx, unwrappedClosedPromise);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#include "vm/JSContext.h" // JSContext
|
||||
#include "vm/PromiseObject.h" // js::PromiseObject
|
||||
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::ResolveUnwrappedPromiseWithUndefined, js::SetSettledPromiseIsHandled
|
||||
#include "builtin/Promise-inl.h" // js::SetSettledPromiseIsHandled
|
||||
#include "builtin/streams/MiscellaneousOperations-inl.h" // js::ResolveUnwrappedPromiseWithUndefined
|
||||
#include "builtin/streams/WritableStream-inl.h" // js::WritableStream::setCloseRequest
|
||||
#include "builtin/streams/WritableStreamDefaultWriter-inl.h" // js::UnwrapStreamFromWriter
|
||||
#include "vm/Compartment-inl.h" // js::UnwrapAnd{DowncastObject,TypeCheckThis}
|
||||
|
@ -185,7 +186,7 @@ static bool EnsurePromiseRejected(
|
|||
}
|
||||
|
||||
// 4.6.{5,6} step 3: Set writer.[[<field>]].[[PromiseIsHandled]] to true.
|
||||
SetSettledPromiseIsHandled(cx, unwrappedPromise);
|
||||
js::SetSettledPromiseIsHandled(cx, unwrappedPromise);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include "wasm/WasmModule.h"
|
||||
#include "wasm/WasmProcess.h"
|
||||
|
||||
#include "builtin/Promise-inl.h"
|
||||
#include "debugger/DebugAPI-inl.h"
|
||||
#include "vm/Compartment-inl.h"
|
||||
#include "vm/Interpreter-inl.h"
|
||||
|
@ -3828,6 +3829,28 @@ JS_PUBLIC_API bool JS::GetPromiseIsHandled(JS::HandleObject promiseObj) {
|
|||
return !promise->isUnhandled();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void JS::SetSettledPromiseIsHandled(JSContext* cx,
|
||||
JS::HandleObject promise) {
|
||||
AssertHeapIsIdle();
|
||||
CHECK_THREAD(cx);
|
||||
cx->check(promise);
|
||||
|
||||
mozilla::Maybe<AutoRealm> ar;
|
||||
Rooted<PromiseObject*> promiseObj(cx);
|
||||
if (IsWrapper(promise)) {
|
||||
promiseObj = promise->maybeUnwrapAs<PromiseObject>();
|
||||
if (!promiseObj) {
|
||||
ReportAccessDenied(cx);
|
||||
return;
|
||||
}
|
||||
ar.emplace(cx, promiseObj);
|
||||
} else {
|
||||
promiseObj = promise.as<PromiseObject>();
|
||||
}
|
||||
|
||||
js::SetSettledPromiseIsHandled(cx, promiseObj);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API JSObject* JS::GetPromiseAllocationSite(JS::HandleObject promise) {
|
||||
return promise->as<PromiseObject>().allocationSite();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче