Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/builtins/promise-all.tq')
-rw-r--r--deps/v8/src/builtins/promise-all.tq659
1 files changed, 326 insertions, 333 deletions
diff --git a/deps/v8/src/builtins/promise-all.tq b/deps/v8/src/builtins/promise-all.tq
index 19a16d8da85..b7fad88f6fc 100644
--- a/deps/v8/src/builtins/promise-all.tq
+++ b/deps/v8/src/builtins/promise-all.tq
@@ -6,165 +6,160 @@
#include 'src/builtins/builtins-promise-gen.h'
namespace promise {
- const kPromiseBuiltinsPromiseContextLength: constexpr int31
- generates 'PromiseBuiltins::kPromiseContextLength';
-
- // Creates the context used by all Promise.all resolve element closures,
- // together with the values array. Since all closures for a single Promise.all
- // call use the same context, we need to store the indices for the individual
- // closures somewhere else (we put them into the identity hash field of the
- // closures), and we also need to have a separate marker for when the closure
- // was called already (we slap the native context onto the closure in that
- // case to mark it's done).
- macro CreatePromiseAllResolveElementContext(implicit context: Context)(
- capability: PromiseCapability, nativeContext: NativeContext): Context {
- // TODO(bmeurer): Manually fold this into a single allocation.
- const arrayMap = UnsafeCast<Map>(
- nativeContext[NativeContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX]);
- const valuesArray = AllocateJSArray(
- ElementsKind::PACKED_ELEMENTS, arrayMap, IntPtrConstant(0),
- SmiConstant(0));
- const resolveContext = AllocateSyntheticFunctionContext(
- nativeContext,
- PromiseAllResolveElementContextSlots::kPromiseAllResolveElementLength);
- resolveContext[PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementRemainingSlot] = SmiConstant(1);
- resolveContext[PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementCapabilitySlot] = capability;
- resolveContext[PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementValuesArraySlot] = valuesArray;
- return resolveContext;
- }
+const kPromiseBuiltinsPromiseContextLength: constexpr int31
+ generates 'PromiseBuiltins::kPromiseContextLength';
+
+// Creates the context used by all Promise.all resolve element closures,
+// together with the values array. Since all closures for a single Promise.all
+// call use the same context, we need to store the indices for the individual
+// closures somewhere else (we put them into the identity hash field of the
+// closures), and we also need to have a separate marker for when the closure
+// was called already (we slap the native context onto the closure in that
+// case to mark it's done).
+macro CreatePromiseAllResolveElementContext(implicit context: Context)(
+ capability: PromiseCapability, nativeContext: NativeContext): Context {
+ // TODO(bmeurer): Manually fold this into a single allocation.
+ const arrayMap = UnsafeCast<Map>(
+ nativeContext[NativeContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX]);
+ const valuesArray = AllocateJSArray(
+ ElementsKind::PACKED_ELEMENTS, arrayMap, IntPtrConstant(0),
+ SmiConstant(0));
+ const resolveContext = AllocateSyntheticFunctionContext(
+ nativeContext,
+ PromiseAllResolveElementContextSlots::kPromiseAllResolveElementLength);
+ resolveContext[PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementRemainingSlot] = SmiConstant(1);
+ resolveContext[PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementCapabilitySlot] = capability;
+ resolveContext[PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementValuesArraySlot] = valuesArray;
+ return resolveContext;
+}
- macro CreatePromiseAllResolveElementFunction(implicit context: Context)(
- resolveElementContext: Context, index: Smi, nativeContext: NativeContext,
- slotIndex: constexpr NativeContextSlot): JSFunction {
- assert(index > 0);
- assert(index < kPropertyArrayHashFieldMax);
-
- const map = UnsafeCast<Map>(
- nativeContext
- [NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
- const resolveInfo =
- UnsafeCast<SharedFunctionInfo>(nativeContext[slotIndex]);
- const resolve = AllocateFunctionWithMapAndContext(
- map, resolveInfo, resolveElementContext);
-
- assert(kPropertyArrayNoHashSentinel == 0);
- resolve.properties_or_hash = index;
- return resolve;
- }
+macro CreatePromiseAllResolveElementFunction(implicit context: Context)(
+ resolveElementContext: Context, index: Smi, nativeContext: NativeContext,
+ resolveFunction: SharedFunctionInfo): JSFunction {
+ assert(index > 0);
+ assert(index < kPropertyArrayHashFieldMax);
+
+ const map = UnsafeCast<Map>(
+ nativeContext
+ [NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
+ const resolve = AllocateFunctionWithMapAndContext(
+ map, resolveFunction, resolveElementContext);
+
+ assert(kPropertyArrayNoHashSentinel == 0);
+ resolve.properties_or_hash = index;
+ return resolve;
+}
- @export
- macro CreatePromiseResolvingFunctionsContext(implicit context: Context)(
- promise: JSPromise, debugEvent: Object, nativeContext: NativeContext):
- Context {
- const resolveContext = AllocateSyntheticFunctionContext(
- nativeContext, kPromiseBuiltinsPromiseContextLength);
- resolveContext[kPromiseBuiltinsPromiseSlot] = promise;
- resolveContext[kPromiseBuiltinsAlreadyResolvedSlot] = False;
- resolveContext[kPromiseBuiltinsDebugEventSlot] = debugEvent;
- return resolveContext;
- }
+@export
+macro CreatePromiseResolvingFunctionsContext(implicit context: Context)(
+ promise: JSPromise, debugEvent: Object, nativeContext: NativeContext):
+ Context {
+ const resolveContext = AllocateSyntheticFunctionContext(
+ nativeContext, kPromiseBuiltinsPromiseContextLength);
+ resolveContext[kPromiseBuiltinsPromiseSlot] = promise;
+ resolveContext[kPromiseBuiltinsAlreadyResolvedSlot] = False;
+ resolveContext[kPromiseBuiltinsDebugEventSlot] = debugEvent;
+ return resolveContext;
+}
- macro IsPromiseThenLookupChainIntact(implicit context: Context)(
- nativeContext: NativeContext, receiverMap: Map): bool {
- if (IsForceSlowPath()) return false;
- if (!IsJSPromiseMap(receiverMap)) return false;
- if (receiverMap.prototype !=
- nativeContext[NativeContextSlot::PROMISE_PROTOTYPE_INDEX])
- return false;
- return !IsPromiseThenProtectorCellInvalid();
- }
+macro IsPromiseThenLookupChainIntact(implicit context: Context)(
+ nativeContext: NativeContext, receiverMap: Map): bool {
+ if (IsForceSlowPath()) return false;
+ if (!IsJSPromiseMap(receiverMap)) return false;
+ if (receiverMap.prototype !=
+ nativeContext[NativeContextSlot::PROMISE_PROTOTYPE_INDEX])
+ return false;
+ return !IsPromiseThenProtectorCellInvalid();
+}
- struct PromiseAllResolveElementFunctor {
- macro Call(implicit context: Context)(
- resolveElementContext: Context, nativeContext: NativeContext,
- index: Smi, _capability: PromiseCapability): Callable {
- return CreatePromiseAllResolveElementFunction(
- resolveElementContext, index, nativeContext,
- NativeContextSlot::PROMISE_ALL_RESOLVE_ELEMENT_SHARED_FUN);
- }
+struct PromiseAllResolveElementFunctor {
+ macro Call(implicit context: Context)(
+ resolveElementContext: Context, nativeContext: NativeContext, index: Smi,
+ _capability: PromiseCapability): Callable {
+ return CreatePromiseAllResolveElementFunction(
+ resolveElementContext, index, nativeContext,
+ PromiseAllResolveElementSharedFunConstant());
}
+}
- struct PromiseAllRejectElementFunctor {
- macro Call(implicit context: Context)(
- _resolveElementContext: Context, _nativeContext: NativeContext,
- _index: Smi, capability: PromiseCapability): Callable {
- return UnsafeCast<Callable>(capability.reject);
- }
+struct PromiseAllRejectElementFunctor {
+ macro Call(implicit context: Context)(
+ _resolveElementContext: Context, _nativeContext: NativeContext,
+ _index: Smi, capability: PromiseCapability): Callable {
+ return UnsafeCast<Callable>(capability.reject);
}
+}
- struct PromiseAllSettledResolveElementFunctor {
- macro Call(implicit context: Context)(
- resolveElementContext: Context, nativeContext: NativeContext,
- index: Smi, _capability: PromiseCapability): Callable {
- return CreatePromiseAllResolveElementFunction(
- resolveElementContext, index, nativeContext,
- NativeContextSlot::PROMISE_ALL_SETTLED_RESOLVE_ELEMENT_SHARED_FUN);
- }
+struct PromiseAllSettledResolveElementFunctor {
+ macro Call(implicit context: Context)(
+ resolveElementContext: Context, nativeContext: NativeContext, index: Smi,
+ _capability: PromiseCapability): Callable {
+ return CreatePromiseAllResolveElementFunction(
+ resolveElementContext, index, nativeContext,
+ PromiseAllSettledResolveElementSharedFunConstant());
}
+}
- struct PromiseAllSettledRejectElementFunctor {
- macro Call(implicit context: Context)(
- resolveElementContext: Context, nativeContext: NativeContext,
- index: Smi, _capability: PromiseCapability): Callable {
- return CreatePromiseAllResolveElementFunction(
- resolveElementContext, index, nativeContext,
- NativeContextSlot::PROMISE_ALL_SETTLED_REJECT_ELEMENT_SHARED_FUN);
- }
+struct PromiseAllSettledRejectElementFunctor {
+ macro Call(implicit context: Context)(
+ resolveElementContext: Context, nativeContext: NativeContext, index: Smi,
+ _capability: PromiseCapability): Callable {
+ return CreatePromiseAllResolveElementFunction(
+ resolveElementContext, index, nativeContext,
+ PromiseAllSettledRejectElementSharedFunConstant());
}
+}
- transitioning macro PerformPromiseAll<F1: type, F2: type>(implicit context:
- Context)(
- constructor: JSReceiver, capability: PromiseCapability,
- iter: iterator::IteratorRecord, createResolveElementFunctor: F1,
- createRejectElementFunctor: F2): JSAny labels Reject(Object) {
- const nativeContext = LoadNativeContext(context);
- const promise = capability.promise;
- const resolve = capability.resolve;
- const reject = capability.reject;
-
- // For catch prediction, don't treat the .then calls as handling it;
- // instead, recurse outwards.
- if (IsDebugActive()) deferred {
- SetPropertyStrict(
- context, reject, kPromiseForwardingHandlerSymbol, True);
- }
+transitioning macro PerformPromiseAll<F1: type, F2: type>(
+ implicit context: Context)(
+ constructor: JSReceiver, capability: PromiseCapability,
+ iter: iterator::IteratorRecord, createResolveElementFunctor: F1,
+ createRejectElementFunctor: F2): JSAny labels
+Reject(Object) {
+ const nativeContext = LoadNativeContext(context);
+ const promise = capability.promise;
+ const resolve = capability.resolve;
+ const reject = capability.reject;
+
+ // For catch prediction, don't treat the .then calls as handling it;
+ // instead, recurse outwards.
+ if (IsDebugActive()) deferred {
+ SetPropertyStrict(context, reject, kPromiseForwardingHandlerSymbol, True);
+ }
- const resolveElementContext =
- CreatePromiseAllResolveElementContext(capability, nativeContext);
+ const resolveElementContext =
+ CreatePromiseAllResolveElementContext(capability, nativeContext);
- let index: Smi = 1;
+ let index: Smi = 1;
- // We can skip the "resolve" lookup on {constructor} if it's the
- // Promise constructor and the Promise.resolve protector is intact,
- // as that guards the lookup path for the "resolve" property on the
- // Promise constructor.
- let promiseResolveFunction: JSAny = Undefined;
+ // We can skip the "resolve" lookup on {constructor} if it's the
+ // Promise constructor and the Promise.resolve protector is intact,
+ // as that guards the lookup path for the "resolve" property on the
+ // Promise constructor.
+ let promiseResolveFunction: JSAny = Undefined;
+ try {
try {
- try {
- if (!IsPromiseResolveLookupChainIntact(nativeContext, constructor)) {
- // 5. Let _promiseResolve_ be ? Get(_constructor_, `"resolve"`).
- let promiseResolve: JSAny;
- try {
- promiseResolve = GetProperty(constructor, kResolveString);
- } catch (e) deferred {
- iterator::IteratorCloseOnException(iter, e) otherwise Reject;
- }
-
- // 6. If IsCallable(_promiseResolve_) is *false*, throw a *TypeError*
- // exception.
- promiseResolveFunction = Cast<Callable>(promiseResolve)
- otherwise ThrowTypeError(
- MessageTemplate::kCalledNonCallable, 'resolve');
- }
+ if (!IsPromiseResolveLookupChainIntact(nativeContext, constructor)) {
+ let promiseResolve: JSAny;
+
+ // 5. Let _promiseResolve_ be ? Get(_constructor_, `"resolve"`).
+ promiseResolve = GetProperty(constructor, kResolveString);
- const fastIteratorResultMap = UnsafeCast<Map>(
- nativeContext[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]);
- while (true) {
- let nextValue: JSAny;
+ // 6. If IsCallable(_promiseResolve_) is *false*, throw a *TypeError*
+ // exception.
+ promiseResolveFunction =
+ Cast<Callable>(promiseResolve) otherwise ThrowTypeError(
+ MessageTemplate::kCalledNonCallable, 'resolve');
+ }
+ const fastIteratorResultMap = UnsafeCast<Map>(
+ nativeContext[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]);
+ while (true) {
+ let nextValue: JSAny;
+ try {
// Let next be IteratorStep(iteratorRecord.[[Iterator]]).
// If next is an abrupt completion, set iteratorRecord.[[Done]] to
// true. ReturnIfAbrupt(next).
@@ -176,209 +171,207 @@ namespace promise {
// to true.
// ReturnIfAbrupt(nextValue).
nextValue = iterator::IteratorValue(next, fastIteratorResultMap);
+ } catch (e) {
+ goto Reject(e);
+ }
- // Check if we reached the limit.
- if (index == kPropertyArrayHashFieldMax) {
- // If there are too many elements (currently more than 2**21-1),
- // raise a RangeError here (which is caught directly and turned into
- // a rejection) of the resulting promise. We could gracefully handle
- // this case as well and support more than this number of elements
- // by going to a separate function and pass the larger indices via a
- // separate context, but it doesn't seem likely that we need this,
- // and it's unclear how the rest of the system deals with 2**21 live
- // Promises anyways.
- try {
- ThrowRangeError(MessageTemplate::kTooManyElementsInPromiseAll);
- } catch (e) deferred {
- iterator::IteratorCloseOnException(iter, e) otherwise Reject;
- }
- }
-
- // Set remainingElementsCount.[[Value]] to
- // remainingElementsCount.[[Value]] + 1.
- const remainingElementsCount =
- UnsafeCast<Smi>(resolveElementContext
- [PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementRemainingSlot]);
- resolveElementContext[PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementRemainingSlot] =
- remainingElementsCount + 1;
-
- // Let resolveElement be CreateBuiltinFunction(steps,
- // « [[AlreadyCalled]],
- // [[Index]],
- // [[Values]],
- // [[Capability]],
- // [[RemainingElements]]
- // »).
- // Set resolveElement.[[AlreadyCalled]] to a Record { [[Value]]: false
- // }. Set resolveElement.[[Index]] to index. Set
- // resolveElement.[[Values]] to values. Set
- // resolveElement.[[Capability]] to resultCapability. Set
- // resolveElement.[[RemainingElements]] to remainingElementsCount.
- const resolveElementFun = createResolveElementFunctor.Call(
- resolveElementContext, nativeContext, index, capability);
- const rejectElementFun = createRejectElementFunctor.Call(
- resolveElementContext, nativeContext, index, capability);
-
- // We can skip the "resolve" lookup on the {constructor} as well as
- // the "then" lookup on the result of the "resolve" call, and
- // immediately chain continuation onto the {next_value} if:
- //
- // (a) The {constructor} is the intrinsic %Promise% function, and
- // looking up "resolve" on {constructor} yields the initial
- // Promise.resolve() builtin, and
- // (b) the promise @@species protector cell is valid, meaning that
- // no one messed with the Symbol.species property on any
- // intrinsic promise or on the Promise.prototype, and
- // (c) the {next_value} is a JSPromise whose [[Prototype]] field
- // contains the intrinsic %PromisePrototype%, and
- // (d) we're not running with async_hooks or DevTools enabled.
- //
- // In that case we also don't need to allocate a chained promise for
- // the PromiseReaction (aka we can pass undefined to
- // PerformPromiseThen), since this is only necessary for DevTools and
- // PromiseHooks.
- if (promiseResolveFunction != Undefined ||
- IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() ||
- IsPromiseSpeciesProtectorCellInvalid() || Is<Smi>(nextValue) ||
- !IsPromiseThenLookupChainIntact(
- nativeContext, UnsafeCast<HeapObject>(nextValue).map)) {
- try {
- // Let nextPromise be ? Call(constructor, _promiseResolve_, «
- // nextValue »).
- const nextPromise = CallResolve(
- UnsafeCast<Constructor>(constructor), promiseResolveFunction,
- nextValue);
-
- // Perform ? Invoke(nextPromise, "then", « resolveElement,
- // resultCapability.[[Reject]] »).
- const then = GetProperty(nextPromise, kThenString);
- const thenResult = Call(
- nativeContext, then, nextPromise, resolveElementFun,
- rejectElementFun);
-
- // For catch prediction, mark that rejections here are
- // semantically handled by the combined Promise.
- if (IsDebugActive() && Is<JSPromise>(thenResult)) deferred {
- SetPropertyStrict(
- context, thenResult, kPromiseHandledBySymbol, promise);
- }
- } catch (e) deferred {
- iterator::IteratorCloseOnException(iter, e) otherwise Reject;
+ // Check if we reached the limit.
+ if (index == kPropertyArrayHashFieldMax) {
+ // If there are too many elements (currently more than 2**21-1),
+ // raise a RangeError here (which is caught below and turned into
+ // a rejection of the resulting promise). We could gracefully handle
+ // this case as well and support more than this number of elements
+ // by going to a separate function and pass the larger indices via a
+ // separate context, but it doesn't seem likely that we need this,
+ // and it's unclear how the rest of the system deals with 2**21 live
+ // Promises anyway.
+ ThrowRangeError(
+ MessageTemplate::kTooManyElementsInPromiseCombinator, 'all');
+ }
+
+ // Set remainingElementsCount.[[Value]] to
+ // remainingElementsCount.[[Value]] + 1.
+ const remainingElementsCount = UnsafeCast<Smi>(
+ resolveElementContext[PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementRemainingSlot]);
+ resolveElementContext[PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementRemainingSlot] =
+ remainingElementsCount + 1;
+
+ // Let resolveElement be CreateBuiltinFunction(steps,
+ // « [[AlreadyCalled]],
+ // [[Index]],
+ // [[Values]],
+ // [[Capability]],
+ // [[RemainingElements]]
+ // »).
+ // Set resolveElement.[[AlreadyCalled]] to a Record { [[Value]]: false
+ // }. Set resolveElement.[[Index]] to index. Set
+ // resolveElement.[[Values]] to values. Set
+ // resolveElement.[[Capability]] to resultCapability. Set
+ // resolveElement.[[RemainingElements]] to remainingElementsCount.
+ const resolveElementFun = createResolveElementFunctor.Call(
+ resolveElementContext, nativeContext, index, capability);
+ const rejectElementFun = createRejectElementFunctor.Call(
+ resolveElementContext, nativeContext, index, capability);
+
+ // We can skip the "resolve" lookup on the {constructor} as well as
+ // the "then" lookup on the result of the "resolve" call, and
+ // immediately chain continuation onto the {next_value} if:
+ //
+ // (a) The {constructor} is the intrinsic %Promise% function, and
+ // looking up "resolve" on {constructor} yields the initial
+ // Promise.resolve() builtin, and
+ // (b) the promise @@species protector cell is valid, meaning that
+ // no one messed with the Symbol.species property on any
+ // intrinsic promise or on the Promise.prototype, and
+ // (c) the {next_value} is a JSPromise whose [[Prototype]] field
+ // contains the intrinsic %PromisePrototype%, and
+ // (d) we're not running with async_hooks or DevTools enabled.
+ //
+ // In that case we also don't need to allocate a chained promise for
+ // the PromiseReaction (aka we can pass undefined to
+ // PerformPromiseThen), since this is only necessary for DevTools and
+ // PromiseHooks.
+ if (promiseResolveFunction != Undefined ||
+ IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() ||
+ IsPromiseSpeciesProtectorCellInvalid() || Is<Smi>(nextValue) ||
+ !IsPromiseThenLookupChainIntact(
+ nativeContext, UnsafeCast<HeapObject>(nextValue).map)) {
+ // Let nextPromise be ? Call(constructor, _promiseResolve_, «
+ // nextValue »).
+ const nextPromise = CallResolve(
+ UnsafeCast<Constructor>(constructor), promiseResolveFunction,
+ nextValue);
+
+ // Perform ? Invoke(nextPromise, "then", « resolveElement,
+ // resultCapability.[[Reject]] »).
+ const then = GetProperty(nextPromise, kThenString);
+ const thenResult = Call(
+ nativeContext, then, nextPromise, resolveElementFun,
+ rejectElementFun);
+
+ // For catch prediction, mark that rejections here are
+ // semantically handled by the combined Promise.
+ if (IsDebugActive() && Is<JSPromise>(thenResult)) deferred {
+ SetPropertyStrict(
+ context, thenResult, kPromiseHandledBySymbol, promise);
}
- } else {
- PerformPromiseThenImpl(
- UnsafeCast<JSPromise>(nextValue), resolveElementFun,
- rejectElementFun, Undefined);
- }
-
- // Set index to index + 1.
- index += 1;
+ } else {
+ PerformPromiseThenImpl(
+ UnsafeCast<JSPromise>(nextValue), resolveElementFun,
+ rejectElementFun, Undefined);
}
+
+ // Set index to index + 1.
+ index += 1;
}
+ } catch (e) deferred {
+ iterator::IteratorCloseOnException(iter);
+ goto Reject(e);
}
- label Done {}
-
- // Set iteratorRecord.[[Done]] to true.
- // Set remainingElementsCount.[[Value]] to
- // remainingElementsCount.[[Value]] - 1.
- let remainingElementsCount = UnsafeCast<Smi>(
+ } label Done {}
+
+ // Set iteratorRecord.[[Done]] to true.
+ // Set remainingElementsCount.[[Value]] to
+ // remainingElementsCount.[[Value]] - 1.
+ let remainingElementsCount = UnsafeCast<Smi>(
+ resolveElementContext[PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementRemainingSlot]);
+ remainingElementsCount -= 1;
+ resolveElementContext[PromiseAllResolveElementContextSlots::
+ kPromiseAllResolveElementRemainingSlot] =
+ remainingElementsCount;
+ if (remainingElementsCount > 0) {
+ // Pre-allocate the backing store for the {values_array} to the desired
+ // capacity here. We may already have elements here in case of some
+ // fancy Thenable that calls the resolve callback immediately, so we need
+ // to handle that correctly here.
+ const valuesArray = UnsafeCast<JSArray>(
resolveElementContext[PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementRemainingSlot]);
- remainingElementsCount -= 1;
- resolveElementContext[PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementRemainingSlot] =
- remainingElementsCount;
- if (remainingElementsCount > 0) {
- // Pre-allocate the backing store for the {values_array} to the desired
- // capacity here. We may already have elements here in case of some
- // fancy Thenable that calls the resolve callback immediately, so we need
- // to handle that correctly here.
- const valuesArray = UnsafeCast<JSArray>(
+ kPromiseAllResolveElementValuesArraySlot]);
+ const oldElements = UnsafeCast<FixedArray>(valuesArray.elements);
+ const oldCapacity = oldElements.length_intptr;
+ const newCapacity = SmiUntag(index);
+ if (oldCapacity < newCapacity) {
+ valuesArray.elements =
+ ExtractFixedArray(oldElements, 0, oldCapacity, newCapacity);
+ }
+ } else
+ deferred {
+ // If remainingElementsCount.[[Value]] is 0, then
+ // Let valuesArray be CreateArrayFromList(values).
+ // Perform ? Call(resultCapability.[[Resolve]], undefined,
+ // « valuesArray »).
+ assert(remainingElementsCount == 0);
+ const valuesArray = UnsafeCast<JSAny>(
resolveElementContext[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesArraySlot]);
- const oldElements = UnsafeCast<FixedArray>(valuesArray.elements);
- const oldCapacity = oldElements.length_intptr;
- const newCapacity = SmiUntag(index);
- if (oldCapacity < newCapacity) {
- valuesArray.elements =
- ExtractFixedArray(oldElements, 0, oldCapacity, newCapacity);
- }
- } else
- deferred {
- // If remainingElementsCount.[[Value]] is 0, then
- // Let valuesArray be CreateArrayFromList(values).
- // Perform ? Call(resultCapability.[[Resolve]], undefined,
- // « valuesArray »).
- assert(remainingElementsCount == 0);
- const valuesArray = UnsafeCast<JSAny>(
- resolveElementContext
- [PromiseAllResolveElementContextSlots::
- kPromiseAllResolveElementValuesArraySlot]);
- Call(nativeContext, UnsafeCast<JSAny>(resolve), Undefined, valuesArray);
- }
-
- // Return resultCapability.[[Promise]].
- return promise;
- }
+ Call(nativeContext, UnsafeCast<JSAny>(resolve), Undefined, valuesArray);
+ }
- transitioning macro GeneratePromiseAll<F1: type, F2: type>(implicit context:
- Context)(
- receiver: JSAny, iterable: JSAny, createResolveElementFunctor: F1,
- createRejectElementFunctor: F2): JSAny {
- // Let C be the this value.
- // If Type(C) is not Object, throw a TypeError exception.
- const receiver = Cast<JSReceiver>(receiver)
- otherwise ThrowTypeError(
- MessageTemplate::kCalledOnNonObject, 'Promise.all');
-
- // Let promiseCapability be ? NewPromiseCapability(C).
- // Don't fire debugEvent so that forwarding the rejection through all does
- // not trigger redundant ExceptionEvents
- const capability = NewPromiseCapability(receiver, False);
+ // Return resultCapability.[[Promise]].
+ return promise;
+}
- try {
- try {
- // Let iterator be GetIterator(iterable).
- // IfAbruptRejectPromise(iterator, promiseCapability).
- let i = iterator::GetIterator(iterable);
-
- // Let result be PerformPromiseAll(iteratorRecord, C,
- // promiseCapability). If result is an abrupt completion, then
- // If iteratorRecord.[[Done]] is false, let result be
- // IteratorClose(iterator, result).
- // IfAbruptRejectPromise(result, promiseCapability).
- return PerformPromiseAll(
- receiver, capability, i, createResolveElementFunctor,
- createRejectElementFunctor) otherwise Reject;
- } catch (e) deferred {
- goto Reject(e);
- }
- }
- label Reject(e: Object) deferred {
- // Exception must be bound to a JS value.
- const e = UnsafeCast<JSAny>(e);
- const reject = UnsafeCast<JSAny>(capability.reject);
- Call(context, reject, Undefined, e);
- return capability.promise;
- }
+transitioning macro GeneratePromiseAll<F1: type, F2: type>(
+ implicit context: Context)(
+ receiver: JSAny, iterable: JSAny, createResolveElementFunctor: F1,
+ createRejectElementFunctor: F2): JSAny {
+ // Let C be the this value.
+ // If Type(C) is not Object, throw a TypeError exception.
+ const receiver = Cast<JSReceiver>(receiver)
+ otherwise ThrowTypeError(MessageTemplate::kCalledOnNonObject, 'Promise.all');
+
+ // Let promiseCapability be ? NewPromiseCapability(C).
+ // Don't fire debugEvent so that forwarding the rejection through all does
+ // not trigger redundant ExceptionEvents
+ const capability = NewPromiseCapability(receiver, False);
+
+ try {
+ // Let iterator be GetIterator(iterable).
+ // IfAbruptRejectPromise(iterator, promiseCapability).
+ let i = iterator::GetIterator(iterable);
+
+ // Let result be PerformPromiseAll(iteratorRecord, C,
+ // promiseCapability). If result is an abrupt completion, then
+ // If iteratorRecord.[[Done]] is false, let result be
+ // IteratorClose(iterator, result).
+ // IfAbruptRejectPromise(result, promiseCapability).
+ return PerformPromiseAll(
+ receiver, capability, i, createResolveElementFunctor,
+ createRejectElementFunctor) otherwise Reject;
+ } catch (e) deferred {
+ goto Reject(e);
+ } label Reject(e: Object) deferred {
+ // Exception must be bound to a JS value.
+ const e = UnsafeCast<JSAny>(e);
+ const reject = UnsafeCast<JSAny>(capability.reject);
+ Call(context, reject, Undefined, e);
+ return capability.promise;
}
+}
- // ES#sec-promise.all
- transitioning javascript builtin PromiseAll(
- js-implicit context: Context, receiver: JSAny)(iterable: JSAny): JSAny {
- return GeneratePromiseAll(
- receiver, iterable, PromiseAllResolveElementFunctor{},
- PromiseAllRejectElementFunctor{});
- }
+// ES#sec-promise.all
+transitioning javascript builtin PromiseAll(
+ js-implicit context: Context, receiver: JSAny)(iterable: JSAny): JSAny {
+ return GeneratePromiseAll(
+ receiver, iterable, PromiseAllResolveElementFunctor{},
+ PromiseAllRejectElementFunctor{});
+}
- // ES#sec-promise.allsettled
- // Promise.allSettled ( iterable )
- transitioning javascript builtin PromiseAllSettled(
- js-implicit context: Context, receiver: JSAny)(iterable: JSAny): JSAny {
- return GeneratePromiseAll(
- receiver, iterable, PromiseAllSettledResolveElementFunctor{},
- PromiseAllSettledRejectElementFunctor{});
- }
+// ES#sec-promise.allsettled
+// Promise.allSettled ( iterable )
+transitioning javascript builtin PromiseAllSettled(
+ js-implicit context: Context, receiver: JSAny)(iterable: JSAny): JSAny {
+ return GeneratePromiseAll(
+ receiver, iterable, PromiseAllSettledResolveElementFunctor{},
+ PromiseAllSettledRejectElementFunctor{});
+}
+
+extern macro PromiseAllResolveElementSharedFunConstant(): SharedFunctionInfo;
+extern macro PromiseAllSettledRejectElementSharedFunConstant():
+ SharedFunctionInfo;
+extern macro PromiseAllSettledResolveElementSharedFunConstant():
+ SharedFunctionInfo;
}