зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1328820 - Add documentation comment to Promise.h, AsyncFunction.h, and AsyncIteration.h r=anba DONTBUILD comment-only
This commit is contained in:
Родитель
544b61c613
Коммит
1e093ed64e
|
@ -15,18 +15,53 @@
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
enum PromiseSlots {
|
enum PromiseSlots {
|
||||||
|
// Int32 value with PROMISE_FLAG_* flags below.
|
||||||
PromiseSlot_Flags = 0,
|
PromiseSlot_Flags = 0,
|
||||||
|
|
||||||
|
// * if this promise is pending, reaction objects
|
||||||
|
// * undefined if there's no reaction
|
||||||
|
// * maybe-wrapped PromiseReactionRecord if there's only one reacion
|
||||||
|
// * dense array if there are two or more more reactions
|
||||||
|
// * if this promise is fulfilled, the resolution value
|
||||||
|
// * if this promise is rejected, the reason for the rejection
|
||||||
PromiseSlot_ReactionsOrResult,
|
PromiseSlot_ReactionsOrResult,
|
||||||
|
|
||||||
|
// * if this promise is pending, resolve/reject functions.
|
||||||
|
// This slot holds only the reject function. The resolve function is
|
||||||
|
// reachable from the reject function's extended slot.
|
||||||
|
// * if this promise is either fulfilled or rejected, undefined
|
||||||
|
// * (special case) if this promise is the return value of an async function
|
||||||
|
// invocation, the generator object for the function's internal generator
|
||||||
PromiseSlot_RejectFunction,
|
PromiseSlot_RejectFunction,
|
||||||
PromiseSlot_AwaitGenerator = PromiseSlot_RejectFunction,
|
PromiseSlot_AwaitGenerator = PromiseSlot_RejectFunction,
|
||||||
|
|
||||||
|
// Promise object's debug info, which is created on demand.
|
||||||
|
// * if this promise has no debug info, undefined
|
||||||
|
// * if this promise contains only its process-unique ID, the ID's number
|
||||||
|
// value
|
||||||
|
// * otherwise a PromiseDebugInfo object
|
||||||
PromiseSlot_DebugInfo,
|
PromiseSlot_DebugInfo,
|
||||||
|
|
||||||
PromiseSlots,
|
PromiseSlots,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This promise is either fulfilled or rejected.
|
||||||
|
// If this flag is not set, this promise is pending.
|
||||||
#define PROMISE_FLAG_RESOLVED 0x1
|
#define PROMISE_FLAG_RESOLVED 0x1
|
||||||
|
|
||||||
|
// If this flag and PROMISE_FLAG_RESOLVED are set, this promise is fulfilled.
|
||||||
|
// If only PROMISE_FLAG_RESOLVED is set, this promise is rejected.
|
||||||
#define PROMISE_FLAG_FULFILLED 0x2
|
#define PROMISE_FLAG_FULFILLED 0x2
|
||||||
|
|
||||||
|
// Indicates the promise has ever had a fulfillment or rejection handler;
|
||||||
|
// used in unhandled rejection tracking.
|
||||||
#define PROMISE_FLAG_HANDLED 0x4
|
#define PROMISE_FLAG_HANDLED 0x4
|
||||||
|
|
||||||
|
// This promise uses the default resolving functions.
|
||||||
|
// The PromiseSlot_RejectFunction slot is not used.
|
||||||
#define PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS 0x08
|
#define PROMISE_FLAG_DEFAULT_RESOLVING_FUNCTIONS 0x08
|
||||||
|
|
||||||
|
// This promise is the return value of an async function invocation.
|
||||||
#define PROMISE_FLAG_ASYNC 0x10
|
#define PROMISE_FLAG_ASYNC 0x10
|
||||||
|
|
||||||
class AutoSetNewObjectMetadata;
|
class AutoSetNewObjectMetadata;
|
||||||
|
@ -92,7 +127,10 @@ class PromiseObject : public NativeObject
|
||||||
return resolutionTime() - allocationTime();
|
return resolutionTime() - allocationTime();
|
||||||
}
|
}
|
||||||
MOZ_MUST_USE bool dependentPromises(JSContext* cx, MutableHandle<GCVector<Value>> values);
|
MOZ_MUST_USE bool dependentPromises(JSContext* cx, MutableHandle<GCVector<Value>> values);
|
||||||
|
|
||||||
|
// Return the process-unique ID of this promise. Only used by the debugger.
|
||||||
uint64_t getID();
|
uint64_t getID();
|
||||||
|
|
||||||
bool isUnhandled() {
|
bool isUnhandled() {
|
||||||
MOZ_ASSERT(state() == JS::PromiseState::Rejected);
|
MOZ_ASSERT(state() == JS::PromiseState::Rejected);
|
||||||
return !(flags() & PROMISE_FLAG_HANDLED);
|
return !(flags() & PROMISE_FLAG_HANDLED);
|
||||||
|
@ -113,9 +151,18 @@ class PromiseObject : public NativeObject
|
||||||
MOZ_MUST_USE JSObject*
|
MOZ_MUST_USE JSObject*
|
||||||
GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises);
|
GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises);
|
||||||
|
|
||||||
|
// Whether to create a promise as the return value of Promise#{then,catch}.
|
||||||
|
// If the return value is known to be unused, and if the operation is known
|
||||||
|
// to be unobservable, we can skip creating the promise.
|
||||||
enum class CreateDependentPromise {
|
enum class CreateDependentPromise {
|
||||||
|
// The return value is not known to be unused.
|
||||||
Always,
|
Always,
|
||||||
|
|
||||||
|
// The return value is known to be unused.
|
||||||
SkipIfCtorUnobservable,
|
SkipIfCtorUnobservable,
|
||||||
|
|
||||||
|
// The return value is known to be unused, and the operation is known
|
||||||
|
// to be unobservable.
|
||||||
Never
|
Never
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,9 +191,17 @@ MOZ_MUST_USE JSObject*
|
||||||
PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
|
PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the promise object which will be used as the return value of an async
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
MOZ_MUST_USE PromiseObject*
|
MOZ_MUST_USE PromiseObject*
|
||||||
CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
|
CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given object is a promise created by
|
||||||
|
* CreatePromiseObjectForAsync function.
|
||||||
|
*/
|
||||||
MOZ_MUST_USE bool
|
MOZ_MUST_USE bool
|
||||||
IsPromiseForAsync(JSObject* promise);
|
IsPromiseForAsync(JSObject* promise);
|
||||||
|
|
||||||
|
|
|
@ -12,21 +12,44 @@
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
|
// An async function is implemented using two function objects, which are
|
||||||
|
// referred to as the "unwrapped" and the "wrapped" async function object.
|
||||||
|
// The unwrapped function is a generator function compiled from the async
|
||||||
|
// function's script. |await| expressions within the async function are
|
||||||
|
// compiled like |yield| expression for the generator function with dedicated
|
||||||
|
// opcode,. The unwrapped function is never exposed to user script.
|
||||||
|
// The wrapped function is a native function which wraps the generator function,
|
||||||
|
// hence its name, and is the publicly exposed object of the async function.
|
||||||
|
//
|
||||||
|
// The unwrapped async function is created while compiling the async function,
|
||||||
|
// and the wrapped async function is created while executing the async function
|
||||||
|
// declaration or expression.
|
||||||
|
|
||||||
|
// Returns a wrapped async function from an unwrapped async function.
|
||||||
JSFunction*
|
JSFunction*
|
||||||
GetWrappedAsyncFunction(JSFunction* unwrapped);
|
GetWrappedAsyncFunction(JSFunction* unwrapped);
|
||||||
|
|
||||||
|
// Returns an unwrapped async function from a wrapped async function.
|
||||||
JSFunction*
|
JSFunction*
|
||||||
GetUnwrappedAsyncFunction(JSFunction* wrapped);
|
GetUnwrappedAsyncFunction(JSFunction* wrapped);
|
||||||
|
|
||||||
|
// Returns true if the given function is a wrapped async function.
|
||||||
bool
|
bool
|
||||||
IsWrappedAsyncFunction(JSFunction* fun);
|
IsWrappedAsyncFunction(JSFunction* fun);
|
||||||
|
|
||||||
|
// Create a wrapped async function from unwrapped async function with given
|
||||||
|
// prototype object.
|
||||||
JSObject*
|
JSObject*
|
||||||
WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto);
|
WrapAsyncFunctionWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto);
|
||||||
|
|
||||||
|
// Create a wrapped async function from unwrapped async function with default
|
||||||
|
// prototype object.
|
||||||
JSObject*
|
JSObject*
|
||||||
WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped);
|
WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped);
|
||||||
|
|
||||||
|
// Resume the async function when the `await` operand resolves.
|
||||||
|
// Split into two functions depending on whether the awaited value was
|
||||||
|
// fulfilled or rejected.
|
||||||
MOZ_MUST_USE bool
|
MOZ_MUST_USE bool
|
||||||
AsyncFunctionAwaitedFulfilled(JSContext* cx, Handle<PromiseObject*> resultPromise,
|
AsyncFunctionAwaitedFulfilled(JSContext* cx, Handle<PromiseObject*> resultPromise,
|
||||||
HandleValue generatorVal, HandleValue value);
|
HandleValue generatorVal, HandleValue value);
|
||||||
|
|
|
@ -14,33 +14,55 @@
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
// Async generator consists of 2 functions, |wrapped| and |unwrapped|.
|
// An async generator is implemented using two function objects, which are
|
||||||
// |unwrapped| is a generator function compiled from async generator script,
|
// referred to as the "unwrapped" and the "wrapped" async generator object.
|
||||||
// |await| behaves just like |yield| there. |unwrapped| isn't exposed to user
|
// The unwrapped function is a generator function compiled from the async
|
||||||
// script.
|
// generator's script. |await| expressions within the async generator are
|
||||||
// |wrapped| is a native function that is the value of async generator.
|
// compiled like |yield| expression for the generator function with dedicated
|
||||||
|
// opcode. The unwrapped function is never exposed to user script.
|
||||||
|
// The wrapped function is a native function which wraps the generator function,
|
||||||
|
// hence its name, and is the publicly exposed object of the async generator.
|
||||||
|
//
|
||||||
|
// The unwrapped async generator is created while compiling the async generator,
|
||||||
|
// and the wrapped async generator is created while executing the async
|
||||||
|
// generator declaration or expression.
|
||||||
|
|
||||||
|
// Create a wrapped async generator from an unwrapped async generator with given
|
||||||
|
// prototype object.
|
||||||
JSObject*
|
JSObject*
|
||||||
WrapAsyncGeneratorWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto);
|
WrapAsyncGeneratorWithProto(JSContext* cx, HandleFunction unwrapped, HandleObject proto);
|
||||||
|
|
||||||
|
// Create a wrapped async generator from an unwrapped async generator
|
||||||
|
// with default prototype object.
|
||||||
JSObject*
|
JSObject*
|
||||||
WrapAsyncGenerator(JSContext* cx, HandleFunction unwrapped);
|
WrapAsyncGenerator(JSContext* cx, HandleFunction unwrapped);
|
||||||
|
|
||||||
|
// Returns true if the given function is a wrapped async generator.
|
||||||
bool
|
bool
|
||||||
IsWrappedAsyncGenerator(JSFunction* fun);
|
IsWrappedAsyncGenerator(JSFunction* fun);
|
||||||
|
|
||||||
|
// Returns a wrapped async generator from an unwrapped async generator.
|
||||||
JSFunction*
|
JSFunction*
|
||||||
GetWrappedAsyncGenerator(JSFunction* unwrapped);
|
GetWrappedAsyncGenerator(JSFunction* unwrapped);
|
||||||
|
|
||||||
|
// Return an unwrapped async generator from a wrapped async generator.
|
||||||
JSFunction*
|
JSFunction*
|
||||||
GetUnwrappedAsyncGenerator(JSFunction* wrapped);
|
GetUnwrappedAsyncGenerator(JSFunction* wrapped);
|
||||||
|
|
||||||
|
// Resume the async generator when the `await` operand fulfills to `value`.
|
||||||
MOZ_MUST_USE bool
|
MOZ_MUST_USE bool
|
||||||
AsyncGeneratorAwaitedFulfilled(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
|
AsyncGeneratorAwaitedFulfilled(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
|
||||||
HandleValue value);
|
HandleValue value);
|
||||||
|
|
||||||
|
// Resume the async generator when the `await` operand rejects with `reason`.
|
||||||
MOZ_MUST_USE bool
|
MOZ_MUST_USE bool
|
||||||
AsyncGeneratorAwaitedRejected(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
|
AsyncGeneratorAwaitedRejected(JSContext* cx, Handle<AsyncGeneratorObject*> asyncGenObj,
|
||||||
HandleValue reason);
|
HandleValue reason);
|
||||||
|
|
||||||
|
// Resume the async generator after awaiting on the value passed to
|
||||||
|
// AsyncGenerator#return, when the async generator was still executing.
|
||||||
|
// Split into two functions depending on whether the awaited value was
|
||||||
|
// fulfilled or rejected.
|
||||||
MOZ_MUST_USE bool
|
MOZ_MUST_USE bool
|
||||||
AsyncGeneratorYieldReturnAwaitedFulfilled(JSContext* cx,
|
AsyncGeneratorYieldReturnAwaitedFulfilled(JSContext* cx,
|
||||||
Handle<AsyncGeneratorObject*> asyncGenObj,
|
Handle<AsyncGeneratorObject*> asyncGenObj,
|
||||||
|
@ -52,13 +74,27 @@ AsyncGeneratorYieldReturnAwaitedRejected(JSContext* cx,
|
||||||
|
|
||||||
class AsyncGeneratorObject;
|
class AsyncGeneratorObject;
|
||||||
|
|
||||||
|
// AsyncGeneratorRequest record in the spec.
|
||||||
|
// Stores the info from AsyncGenerator#{next,return,throw}.
|
||||||
|
//
|
||||||
|
// This object is reused across multiple requests as an optimization, and
|
||||||
|
// stored in the Slot_CachedRequest slot.
|
||||||
class AsyncGeneratorRequest : public NativeObject
|
class AsyncGeneratorRequest : public NativeObject
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
enum AsyncGeneratorRequestSlots {
|
enum AsyncGeneratorRequestSlots {
|
||||||
|
// Int32 value with CompletionKind.
|
||||||
|
// Normal: next
|
||||||
|
// Return: return
|
||||||
|
// Throw: throw
|
||||||
Slot_CompletionKind = 0,
|
Slot_CompletionKind = 0,
|
||||||
|
|
||||||
|
// The value passed to AsyncGenerator#{next,return,throw}.
|
||||||
Slot_CompletionValue,
|
Slot_CompletionValue,
|
||||||
|
|
||||||
|
// The promise returned by AsyncGenerator#{next,return,throw}.
|
||||||
Slot_Promise,
|
Slot_Promise,
|
||||||
|
|
||||||
Slots,
|
Slots,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,6 +104,7 @@ class AsyncGeneratorRequest : public NativeObject
|
||||||
setFixedSlot(Slot_Promise, ObjectValue(*promise));
|
setFixedSlot(Slot_Promise, ObjectValue(*promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear the request data for reuse.
|
||||||
void clearData() {
|
void clearData() {
|
||||||
setFixedSlot(Slot_CompletionValue, NullValue());
|
setFixedSlot(Slot_CompletionValue, NullValue());
|
||||||
setFixedSlot(Slot_Promise, NullValue());
|
setFixedSlot(Slot_Promise, NullValue());
|
||||||
|
@ -97,23 +134,50 @@ class AsyncGeneratorObject : public NativeObject
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
enum AsyncGeneratorObjectSlots {
|
enum AsyncGeneratorObjectSlots {
|
||||||
|
// Int32 value containing one of the |State| fields from below.
|
||||||
Slot_State = 0,
|
Slot_State = 0,
|
||||||
|
|
||||||
|
// Generator object for the unwrapped async generator.
|
||||||
Slot_Generator,
|
Slot_Generator,
|
||||||
|
|
||||||
|
// * null value if this async generator has no requests
|
||||||
|
// * AsyncGeneratorRequest if this async generator has only one request
|
||||||
|
// * list object if this async generator has 2 or more requests
|
||||||
Slot_QueueOrRequest,
|
Slot_QueueOrRequest,
|
||||||
|
|
||||||
|
// Cached AsyncGeneratorRequest for later use.
|
||||||
|
// undefined if there's no cache.
|
||||||
Slot_CachedRequest,
|
Slot_CachedRequest,
|
||||||
|
|
||||||
Slots
|
Slots
|
||||||
};
|
};
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
|
// "suspendedStart" in the spec.
|
||||||
|
// Suspended after invocation.
|
||||||
State_SuspendedStart,
|
State_SuspendedStart,
|
||||||
|
|
||||||
|
// "suspendedYield" in the spec
|
||||||
|
// Suspended with `yield` expression.
|
||||||
State_SuspendedYield,
|
State_SuspendedYield,
|
||||||
|
|
||||||
|
// "executing" in the spec.
|
||||||
|
// Resumed from initial suspend or yield, and either running the script
|
||||||
|
// or awaiting for `await` expression.
|
||||||
State_Executing,
|
State_Executing,
|
||||||
// State_AwaitingYieldReturn corresponds to the case that
|
|
||||||
// AsyncGenerator#return is called while State_Executing,
|
// Part of "executing" in the spec.
|
||||||
// just like the case that AsyncGenerator#return is called
|
// Awaiting on the value passed by AsyncGenerator#return which is called
|
||||||
// while State_Completed.
|
// while executing.
|
||||||
State_AwaitingYieldReturn,
|
State_AwaitingYieldReturn,
|
||||||
|
|
||||||
|
// Part of "executing" in the spec.
|
||||||
|
// Awaiting on the value passed by AsyncGenerator#return which is called
|
||||||
|
// after completed.
|
||||||
State_AwaitingReturn,
|
State_AwaitingReturn,
|
||||||
|
|
||||||
|
// "completed" in the spec.
|
||||||
|
// The generator is completed.
|
||||||
State_Completed
|
State_Completed
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,8 +193,8 @@ class AsyncGeneratorObject : public NativeObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue is implemented in 2 ways. If only one request is queued ever,
|
// Queue is implemented in 2 ways. If only one request is queued ever,
|
||||||
// request is stored directly to the slot. Once 2 requests are queued, an
|
// request is stored directly to the slot. Once 2 requests are queued, a
|
||||||
// array is created and requests are pushed into it, and the array is
|
// list is created and requests are appended into it, and the list is
|
||||||
// stored to the slot.
|
// stored to the slot.
|
||||||
|
|
||||||
bool isSingleQueue() const {
|
bool isSingleQueue() const {
|
||||||
|
@ -267,8 +331,12 @@ class AsyncFromSyncIteratorObject : public NativeObject
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
enum AsyncFromSyncIteratorObjectSlots {
|
enum AsyncFromSyncIteratorObjectSlots {
|
||||||
|
// Object that implements the sync iterator protocol.
|
||||||
Slot_Iterator = 0,
|
Slot_Iterator = 0,
|
||||||
|
|
||||||
|
// The `next` property of the iterator object.
|
||||||
Slot_NextMethod = 1,
|
Slot_NextMethod = 1,
|
||||||
|
|
||||||
Slots
|
Slots
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче