зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1315756 - Do not allocate throwawayCapability in AsyncFunctionAwait. r=till
This commit is contained in:
Родитель
5b812dee62
Коммит
367ecab382
|
@ -173,6 +173,7 @@ enum ReactionRecordSlots {
|
|||
#define REACTION_FLAG_RESOLVED 0x1
|
||||
#define REACTION_FLAG_FULFILLED 0x2
|
||||
#define REACTION_FLAG_IGNORE_DEFAULT_RESOLUTION 0x4
|
||||
#define REACTION_FLAG_AWAIT 0x8
|
||||
|
||||
// ES2016, 25.4.1.2.
|
||||
class PromiseReactionRecord : public NativeObject
|
||||
|
@ -199,6 +200,15 @@ class PromiseReactionRecord : public NativeObject
|
|||
flags |= REACTION_FLAG_FULFILLED;
|
||||
setFixedSlot(ReactionRecordSlot_Flags, Int32Value(flags));
|
||||
}
|
||||
void setIsAwait() {
|
||||
int32_t flags = this->flags();
|
||||
flags |= REACTION_FLAG_AWAIT;
|
||||
setFixedSlot(ReactionRecordSlot_Flags, Int32Value(flags));
|
||||
}
|
||||
bool isAwait() {
|
||||
int32_t flags = this->flags();
|
||||
return flags & REACTION_FLAG_AWAIT;
|
||||
}
|
||||
Value handler() {
|
||||
MOZ_ASSERT(targetState() != JS::PromiseState::Pending);
|
||||
uint32_t slot = targetState() == JS::PromiseState::Fulfilled
|
||||
|
@ -808,6 +818,35 @@ TriggerPromiseReactions(JSContext* cx, HandleValue reactionsVal, JS::PromiseStat
|
|||
return true;
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
AwaitPromiseReactionJob(JSContext* cx, Handle<PromiseReactionRecord*> reaction,
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
MOZ_ASSERT(reaction->isAwait());
|
||||
|
||||
RootedValue handlerVal(cx, reaction->handler());
|
||||
RootedValue argument(cx, reaction->handlerArg());
|
||||
Rooted<PromiseObject*> resultPromise(cx, &reaction->promise()->as<PromiseObject>());
|
||||
RootedValue generatorVal(cx, resultPromise->getFixedSlot(PromiseSlot_AwaitGenerator));
|
||||
|
||||
int32_t handlerNum = int32_t(handlerVal.toNumber());
|
||||
MOZ_ASSERT(handlerNum == PROMISE_HANDLER_AWAIT_FULFILLED
|
||||
|| handlerNum == PROMISE_HANDLER_AWAIT_REJECTED);
|
||||
|
||||
// Await's handlers don't return a value, nor throw exception.
|
||||
// They fail only on OOM.
|
||||
if (handlerNum == PROMISE_HANDLER_AWAIT_FULFILLED) {
|
||||
if (!AsyncFunctionAwaitedFulfilled(cx, resultPromise, generatorVal, argument))
|
||||
return false;
|
||||
} else {
|
||||
if (!AsyncFunctionAwaitedRejected(cx, resultPromise, generatorVal, argument))
|
||||
return false;
|
||||
}
|
||||
|
||||
rval.setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ES2016, 25.4.2.1.
|
||||
/**
|
||||
* Callback triggering the fulfill/reject reaction for a resolved Promise,
|
||||
|
@ -844,6 +883,8 @@ PromiseReactionJob(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
// Steps 1-2.
|
||||
Rooted<PromiseReactionRecord*> reaction(cx, &reactionObj->as<PromiseReactionRecord>());
|
||||
if (reaction->isAwait())
|
||||
return AwaitPromiseReactionJob(cx, reaction, args.rval());
|
||||
|
||||
// Step 3.
|
||||
RootedValue handlerVal(cx, reaction->handler());
|
||||
|
@ -860,32 +901,11 @@ PromiseReactionJob(JSContext* cx, unsigned argc, Value* vp)
|
|||
// Step 4.
|
||||
if (handlerNum == PROMISE_HANDLER_IDENTITY) {
|
||||
handlerResult = argument;
|
||||
} else if (handlerNum == PROMISE_HANDLER_THROWER) {
|
||||
} else {
|
||||
// Step 5.
|
||||
MOZ_ASSERT(handlerNum == PROMISE_HANDLER_THROWER);
|
||||
resolutionMode = RejectMode;
|
||||
handlerResult = argument;
|
||||
} else {
|
||||
MOZ_ASSERT(handlerNum == PROMISE_HANDLER_AWAIT_FULFILLED
|
||||
|| handlerNum == PROMISE_HANDLER_AWAIT_REJECTED);
|
||||
|
||||
Rooted<PromiseObject*> promiseObj(cx, &reaction->promise()->as<PromiseObject>());
|
||||
MOZ_ASSERT(PromiseHasAnyFlag(*promiseObj, PROMISE_FLAG_AWAIT));
|
||||
|
||||
RootedValue generatorVal(cx, promiseObj->getFixedSlot(PromiseSlot_AwaitGenerator));
|
||||
|
||||
// Step 6.
|
||||
// Optimized for await.
|
||||
bool result;
|
||||
if (handlerNum == PROMISE_HANDLER_AWAIT_FULFILLED)
|
||||
result = AsyncFunctionAwaitedFulfilled(cx, argument, generatorVal, &handlerResult);
|
||||
else
|
||||
result = AsyncFunctionAwaitedRejected(cx, argument, generatorVal, &handlerResult);
|
||||
|
||||
if (!result) {
|
||||
resolutionMode = RejectMode;
|
||||
if (!cx->isExceptionPending() || !GetAndClearException(cx, &handlerResult))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Step 6.
|
||||
|
@ -2088,19 +2108,58 @@ js::OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise, HandleVal
|
|||
return resultPromise;
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool PerformPromiseThenImpl(JSContext* cx, Handle<PromiseObject*> promise,
|
||||
HandleValue onFulfilled,
|
||||
HandleValue onRejected,
|
||||
HandleObject resultPromise,
|
||||
HandleObject resolve,
|
||||
HandleObject reject);
|
||||
static MOZ_MUST_USE bool PerformPromiseThenWithReaction(JSContext* cx,
|
||||
Handle<PromiseObject*> promise,
|
||||
Handle<PromiseReactionRecord*> reaction);
|
||||
|
||||
// Some async/await functions are implemented here instead of
|
||||
// js/src/builtin/AsyncFunction.cpp, to call Promise internal functions.
|
||||
|
||||
// Async Functions proposal 1.1.8 and 1.2.14 step 1.
|
||||
MOZ_MUST_USE PromiseObject*
|
||||
js::CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal)
|
||||
{
|
||||
// Step 1.
|
||||
Rooted<PromiseObject*> promise(cx, CreatePromiseObjectWithDefaultResolution(cx));
|
||||
if (!promise)
|
||||
return nullptr;
|
||||
|
||||
AddPromiseFlags(*promise, PROMISE_FLAG_ASYNC);
|
||||
promise->setFixedSlot(PromiseSlot_AwaitGenerator, generatorVal);
|
||||
return promise;
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.2 steps 3.f, 3.g.
|
||||
MOZ_MUST_USE bool
|
||||
js::AsyncFunctionThrown(JSContext* cx, Handle<PromiseObject*> resultPromise)
|
||||
{
|
||||
// Step 3.f.
|
||||
RootedValue exc(cx);
|
||||
if (!GetAndClearException(cx, &exc))
|
||||
return false;
|
||||
|
||||
if (!RejectMaybeWrappedPromise(cx, resultPromise, exc))
|
||||
return false;
|
||||
|
||||
// Step 3.g.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.2 steps 3.d-e, 3.g.
|
||||
MOZ_MUST_USE bool
|
||||
js::AsyncFunctionReturned(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value)
|
||||
{
|
||||
// Steps 3.d-e.
|
||||
if (!ResolvePromiseInternal(cx, resultPromise, value))
|
||||
return false;
|
||||
|
||||
// Step 3.g.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.3 steps 2-8.
|
||||
// Implemented here instead of js/src/builtin/AsyncFunction.cpp
|
||||
// to call Promise internal functions
|
||||
bool
|
||||
js::AsyncFunctionAwait(JSContext* cx, HandleValue generatorVal, HandleValue value,
|
||||
MutableHandleValue rval)
|
||||
MOZ_MUST_USE bool
|
||||
js::AsyncFunctionAwait(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value)
|
||||
{
|
||||
// Step 2.
|
||||
Rooted<PromiseObject*> promise(cx, CreatePromiseObjectWithDefaultResolution(cx));
|
||||
|
@ -2115,24 +2174,22 @@ js::AsyncFunctionAwait(JSContext* cx, HandleValue generatorVal, HandleValue valu
|
|||
RootedValue onFulfilled(cx, Int32Value(PROMISE_HANDLER_AWAIT_FULFILLED));
|
||||
RootedValue onRejected(cx, Int32Value(PROMISE_HANDLER_AWAIT_REJECTED));
|
||||
|
||||
// Step 7.
|
||||
Rooted<PromiseObject*> resultPromise(cx, CreatePromiseObjectWithDefaultResolution(cx));
|
||||
if (!resultPromise)
|
||||
RootedObject incumbentGlobal(cx);
|
||||
if (!GetObjectFromIncumbentGlobal(cx, &incumbentGlobal))
|
||||
return false;
|
||||
|
||||
// Step 6 (reordered).
|
||||
AddPromiseFlags(*resultPromise, PROMISE_FLAG_AWAIT);
|
||||
resultPromise->setFixedSlot(PromiseSlot_AwaitGenerator, generatorVal);
|
||||
// Steps 6-7.
|
||||
Rooted<PromiseReactionRecord*> reaction(cx, NewReactionRecord(cx, resultPromise,
|
||||
onFulfilled, onRejected,
|
||||
nullptr, nullptr,
|
||||
incumbentGlobal));
|
||||
if (!reaction)
|
||||
return false;
|
||||
|
||||
reaction->setIsAwait();
|
||||
|
||||
// Step 8.
|
||||
if (!PerformPromiseThenImpl(cx, promise, onFulfilled, onRejected, resultPromise,
|
||||
nullptr, nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
rval.setObject(*resultPromise);
|
||||
return true;
|
||||
return PerformPromiseThenWithReaction(cx, promise, reaction);
|
||||
}
|
||||
|
||||
// ES2016, 25.4.5.3.
|
||||
|
@ -2201,15 +2258,6 @@ PerformPromiseThen(JSContext* cx, Handle<PromiseObject*> promise, HandleValue on
|
|||
if (!IsCallable(onRejected))
|
||||
onRejected = Int32Value(PROMISE_HANDLER_THROWER);
|
||||
|
||||
return PerformPromiseThenImpl(cx, promise, onFulfilled, onRejected, resultPromise,
|
||||
resolve, reject);
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
PerformPromiseThenImpl(JSContext* cx, Handle<PromiseObject*> promise, HandleValue onFulfilled,
|
||||
HandleValue onRejected, HandleObject resultPromise,
|
||||
HandleObject resolve, HandleObject reject)
|
||||
{
|
||||
RootedObject incumbentGlobal(cx);
|
||||
if (!GetObjectFromIncumbentGlobal(cx, &incumbentGlobal))
|
||||
return false;
|
||||
|
@ -2222,6 +2270,13 @@ PerformPromiseThenImpl(JSContext* cx, Handle<PromiseObject*> promise, HandleValu
|
|||
if (!reaction)
|
||||
return false;
|
||||
|
||||
return PerformPromiseThenWithReaction(cx, promise, reaction);
|
||||
}
|
||||
|
||||
static MOZ_MUST_USE bool
|
||||
PerformPromiseThenWithReaction(JSContext* cx, Handle<PromiseObject*> promise,
|
||||
Handle<PromiseReactionRecord*> reaction)
|
||||
{
|
||||
JS::PromiseState state = promise->state();
|
||||
int32_t flags = promise->getFixedSlot(PromiseSlot_Flags).toInt32();
|
||||
if (state == JS::PromiseState::Pending) {
|
||||
|
@ -2534,7 +2589,7 @@ PromiseObject::dependentPromises(JSContext* cx, MutableHandle<GCVector<Value>> v
|
|||
bool
|
||||
PromiseObject::resolve(JSContext* cx, HandleValue resolutionValue)
|
||||
{
|
||||
MOZ_ASSERT(!PromiseHasAnyFlag(*this, PROMISE_FLAG_AWAIT));
|
||||
MOZ_ASSERT(!PromiseHasAnyFlag(*this, PROMISE_FLAG_ASYNC));
|
||||
if (state() != JS::PromiseState::Pending)
|
||||
return true;
|
||||
|
||||
|
@ -2557,7 +2612,7 @@ PromiseObject::resolve(JSContext* cx, HandleValue resolutionValue)
|
|||
bool
|
||||
PromiseObject::reject(JSContext* cx, HandleValue rejectionValue)
|
||||
{
|
||||
MOZ_ASSERT(!PromiseHasAnyFlag(*this, PROMISE_FLAG_AWAIT));
|
||||
MOZ_ASSERT(!PromiseHasAnyFlag(*this, PROMISE_FLAG_ASYNC));
|
||||
if (state() != JS::PromiseState::Pending)
|
||||
return true;
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ enum PromiseSlots {
|
|||
#define PROMISE_FLAG_REPORTED 0x8
|
||||
#define PROMISE_FLAG_DEFAULT_RESOLVE_FUNCTION 0x10
|
||||
#define PROMISE_FLAG_DEFAULT_REJECT_FUNCTION 0x20
|
||||
#define PROMISE_FLAG_AWAIT 0x40
|
||||
#define PROMISE_FLAG_ASYNC 0x40
|
||||
|
||||
class AutoSetNewObjectMetadata;
|
||||
|
||||
|
@ -119,9 +119,17 @@ MOZ_MUST_USE JSObject*
|
|||
OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise, HandleValue onFulfilled,
|
||||
HandleValue onRejected);
|
||||
|
||||
bool
|
||||
AsyncFunctionAwait(JSContext* cx, HandleValue generatorVal, HandleValue value,
|
||||
MutableHandleValue rval);
|
||||
MOZ_MUST_USE PromiseObject*
|
||||
CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
|
||||
|
||||
MOZ_MUST_USE bool
|
||||
AsyncFunctionReturned(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value);
|
||||
|
||||
MOZ_MUST_USE bool
|
||||
AsyncFunctionThrown(JSContext* cx, Handle<PromiseObject*> resultPromise);
|
||||
|
||||
MOZ_MUST_USE bool
|
||||
AsyncFunctionAwait(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue value);
|
||||
|
||||
/**
|
||||
* A PromiseTask represents a task that can be dispatched to a helper thread
|
||||
|
|
|
@ -47,7 +47,8 @@ GlobalObject::initAsyncFunction(JSContext* cx, Handle<GlobalObject*> global)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool AsyncFunctionStart(JSContext* cx, HandleValue generatorVal, MutableHandleValue rval);
|
||||
static MOZ_MUST_USE bool AsyncFunctionStart(JSContext* cx, Handle<PromiseObject*> resultPromise,
|
||||
HandleValue generatorVal);
|
||||
|
||||
#define UNWRAPPED_ASYNC_WRAPPED_SLOT 1
|
||||
#define WRAPPED_ASYNC_UNWRAPPED_SLOT 0
|
||||
|
@ -72,11 +73,21 @@ WrappedAsyncFunction(JSContext* cx, unsigned argc, Value* vp)
|
|||
for (size_t i = 0, len = argc; i < len; i++)
|
||||
args2[i].set(args[i]);
|
||||
if (Call(cx, unwrappedVal, thisValue, args2, &generatorVal)) {
|
||||
// Steps 3, 5.
|
||||
return AsyncFunctionStart(cx, generatorVal, args.rval());
|
||||
// Step 1.
|
||||
Rooted<PromiseObject*> resultPromise(cx, CreatePromiseObjectForAsync(cx, generatorVal));
|
||||
if (!resultPromise)
|
||||
return false;
|
||||
|
||||
// Step 3.
|
||||
if (!AsyncFunctionStart(cx, resultPromise, generatorVal))
|
||||
return false;
|
||||
|
||||
// Step 5.
|
||||
args.rval().setObject(*resultPromise);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
// Steps 1, 4.
|
||||
RootedValue exc(cx);
|
||||
if (!GetAndClearException(cx, &exc))
|
||||
return false;
|
||||
|
@ -129,47 +140,19 @@ js::WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped)
|
|||
return wrapped;
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.2 steps 3.f, 3.g.
|
||||
static bool
|
||||
AsyncFunctionThrown(JSContext* cx, MutableHandleValue rval)
|
||||
{
|
||||
// Step 3.f.
|
||||
RootedValue exc(cx);
|
||||
if (!GetAndClearException(cx, &exc))
|
||||
return false;
|
||||
|
||||
RootedObject rejectPromise(cx, PromiseObject::unforgeableReject(cx, exc));
|
||||
if (!rejectPromise)
|
||||
return false;
|
||||
|
||||
// Step 3.g.
|
||||
rval.setObject(*rejectPromise);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.2 steps 3.d-e, 3.g.
|
||||
static bool
|
||||
AsyncFunctionReturned(JSContext* cx, HandleValue value, MutableHandleValue rval)
|
||||
{
|
||||
// Steps 3.d-e.
|
||||
RootedObject resolveObj(cx, PromiseObject::unforgeableResolve(cx, value));
|
||||
if (!resolveObj)
|
||||
return false;
|
||||
|
||||
// Step 3.g.
|
||||
rval.setObject(*resolveObj);
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class ResumeKind {
|
||||
Normal,
|
||||
Throw
|
||||
};
|
||||
|
||||
// Async Functions proposal 2.2 steps 3.f, 3.g.
|
||||
// Async Functions proposal 2.2 steps 3.d-e, 3.g.
|
||||
// Implemented in js/src/builtin/Promise.cpp
|
||||
|
||||
// Async Functions proposal 2.2 steps 3-8, 2.4 steps 2-7, 2.5 steps 2-7.
|
||||
static bool
|
||||
AsyncFunctionResume(JSContext* cx, HandleValue generatorVal, ResumeKind kind,
|
||||
HandleValue valueOrReason, MutableHandleValue rval)
|
||||
AsyncFunctionResume(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue generatorVal,
|
||||
ResumeKind kind, HandleValue valueOrReason)
|
||||
{
|
||||
// Execution context switching is handled in generator.
|
||||
HandlePropertyName funName = kind == ResumeKind::Normal
|
||||
|
@ -179,7 +162,7 @@ AsyncFunctionResume(JSContext* cx, HandleValue generatorVal, ResumeKind kind,
|
|||
args[0].set(valueOrReason);
|
||||
RootedValue result(cx);
|
||||
if (!CallSelfHostedFunction(cx, funName, generatorVal, args, &result))
|
||||
return AsyncFunctionThrown(cx, rval);
|
||||
return AsyncFunctionThrown(cx, resultPromise);
|
||||
|
||||
RootedObject resultObj(cx, &result.toObject());
|
||||
RootedValue doneVal(cx);
|
||||
|
@ -190,41 +173,41 @@ AsyncFunctionResume(JSContext* cx, HandleValue generatorVal, ResumeKind kind,
|
|||
return false;
|
||||
|
||||
if (doneVal.toBoolean())
|
||||
return AsyncFunctionReturned(cx, value, rval);
|
||||
return AsyncFunctionReturned(cx, resultPromise, value);
|
||||
|
||||
return AsyncFunctionAwait(cx, generatorVal, value, rval);
|
||||
return AsyncFunctionAwait(cx, resultPromise, value);
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.2 steps 3-8.
|
||||
static bool
|
||||
AsyncFunctionStart(JSContext* cx, HandleValue generatorVal, MutableHandleValue rval)
|
||||
static MOZ_MUST_USE bool
|
||||
AsyncFunctionStart(JSContext* cx, Handle<PromiseObject*> resultPromise, HandleValue generatorVal)
|
||||
{
|
||||
return AsyncFunctionResume(cx, generatorVal, ResumeKind::Normal, UndefinedHandleValue, rval);
|
||||
return AsyncFunctionResume(cx, resultPromise, generatorVal, ResumeKind::Normal, UndefinedHandleValue);
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.3 steps 1-8.
|
||||
// Implemented in js/src/builtin/Promise.cpp
|
||||
|
||||
// Async Functions proposal 2.4.
|
||||
bool
|
||||
js::AsyncFunctionAwaitedFulfilled(JSContext* cx, HandleValue value, HandleValue generatorVal,
|
||||
MutableHandleValue rval)
|
||||
MOZ_MUST_USE bool
|
||||
js::AsyncFunctionAwaitedFulfilled(JSContext* cx, Handle<PromiseObject*> resultPromise,
|
||||
HandleValue generatorVal, HandleValue value)
|
||||
{
|
||||
// Step 1 (implicit).
|
||||
|
||||
// Steps 2-7.
|
||||
return AsyncFunctionResume(cx, generatorVal, ResumeKind::Normal, value, rval);
|
||||
return AsyncFunctionResume(cx, resultPromise, generatorVal, ResumeKind::Normal, value);
|
||||
}
|
||||
|
||||
// Async Functions proposal 2.5.
|
||||
bool
|
||||
js::AsyncFunctionAwaitedRejected(JSContext* cx, HandleValue reason, HandleValue generatorVal,
|
||||
MutableHandleValue rval)
|
||||
MOZ_MUST_USE bool
|
||||
js::AsyncFunctionAwaitedRejected(JSContext* cx, Handle<PromiseObject*> resultPromise,
|
||||
HandleValue generatorVal, HandleValue reason)
|
||||
{
|
||||
// Step 1 (implicit).
|
||||
|
||||
// Step 2-7.
|
||||
return AsyncFunctionResume(cx, generatorVal, ResumeKind::Throw, reason, rval);
|
||||
return AsyncFunctionResume(cx, resultPromise, generatorVal, ResumeKind::Throw, reason);
|
||||
}
|
||||
|
||||
JSFunction*
|
||||
|
|
|
@ -24,13 +24,13 @@ IsWrappedAsyncFunction(JSFunction* fun);
|
|||
JSObject*
|
||||
WrapAsyncFunction(JSContext* cx, HandleFunction unwrapped);
|
||||
|
||||
bool
|
||||
AsyncFunctionAwaitedFulfilled(JSContext* cx, HandleValue value, HandleValue generatorVal,
|
||||
MutableHandleValue rval);
|
||||
MOZ_MUST_USE bool
|
||||
AsyncFunctionAwaitedFulfilled(JSContext* cx, Handle<PromiseObject*> resultPromise,
|
||||
HandleValue generatorVal, HandleValue value);
|
||||
|
||||
bool
|
||||
AsyncFunctionAwaitedRejected(JSContext* cx, HandleValue reason, HandleValue generatorVal,
|
||||
MutableHandleValue rval);
|
||||
MOZ_MUST_USE bool
|
||||
AsyncFunctionAwaitedRejected(JSContext* cx, Handle<PromiseObject*> resultPromise,
|
||||
HandleValue generatorVal, HandleValue reason);
|
||||
|
||||
} // namespace js
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче