/* -*- 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_h #define builtin_Promise_h #include "js/Promise.h" #include "mozilla/Attributes.h" // MOZ_MUST_USE #include "jsapi.h" // js::CompletionKind #include "jstypes.h" // JS_PUBLIC_API #include "js/CallArgs.h" // JS::CallArgs #include "js/RootingAPI.h" // JS::{,Mutable}Handle #include "js/TypeDecls.h" // JS::HandleObjectVector #include "js/Value.h" // JS::Value struct JS_PUBLIC_API JSContext; class JS_PUBLIC_API JSObject; namespace js { class AsyncFunctionGeneratorObject; class AsyncGeneratorObject; class PromiseObject; // Promise.prototype.then. extern bool Promise_then(JSContext* cx, unsigned argc, JS::Value* vp); // Promise[Symbol.species]. extern bool Promise_static_species(JSContext* cx, unsigned argc, JS::Value* vp); // Promise.resolve. extern bool Promise_static_resolve(JSContext* cx, unsigned argc, JS::Value* vp); /** * Unforgeable version of the JS builtin Promise.all. * * Takes a HandleValueVector of Promise objects and returns a promise that's * resolved with an array of resolution values when all those promises have * been resolved, or rejected with the rejection value of the first rejected * promise. * * Asserts that all objects in the `promises` vector are, maybe wrapped, * instances of `Promise` or a subclass of `Promise`. */ MOZ_MUST_USE JSObject* GetWaitForAllPromise(JSContext* cx, JS::HandleObjectVector promises); /** * Enqueues resolve/reject reactions in the given Promise's reactions lists * as though by calling the original value of Promise.prototype.then, and * without regard to any Promise subclassing used in `promiseObj` itself. */ MOZ_MUST_USE PromiseObject* OriginalPromiseThen( JSContext* cx, JS::Handle promiseObj, JS::Handle onFulfilled, JS::Handle onRejected); enum class UnhandledRejectionBehavior { Ignore, Report }; /** * React to[0] `unwrappedPromise` (which may not be from the current realm) as * if by using a fresh promise created for the provided nullable fulfill/reject * IsCallable objects. * * However, no dependent Promise will be created, and mucking with `Promise`, * `Promise.prototype.then`, and `Promise[Symbol.species]` will not alter this * function's behavior. * * If `unwrappedPromise` rejects and `onRejected_` is null, handling is * determined by `behavior`. If `behavior == Report`, a fresh Promise will be * constructed and rejected on the fly (and thus will be reported as unhandled). * But if `behavior == Ignore`, the rejection is ignored and is not reported as * unhandled. * * Note: Reactions pushed using this function contain a null `promise` field. * That field is only ever used by devtools, which have to treat these reactions * specially. * * 0. The sense of "react" here is the sense of the term as defined by Web IDL: * https://heycam.github.io/webidl/#dfn-perform-steps-once-promise-is-settled */ extern MOZ_MUST_USE bool ReactToUnwrappedPromise( JSContext* cx, JS::Handle unwrappedPromise, JS::Handle onFulfilled_, JS::Handle onRejected_, UnhandledRejectionBehavior behavior); /** * PromiseResolve ( C, x ) * * The abstract operation PromiseResolve, given a constructor and a value, * returns a new promise resolved with that value. */ MOZ_MUST_USE JSObject* PromiseResolve(JSContext* cx, JS::Handle constructor, JS::Handle value); /** * Reject |promise| with the value of the current pending exception. * * |promise| must be from the current realm. Callers must enter the realm of * |promise| if they are not already in it. */ MOZ_MUST_USE bool RejectPromiseWithPendingError( JSContext* cx, JS::Handle promise); /** * Create the promise object which will be used as the return value of an async * function. */ MOZ_MUST_USE PromiseObject* CreatePromiseObjectForAsync(JSContext* cx); /** * Returns true if the given object is a promise created by * either CreatePromiseObjectForAsync function or async generator's method. */ MOZ_MUST_USE bool IsPromiseForAsyncFunctionOrGenerator(JSObject* promise); MOZ_MUST_USE bool AsyncFunctionReturned( JSContext* cx, JS::Handle resultPromise, JS::Handle value); MOZ_MUST_USE bool AsyncFunctionThrown(JSContext* cx, JS::Handle resultPromise, JS::Handle reason); // Start awaiting `value` in an async function (, but doesn't suspend the // async function's execution!). Returns the async function's result promise. MOZ_MUST_USE JSObject* AsyncFunctionAwait( JSContext* cx, JS::Handle genObj, JS::Handle value); // If the await operation can be skipped and the resolution value for `val` can // be acquired, stored the resolved value to `resolved` and `true` to // `*canSkip`. Otherwise, stores `false` to `*canSkip`. MOZ_MUST_USE bool CanSkipAwait(JSContext* cx, JS::Handle val, bool* canSkip); MOZ_MUST_USE bool ExtractAwaitValue(JSContext* cx, JS::Handle val, JS::MutableHandle resolved); MOZ_MUST_USE bool AsyncGeneratorAwait( JSContext* cx, JS::Handle asyncGenObj, JS::Handle value); MOZ_MUST_USE bool AsyncGeneratorResolve( JSContext* cx, JS::Handle asyncGenObj, JS::Handle value, bool done); MOZ_MUST_USE bool AsyncGeneratorReject( JSContext* cx, JS::Handle asyncGenObj, JS::Handle exception); MOZ_MUST_USE bool AsyncGeneratorEnqueue(JSContext* cx, JS::Handle asyncGenVal, CompletionKind completionKind, JS::Handle completionValue, JS::MutableHandle result); bool AsyncFromSyncIteratorMethod(JSContext* cx, JS::CallArgs& args, CompletionKind completionKind); // Callback for describing promise reaction records, for use with // PromiseObject::getReactionRecords. struct PromiseReactionRecordBuilder { // A reaction record created by a call to 'then' or 'catch', with functions to // call on resolution or rejection, and the promise that will be settled // according to the result of calling them. // // Note that resolve, reject, and result may not be same-compartment with cx, // or with the promise we're inspecting. This function presents the values // exactly as they appear in the reaction record. They may also be wrapped or // unwrapped. // // Some reaction records refer to internal resolution or rejection functions // that are not naturally represented as debuggee JavaScript functions. In // this case, resolve and reject may be nullptr. virtual MOZ_MUST_USE bool then(JSContext* cx, JS::Handle resolve, JS::Handle reject, JS::Handle result) = 0; // A reaction record created when one native promise is resolved to another. // The 'promise' argument is the promise that will be settled in the same way // the promise this reaction record is attached to is settled. // // Note that promise may not be same-compartment with cx. This function // presents the promise exactly as it appears in the reaction record. virtual MOZ_MUST_USE bool direct( JSContext* cx, JS::Handle unwrappedPromise) = 0; // A reaction record that resumes an asynchronous function suspended at an // await expression. The 'generator' argument is the generator object // representing the call. // // Note that generator may not be same-compartment with cx. This function // presents the generator exactly as it appears in the reaction record. virtual MOZ_MUST_USE bool asyncFunction( JSContext* cx, JS::Handle unwrappedGenerator) = 0; // A reaction record that resumes an asynchronous generator suspended at an // await expression. The 'generator' argument is the generator object // representing the call. // // Note that generator may not be same-compartment with cx. This function // presents the generator exactly as it appears in the reaction record. virtual MOZ_MUST_USE bool asyncGenerator( JSContext* cx, JS::Handle unwrappedGenerator) = 0; }; } // namespace js #endif // builtin_Promise_h