5 #include "src/builtins/builtins-promise-gen.h" 7 #include "src/builtins/builtins-constructor-gen.h" 8 #include "src/builtins/builtins-iterator-gen.h" 9 #include "src/builtins/builtins-utils-gen.h" 10 #include "src/builtins/builtins.h" 11 #include "src/code-factory.h" 12 #include "src/code-stub-assembler.h" 13 #include "src/objects-inl.h" 14 #include "src/objects/js-promise.h" 15 #include "src/objects/smi.h" 21 using IteratorRecord = IteratorBuiltinsAssembler::IteratorRecord;
23 Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) {
24 Node*
const native_context = LoadNativeContext(context);
25 Node*
const promise_fun =
26 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
27 CSA_ASSERT(
this, IsFunctionWithPrototypeSlotMap(LoadMap(promise_fun)));
28 Node*
const promise_map =
29 LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
30 Node*
const promise = Allocate(JSPromise::kSizeWithEmbedderFields);
31 StoreMapNoWriteBarrier(promise, promise_map);
32 StoreObjectFieldRoot(promise, JSPromise::kPropertiesOrHashOffset,
33 RootIndex::kEmptyFixedArray);
34 StoreObjectFieldRoot(promise, JSPromise::kElementsOffset,
35 RootIndex::kEmptyFixedArray);
39 void PromiseBuiltinsAssembler::PromiseInit(Node* promise) {
40 STATIC_ASSERT(v8::Promise::kPending == 0);
41 StoreObjectFieldNoWriteBarrier(promise, JSPromise::kReactionsOrResultOffset,
42 SmiConstant(Smi::zero()));
43 StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
44 SmiConstant(Smi::zero()));
45 for (
int offset = JSPromise::kSize;
46 offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
47 StoreObjectFieldNoWriteBarrier(promise, offset, SmiConstant(Smi::zero()));
51 Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context) {
52 return AllocateAndInitJSPromise(context, UndefinedConstant());
55 Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context,
57 Node*
const instance = AllocateJSPromise(context);
58 PromiseInit(instance);
61 GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &out);
62 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
69 Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(
71 DCHECK_NE(Promise::kPending, status);
73 Node*
const instance = AllocateJSPromise(context);
74 StoreObjectFieldNoWriteBarrier(instance, JSPromise::kReactionsOrResultOffset,
76 STATIC_ASSERT(JSPromise::kStatusShift == 0);
77 StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset,
79 for (
int offset = JSPromise::kSize;
80 offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
81 StoreObjectFieldNoWriteBarrier(instance, offset, SmiConstant(0));
85 GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &out);
86 CallRuntime(Runtime::kPromiseHookInit, context, instance,
94 std::pair<Node*, Node*>
95 PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions(
96 Node* promise, Node* debug_event, Node* native_context) {
97 Node*
const promise_context = CreatePromiseResolvingFunctionsContext(
98 promise, debug_event, native_context);
99 Node*
const map = LoadContextElement(
100 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
101 Node*
const resolve_info = LoadContextElement(
103 Context::PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX);
104 Node*
const resolve =
105 AllocateFunctionWithMapAndContext(map, resolve_info, promise_context);
106 Node*
const reject_info = LoadContextElement(
108 Context::PROMISE_CAPABILITY_DEFAULT_REJECT_SHARED_FUN_INDEX);
110 AllocateFunctionWithMapAndContext(map, reject_info, promise_context);
111 return std::make_pair(resolve, reject);
115 TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) {
116 Node*
const context = Parameter(Descriptor::kContext);
117 Node*
const constructor = Parameter(Descriptor::kConstructor);
118 Node*
const debug_event = Parameter(Descriptor::kDebugEvent);
119 TNode<Context>
const native_context = LoadNativeContext(context);
121 Label if_not_constructor(
this, Label::kDeferred),
122 if_notcallable(
this, Label::kDeferred), if_fast_promise_capability(
this),
123 if_slow_promise_capability(
this, Label::kDeferred);
124 GotoIf(TaggedIsSmi(constructor), &if_not_constructor);
125 GotoIfNot(IsConstructorMap(LoadMap(constructor)), &if_not_constructor);
126 Branch(WordEqual(constructor,
127 LoadContextElement(native_context,
128 Context::PROMISE_FUNCTION_INDEX)),
129 &if_fast_promise_capability, &if_slow_promise_capability);
131 BIND(&if_fast_promise_capability);
134 AllocateAndInitJSPromise(native_context, UndefinedConstant());
136 Node* resolve =
nullptr;
137 Node* reject =
nullptr;
138 std::tie(resolve, reject) =
139 CreatePromiseResolvingFunctions(promise, debug_event, native_context);
141 Node* capability = Allocate(PromiseCapability::kSize);
142 StoreMapNoWriteBarrier(capability, RootIndex::kPromiseCapabilityMap);
143 StoreObjectFieldNoWriteBarrier(capability,
144 PromiseCapability::kPromiseOffset, promise);
145 StoreObjectFieldNoWriteBarrier(capability,
146 PromiseCapability::kResolveOffset, resolve);
147 StoreObjectFieldNoWriteBarrier(capability, PromiseCapability::kRejectOffset,
152 BIND(&if_slow_promise_capability);
154 Node* capability = Allocate(PromiseCapability::kSize);
155 StoreMapNoWriteBarrier(capability, RootIndex::kPromiseCapabilityMap);
156 StoreObjectFieldRoot(capability, PromiseCapability::kPromiseOffset,
157 RootIndex::kUndefinedValue);
158 StoreObjectFieldRoot(capability, PromiseCapability::kResolveOffset,
159 RootIndex::kUndefinedValue);
160 StoreObjectFieldRoot(capability, PromiseCapability::kRejectOffset,
161 RootIndex::kUndefinedValue);
163 Node* executor_context =
164 CreatePromiseGetCapabilitiesExecutorContext(capability, native_context);
165 Node* executor_info = LoadContextElement(
166 native_context, Context::PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN);
167 Node* function_map = LoadContextElement(
168 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
169 TNode<JSFunction> executor = CAST(AllocateFunctionWithMapAndContext(
170 function_map, executor_info, executor_context));
172 Node* promise = Construct(native_context, CAST(constructor), executor);
173 StoreObjectField(capability, PromiseCapability::kPromiseOffset, promise);
176 LoadObjectField(capability, PromiseCapability::kResolveOffset);
177 GotoIf(TaggedIsSmi(resolve), &if_notcallable);
178 GotoIfNot(IsCallable(resolve), &if_notcallable);
181 LoadObjectField(capability, PromiseCapability::kRejectOffset);
182 GotoIf(TaggedIsSmi(reject), &if_notcallable);
183 GotoIfNot(IsCallable(reject), &if_notcallable);
187 BIND(&if_not_constructor);
188 ThrowTypeError(context, MessageTemplate::kNotConstructor, constructor);
190 BIND(&if_notcallable);
191 ThrowTypeError(context, MessageTemplate::kPromiseNonCallable);
194 Node* PromiseBuiltinsAssembler::CreatePromiseContext(Node* native_context,
196 DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS);
198 Node*
const context = AllocateInNewSpace(FixedArray::SizeFor(slots));
199 InitializeFunctionContext(native_context, context, slots);
203 Node* PromiseBuiltinsAssembler::CreatePromiseAllResolveElementContext(
204 Node* promise_capability, Node* native_context) {
205 CSA_ASSERT(
this, IsNativeContext(native_context));
208 TNode<Map> array_map = CAST(LoadContextElement(
209 native_context, Context::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX));
210 TNode<JSArray> values_array = AllocateJSArray(
211 PACKED_ELEMENTS, array_map, IntPtrConstant(0), SmiConstant(0));
213 Node*
const context =
214 CreatePromiseContext(native_context, kPromiseAllResolveElementLength);
215 StoreContextElementNoWriteBarrier(
216 context, kPromiseAllResolveElementRemainingSlot, SmiConstant(1));
217 StoreContextElementNoWriteBarrier(
218 context, kPromiseAllResolveElementCapabilitySlot, promise_capability);
219 StoreContextElementNoWriteBarrier(
220 context, kPromiseAllResolveElementValuesArraySlot, values_array);
225 Node* PromiseBuiltinsAssembler::CreatePromiseAllResolveElementFunction(
226 Node* context, TNode<Smi> index, Node* native_context) {
227 CSA_ASSERT(
this, SmiGreaterThan(index, SmiConstant(0)));
228 CSA_ASSERT(
this, SmiLessThanOrEqual(
229 index, SmiConstant(PropertyArray::HashField::kMax)));
230 CSA_ASSERT(
this, IsNativeContext(native_context));
232 Node*
const map = LoadContextElement(
233 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
234 Node*
const resolve_info = LoadContextElement(
235 native_context, Context::PROMISE_ALL_RESOLVE_ELEMENT_SHARED_FUN);
236 Node*
const resolve =
237 AllocateFunctionWithMapAndContext(map, resolve_info, context);
239 STATIC_ASSERT(PropertyArray::kNoHashSentinel == 0);
240 StoreObjectFieldNoWriteBarrier(resolve, JSFunction::kPropertiesOrHashOffset,
246 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
247 Node* promise, Node* debug_event, Node* native_context) {
248 Node*
const context =
249 CreatePromiseContext(native_context, kPromiseContextLength);
250 StoreContextElementNoWriteBarrier(context, kPromiseSlot, promise);
251 StoreContextElementNoWriteBarrier(context, kAlreadyResolvedSlot,
253 StoreContextElementNoWriteBarrier(context, kDebugEventSlot, debug_event);
257 Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext(
258 Node* promise_capability, Node* native_context) {
259 int kContextLength = kCapabilitiesContextLength;
260 Node* context = CreatePromiseContext(native_context, kContextLength);
261 StoreContextElementNoWriteBarrier(context, kCapabilitySlot,
266 Node* PromiseBuiltinsAssembler::PromiseHasHandler(Node* promise) {
267 Node*
const flags = LoadObjectField(promise, JSPromise::kFlagsOffset);
268 return IsSetWord(SmiUntag(flags), 1 << JSPromise::kHasHandlerBit);
271 void PromiseBuiltinsAssembler::PromiseSetHasHandler(Node* promise) {
272 TNode<Smi>
const flags =
273 CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
274 TNode<Smi>
const new_flags =
275 SmiOr(flags, SmiConstant(1 << JSPromise::kHasHandlerBit));
276 StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset, new_flags);
279 Node* PromiseBuiltinsAssembler::IsPromiseStatus(
281 return Word32Equal(actual, Int32Constant(expected));
284 Node* PromiseBuiltinsAssembler::PromiseStatus(Node* promise) {
285 STATIC_ASSERT(JSPromise::kStatusShift == 0);
286 TNode<Smi>
const flags =
287 CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
288 return Word32And(SmiToInt32(flags), Int32Constant(JSPromise::kStatusMask));
291 void PromiseBuiltinsAssembler::PromiseSetStatus(
294 IsPromiseStatus(PromiseStatus(promise), v8::Promise::kPending));
295 CHECK_NE(status, v8::Promise::kPending);
297 TNode<Smi> mask = SmiConstant(status);
298 TNode<Smi>
const flags =
299 CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
300 StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
304 void PromiseBuiltinsAssembler::PromiseSetHandledHint(Node* promise) {
305 TNode<Smi>
const flags =
306 CAST(LoadObjectField(promise, JSPromise::kFlagsOffset));
307 TNode<Smi>
const new_flags =
308 SmiOr(flags, SmiConstant(1 << JSPromise::kHandledHintBit));
309 StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset, new_flags);
313 void PromiseBuiltinsAssembler::PerformPromiseThen(
314 Node* context, Node* promise, Node* on_fulfilled, Node* on_rejected,
315 Node* result_promise_or_capability) {
316 CSA_ASSERT(
this, TaggedIsNotSmi(promise));
317 CSA_ASSERT(
this, IsJSPromise(promise));
319 Word32Or(IsCallable(on_fulfilled), IsUndefined(on_fulfilled)));
320 CSA_ASSERT(
this, Word32Or(IsCallable(on_rejected), IsUndefined(on_rejected)));
321 CSA_ASSERT(
this, TaggedIsNotSmi(result_promise_or_capability));
324 Word32Or(Word32Or(IsJSPromise(result_promise_or_capability),
325 IsPromiseCapability(result_promise_or_capability)),
326 IsUndefined(result_promise_or_capability)));
328 Label if_pending(
this), if_notpending(
this), done(
this);
329 Node*
const status = PromiseStatus(promise);
330 Branch(IsPromiseStatus(status, v8::Promise::kPending), &if_pending,
339 Node*
const promise_reactions =
340 LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
341 Node*
const reaction =
342 AllocatePromiseReaction(promise_reactions, result_promise_or_capability,
343 on_fulfilled, on_rejected);
344 StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, reaction);
348 BIND(&if_notpending);
350 VARIABLE(var_map, MachineRepresentation::kTagged);
351 VARIABLE(var_handler, MachineRepresentation::kTagged);
352 Label if_fulfilled(
this), if_rejected(
this, Label::kDeferred),
354 Branch(IsPromiseStatus(status, v8::Promise::kFulfilled), &if_fulfilled,
359 var_map.Bind(LoadRoot(RootIndex::kPromiseFulfillReactionJobTaskMap));
360 var_handler.Bind(on_fulfilled);
366 CSA_ASSERT(
this, IsPromiseStatus(status, v8::Promise::kRejected));
367 var_map.Bind(LoadRoot(RootIndex::kPromiseRejectReactionJobTaskMap));
368 var_handler.Bind(on_rejected);
369 GotoIf(PromiseHasHandler(promise), &enqueue);
370 CallRuntime(Runtime::kPromiseRevokeReject, context, promise);
376 LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
377 Node* microtask = AllocatePromiseReactionJobTask(
378 var_map.value(), context, argument, var_handler.value(),
379 result_promise_or_capability);
380 CallBuiltin(Builtins::kEnqueueMicrotask, context, microtask);
385 PromiseSetHasHandler(promise);
389 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) {
390 Node*
const context = Parameter(Descriptor::kContext);
391 Node*
const promise = Parameter(Descriptor::kPromise);
392 Node*
const on_fulfilled = Parameter(Descriptor::kOnFulfilled);
393 Node*
const on_rejected = Parameter(Descriptor::kOnRejected);
394 Node*
const result_promise = Parameter(Descriptor::kResultPromise);
396 CSA_ASSERT(
this, TaggedIsNotSmi(result_promise));
398 this, Word32Or(IsJSPromise(result_promise), IsUndefined(result_promise)));
400 PerformPromiseThen(context, promise, on_fulfilled, on_rejected,
402 Return(result_promise);
405 Node* PromiseBuiltinsAssembler::AllocatePromiseReaction(
406 Node* next, Node* promise_or_capability, Node* fulfill_handler,
407 Node* reject_handler) {
408 Node*
const reaction = Allocate(PromiseReaction::kSize);
409 StoreMapNoWriteBarrier(reaction, RootIndex::kPromiseReactionMap);
410 StoreObjectFieldNoWriteBarrier(reaction, PromiseReaction::kNextOffset, next);
411 StoreObjectFieldNoWriteBarrier(reaction,
412 PromiseReaction::kPromiseOrCapabilityOffset,
413 promise_or_capability);
414 StoreObjectFieldNoWriteBarrier(
415 reaction, PromiseReaction::kFulfillHandlerOffset, fulfill_handler);
416 StoreObjectFieldNoWriteBarrier(
417 reaction, PromiseReaction::kRejectHandlerOffset, reject_handler);
421 Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
422 Node* map, Node* context, Node* argument, Node* handler,
423 Node* promise_or_capability) {
424 Node*
const microtask = Allocate(PromiseReactionJobTask::kSize);
425 StoreMapNoWriteBarrier(microtask, map);
426 StoreObjectFieldNoWriteBarrier(
427 microtask, PromiseReactionJobTask::kArgumentOffset, argument);
428 StoreObjectFieldNoWriteBarrier(
429 microtask, PromiseReactionJobTask::kContextOffset, context);
430 StoreObjectFieldNoWriteBarrier(
431 microtask, PromiseReactionJobTask::kHandlerOffset, handler);
432 StoreObjectFieldNoWriteBarrier(
433 microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset,
434 promise_or_capability);
438 Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
439 RootIndex map_root_index, Node* context, Node* argument, Node* handler,
440 Node* promise_or_capability) {
441 DCHECK(map_root_index == RootIndex::kPromiseFulfillReactionJobTaskMap ||
442 map_root_index == RootIndex::kPromiseRejectReactionJobTaskMap);
443 Node*
const map = LoadRoot(map_root_index);
444 return AllocatePromiseReactionJobTask(map, context, argument, handler,
445 promise_or_capability);
448 Node* PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask(
449 Node* promise_to_resolve, Node* then, Node* thenable, Node* context) {
450 Node*
const microtask = Allocate(PromiseResolveThenableJobTask::kSize);
451 StoreMapNoWriteBarrier(microtask,
452 RootIndex::kPromiseResolveThenableJobTaskMap);
453 StoreObjectFieldNoWriteBarrier(
454 microtask, PromiseResolveThenableJobTask::kContextOffset, context);
455 StoreObjectFieldNoWriteBarrier(
456 microtask, PromiseResolveThenableJobTask::kPromiseToResolveOffset,
458 StoreObjectFieldNoWriteBarrier(
459 microtask, PromiseResolveThenableJobTask::kThenOffset, then);
460 StoreObjectFieldNoWriteBarrier(
461 microtask, PromiseResolveThenableJobTask::kThenableOffset, thenable);
466 Node* PromiseBuiltinsAssembler::TriggerPromiseReactions(
467 Node* context, Node* reactions, Node* argument,
468 PromiseReaction::Type type) {
472 VARIABLE(var_current, MachineRepresentation::kTagged, reactions);
473 VARIABLE(var_reversed, MachineRepresentation::kTagged,
474 SmiConstant(Smi::zero()));
476 Label loop(
this, {&var_current, &var_reversed}), done_loop(
this);
480 Node* current = var_current.value();
481 GotoIf(TaggedIsSmi(current), &done_loop);
482 var_current.Bind(LoadObjectField(current, PromiseReaction::kNextOffset));
483 StoreObjectField(current, PromiseReaction::kNextOffset,
484 var_reversed.value());
485 var_reversed.Bind(current);
489 reactions = var_reversed.value();
495 VARIABLE(var_current, MachineRepresentation::kTagged, reactions);
497 Label loop(
this, {&var_current}), done_loop(
this);
501 Node* current = var_current.value();
502 GotoIf(TaggedIsSmi(current), &done_loop);
503 var_current.Bind(LoadObjectField(current, PromiseReaction::kNextOffset));
508 STATIC_ASSERT(PromiseReaction::kSize == PromiseReactionJobTask::kSize);
509 if (type == PromiseReaction::kFulfill) {
510 StoreMapNoWriteBarrier(current,
511 RootIndex::kPromiseFulfillReactionJobTaskMap);
512 StoreObjectField(current, PromiseReactionJobTask::kArgumentOffset,
514 StoreObjectField(current, PromiseReactionJobTask::kContextOffset,
516 STATIC_ASSERT(PromiseReaction::kFulfillHandlerOffset ==
517 PromiseReactionJobTask::kHandlerOffset);
518 STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
519 PromiseReactionJobTask::kPromiseOrCapabilityOffset);
522 LoadObjectField(current, PromiseReaction::kRejectHandlerOffset);
523 StoreMapNoWriteBarrier(current,
524 RootIndex::kPromiseRejectReactionJobTaskMap);
525 StoreObjectField(current, PromiseReactionJobTask::kArgumentOffset,
527 StoreObjectField(current, PromiseReactionJobTask::kContextOffset,
529 StoreObjectField(current, PromiseReactionJobTask::kHandlerOffset,
531 STATIC_ASSERT(PromiseReaction::kPromiseOrCapabilityOffset ==
532 PromiseReactionJobTask::kPromiseOrCapabilityOffset);
534 CallBuiltin(Builtins::kEnqueueMicrotask, context, current);
540 return UndefinedConstant();
543 template <
typename... TArgs>
544 Node* PromiseBuiltinsAssembler::InvokeThen(Node* native_context, Node* receiver,
546 CSA_ASSERT(
this, IsNativeContext(native_context));
548 VARIABLE(var_result, MachineRepresentation::kTagged);
549 Label if_fast(
this), if_slow(
this, Label::kDeferred), done(
this, &var_result);
550 GotoIf(TaggedIsSmi(receiver), &if_slow);
551 Node*
const receiver_map = LoadMap(receiver);
556 BranchIfPromiseThenLookupChainIntact(native_context, receiver_map, &if_fast,
562 LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
564 CallJS(CodeFactory::CallFunction(
565 isolate(), ConvertReceiverMode::kNotNullOrUndefined),
566 native_context, then, receiver, args...);
567 var_result.Bind(result);
573 Node*
const then = GetProperty(native_context, receiver,
574 isolate()->factory()->then_string());
575 Node*
const result = CallJS(
576 CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
577 native_context, then, receiver, args...);
578 var_result.Bind(result);
583 return var_result.value();
586 Node* PromiseBuiltinsAssembler::InvokeResolve(Node* native_context,
587 Node* constructor, Node* value,
589 Variable* var_exception) {
590 CSA_ASSERT(
this, IsNativeContext(native_context));
592 VARIABLE(var_result, MachineRepresentation::kTagged);
593 Label if_fast(
this), if_slow(
this, Label::kDeferred), done(
this, &var_result);
598 BranchIfPromiseResolveLookupChainIntact(native_context, constructor, &if_fast,
603 Node*
const result = CallBuiltin(Builtins::kPromiseResolve, native_context,
605 GotoIfException(result, if_exception, var_exception);
607 var_result.Bind(result);
613 Node*
const resolve =
614 GetProperty(native_context, constructor, factory()->resolve_string());
615 GotoIfException(resolve, if_exception, var_exception);
617 Node*
const result = CallJS(
618 CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
619 native_context, resolve, constructor, value);
620 GotoIfException(result, if_exception, var_exception);
622 var_result.Bind(result);
627 return var_result.value();
630 void PromiseBuiltinsAssembler::BranchIfPromiseResolveLookupChainIntact(
631 Node* native_context, Node* constructor, Label* if_fast, Label* if_slow) {
632 CSA_ASSERT(
this, IsNativeContext(native_context));
634 GotoIfForceSlowPath(if_slow);
635 Node*
const promise_fun =
636 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
637 GotoIfNot(WordEqual(promise_fun, constructor), if_slow);
638 Branch(IsPromiseResolveProtectorCellInvalid(), if_slow, if_fast);
641 void PromiseBuiltinsAssembler::GotoIfNotPromiseResolveLookupChainIntact(
642 Node* native_context, Node* constructor, Label* if_slow) {
644 BranchIfPromiseResolveLookupChainIntact(native_context, constructor, &if_fast,
649 void PromiseBuiltinsAssembler::BranchIfPromiseSpeciesLookupChainIntact(
650 Node* native_context, Node* promise_map, Label* if_fast, Label* if_slow) {
651 CSA_ASSERT(
this, IsNativeContext(native_context));
652 CSA_ASSERT(
this, IsJSPromiseMap(promise_map));
654 Node*
const promise_prototype =
655 LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
656 GotoIfForceSlowPath(if_slow);
657 GotoIfNot(WordEqual(LoadMapPrototype(promise_map), promise_prototype),
659 Branch(IsPromiseSpeciesProtectorCellInvalid(), if_slow, if_fast);
662 void PromiseBuiltinsAssembler::BranchIfPromiseThenLookupChainIntact(
663 Node* native_context, Node* receiver_map, Label* if_fast, Label* if_slow) {
664 CSA_ASSERT(
this, IsMap(receiver_map));
665 CSA_ASSERT(
this, IsNativeContext(native_context));
667 GotoIfForceSlowPath(if_slow);
668 GotoIfNot(IsJSPromiseMap(receiver_map), if_slow);
669 Node*
const promise_prototype =
670 LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
671 GotoIfNot(WordEqual(LoadMapPrototype(receiver_map), promise_prototype),
673 Branch(IsPromiseThenProtectorCellInvalid(), if_slow, if_fast);
676 void PromiseBuiltinsAssembler::BranchIfAccessCheckFailed(
677 Node* context, Node* native_context, Node* promise_constructor,
678 Node* executor, Label* if_noaccess) {
679 VARIABLE(var_executor, MachineRepresentation::kTagged);
680 var_executor.Bind(executor);
681 Label has_access(
this), call_runtime(
this, Label::kDeferred);
685 Label found_function(
this), loop_over_bound_function(
this, &var_executor);
686 Goto(&loop_over_bound_function);
687 BIND(&loop_over_bound_function);
689 Node* executor_type = LoadInstanceType(var_executor.value());
690 GotoIf(InstanceTypeEqual(executor_type, JS_FUNCTION_TYPE), &found_function);
691 GotoIfNot(InstanceTypeEqual(executor_type, JS_BOUND_FUNCTION_TYPE),
693 var_executor.Bind(LoadObjectField(
694 var_executor.value(), JSBoundFunction::kBoundTargetFunctionOffset));
695 Goto(&loop_over_bound_function);
701 BIND(&found_function);
703 Node* function_context =
704 LoadObjectField(var_executor.value(), JSFunction::kContextOffset);
705 Node* native_function_context = LoadNativeContext(function_context);
706 Branch(WordEqual(native_context, native_function_context), &has_access,
712 Branch(WordEqual(CallRuntime(Runtime::kAllowDynamicFunction, context,
713 promise_constructor),
715 &has_access, if_noaccess);
721 void PromiseBuiltinsAssembler::SetForwardingHandlerIfTrue(
722 Node* context, Node* condition,
const NodeGenerator&
object) {
724 GotoIfNot(condition, &done);
726 CAST(context), CAST(
object()),
727 HeapConstant(factory()->promise_forwarding_handler_symbol()),
733 void PromiseBuiltinsAssembler::SetPromiseHandledByIfTrue(
734 Node* context, Node* condition, Node* promise,
735 const NodeGenerator& handled_by) {
737 GotoIfNot(condition, &done);
738 GotoIf(TaggedIsSmi(promise), &done);
739 GotoIfNot(HasInstanceType(promise, JS_PROMISE_TYPE), &done);
740 SetPropertyStrict(CAST(context), CAST(promise),
741 HeapConstant(factory()->promise_handled_by_symbol()),
748 TF_BUILTIN(PromiseCapabilityDefaultReject, PromiseBuiltinsAssembler) {
749 Node*
const reason = Parameter(Descriptor::kReason);
750 Node*
const context = Parameter(Descriptor::kContext);
753 Node*
const promise = LoadContextElement(context, kPromiseSlot);
756 Label if_already_resolved(
this, Label::kDeferred);
757 Node*
const already_resolved =
758 LoadContextElement(context, kAlreadyResolvedSlot);
761 GotoIf(IsTrue(already_resolved), &if_already_resolved);
764 StoreContextElementNoWriteBarrier(context, kAlreadyResolvedSlot,
768 Node*
const debug_event = LoadContextElement(context, kDebugEventSlot);
769 Return(CallBuiltin(Builtins::kRejectPromise, context, promise, reason,
772 BIND(&if_already_resolved);
774 Return(CallRuntime(Runtime::kPromiseRejectAfterResolved, context, promise,
780 TF_BUILTIN(PromiseCapabilityDefaultResolve, PromiseBuiltinsAssembler) {
781 Node*
const resolution = Parameter(Descriptor::kResolution);
782 Node*
const context = Parameter(Descriptor::kContext);
785 Node*
const promise = LoadContextElement(context, kPromiseSlot);
788 Label if_already_resolved(
this, Label::kDeferred);
789 Node*
const already_resolved =
790 LoadContextElement(context, kAlreadyResolvedSlot);
793 GotoIf(IsTrue(already_resolved), &if_already_resolved);
796 StoreContextElementNoWriteBarrier(context, kAlreadyResolvedSlot,
801 Return(CallBuiltin(Builtins::kResolvePromise, context, promise, resolution));
803 BIND(&if_already_resolved);
805 Return(CallRuntime(Runtime::kPromiseResolveAfterResolved, context, promise,
810 TF_BUILTIN(PromiseConstructorLazyDeoptContinuation, PromiseBuiltinsAssembler) {
811 Node* promise = Parameter(Descriptor::kPromise);
812 Node* reject = Parameter(Descriptor::kReject);
813 Node* exception = Parameter(Descriptor::kException);
814 Node*
const context = Parameter(Descriptor::kContext);
818 GotoIf(IsTheHole(exception), &
finally);
819 CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
820 context, reject, UndefinedConstant(), exception);
828 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
829 Node*
const executor = Parameter(Descriptor::kExecutor);
830 Node*
const new_target = Parameter(Descriptor::kJSNewTarget);
831 Node*
const context = Parameter(Descriptor::kContext);
832 Isolate* isolate = this->isolate();
834 Label if_targetisundefined(
this, Label::kDeferred);
836 GotoIf(IsUndefined(new_target), &if_targetisundefined);
838 Label if_notcallable(
this, Label::kDeferred);
840 GotoIf(TaggedIsSmi(executor), &if_notcallable);
842 Node*
const executor_map = LoadMap(executor);
843 GotoIfNot(IsCallableMap(executor_map), &if_notcallable);
845 Node*
const native_context = LoadNativeContext(context);
846 Node*
const promise_fun =
847 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
848 Node*
const is_debug_active = IsDebugActive();
849 Label if_targetisnotmodified(
this),
850 if_targetismodified(
this, Label::kDeferred), run_executor(
this),
851 debug_push(
this), if_noaccess(
this, Label::kDeferred);
853 BranchIfAccessCheckFailed(context, native_context, promise_fun, executor,
856 Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified,
857 &if_targetismodified);
859 VARIABLE(var_result, MachineRepresentation::kTagged);
860 VARIABLE(var_reject_call, MachineRepresentation::kTagged);
861 VARIABLE(var_reason, MachineRepresentation::kTagged);
863 BIND(&if_targetisnotmodified);
865 Node*
const instance = AllocateAndInitJSPromise(context);
866 var_result.Bind(instance);
870 BIND(&if_targetismodified);
872 ConstructorBuiltinsAssembler constructor_assembler(this->state());
873 Node*
const instance = constructor_assembler.EmitFastNewObject(
874 context, promise_fun, new_target);
875 PromiseInit(instance);
876 var_result.Bind(instance);
878 GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &debug_push);
879 CallRuntime(Runtime::kPromiseHookInit, context, instance,
880 UndefinedConstant());
886 GotoIfNot(is_debug_active, &run_executor);
887 CallRuntime(Runtime::kDebugPushPromise, context, var_result.value());
893 Label out(
this), if_rejectpromise(
this), debug_pop(
this, Label::kDeferred);
895 Node *resolve, *reject;
896 std::tie(resolve, reject) = CreatePromiseResolvingFunctions(
897 var_result.value(), TrueConstant(), native_context);
899 Node*
const maybe_exception = CallJS(
900 CodeFactory::Call(isolate, ConvertReceiverMode::kNullOrUndefined),
901 context, executor, UndefinedConstant(), resolve, reject);
903 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
904 Branch(is_debug_active, &debug_pop, &out);
906 BIND(&if_rejectpromise);
908 CallJS(CodeFactory::Call(isolate, ConvertReceiverMode::kNullOrUndefined),
909 context, reject, UndefinedConstant(), var_reason.value());
910 Branch(is_debug_active, &debug_pop, &out);
915 CallRuntime(Runtime::kDebugPopPromise, context);
919 Return(var_result.value());
923 BIND(&if_targetisundefined);
924 ThrowTypeError(context, MessageTemplate::kNotAPromise, new_target);
927 BIND(&if_notcallable);
928 ThrowTypeError(context, MessageTemplate::kResolverNotAFunction, executor);
933 Node*
const counter_id =
934 SmiConstant(v8::Isolate::kPromiseConstructorReturnedUndefined);
935 CallRuntime(Runtime::kIncrementUseCounter, context, counter_id);
936 Return(UndefinedConstant());
941 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
942 Node*
const parent = Parameter(Descriptor::kParent);
943 Node*
const context = Parameter(Descriptor::kContext);
944 Return(AllocateAndInitJSPromise(context, parent));
948 TF_BUILTIN(PromiseInternalReject, PromiseBuiltinsAssembler) {
949 Node*
const promise = Parameter(Descriptor::kPromise);
950 Node*
const reason = Parameter(Descriptor::kReason);
951 Node*
const context = Parameter(Descriptor::kContext);
953 Return(CallBuiltin(Builtins::kRejectPromise, context, promise, reason,
958 TF_BUILTIN(PromiseInternalResolve, PromiseBuiltinsAssembler) {
959 Node*
const promise = Parameter(Descriptor::kPromise);
960 Node*
const resolution = Parameter(Descriptor::kResolution);
961 Node*
const context = Parameter(Descriptor::kContext);
962 Return(CallBuiltin(Builtins::kResolvePromise, context, promise, resolution));
967 TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) {
969 Node*
const promise = Parameter(Descriptor::kReceiver);
970 Node*
const on_fulfilled = Parameter(Descriptor::kOnFulfilled);
971 Node*
const on_rejected = Parameter(Descriptor::kOnRejected);
972 Node*
const context = Parameter(Descriptor::kContext);
975 ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE,
976 "Promise.prototype.then");
979 Label fast_promise_capability(
this), slow_constructor(
this, Label::kDeferred),
980 slow_promise_capability(
this, Label::kDeferred);
981 Node*
const native_context = LoadNativeContext(context);
982 Node*
const promise_fun =
983 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
984 Node*
const promise_map = LoadMap(promise);
985 BranchIfPromiseSpeciesLookupChainIntact(
986 native_context, promise_map, &fast_promise_capability, &slow_constructor);
988 BIND(&slow_constructor);
989 Node*
const constructor =
990 SpeciesConstructor(native_context, promise, promise_fun);
991 Branch(WordEqual(constructor, promise_fun), &fast_promise_capability,
992 &slow_promise_capability);
995 Label perform_promise_then(
this);
996 VARIABLE(var_result_promise, MachineRepresentation::kTagged);
997 VARIABLE(var_result_promise_or_capability, MachineRepresentation::kTagged);
999 BIND(&fast_promise_capability);
1001 Node*
const result_promise = AllocateAndInitJSPromise(context, promise);
1002 var_result_promise_or_capability.Bind(result_promise);
1003 var_result_promise.Bind(result_promise);
1004 Goto(&perform_promise_then);
1007 BIND(&slow_promise_capability);
1009 Node*
const debug_event = TrueConstant();
1010 Node*
const capability = CallBuiltin(Builtins::kNewPromiseCapability,
1011 context, constructor, debug_event);
1012 var_result_promise.Bind(
1013 LoadObjectField(capability, PromiseCapability::kPromiseOffset));
1014 var_result_promise_or_capability.Bind(capability);
1015 Goto(&perform_promise_then);
1020 BIND(&perform_promise_then);
1029 VARIABLE(var_on_fulfilled, MachineRepresentation::kTagged, on_fulfilled);
1030 Label if_fulfilled_done(
this), if_fulfilled_notcallable(
this);
1031 GotoIf(TaggedIsSmi(on_fulfilled), &if_fulfilled_notcallable);
1032 Branch(IsCallable(on_fulfilled), &if_fulfilled_done,
1033 &if_fulfilled_notcallable);
1034 BIND(&if_fulfilled_notcallable);
1035 var_on_fulfilled.Bind(UndefinedConstant());
1036 Goto(&if_fulfilled_done);
1037 BIND(&if_fulfilled_done);
1041 VARIABLE(var_on_rejected, MachineRepresentation::kTagged, on_rejected);
1042 Label if_rejected_done(
this), if_rejected_notcallable(
this);
1043 GotoIf(TaggedIsSmi(on_rejected), &if_rejected_notcallable);
1044 Branch(IsCallable(on_rejected), &if_rejected_done,
1045 &if_rejected_notcallable);
1046 BIND(&if_rejected_notcallable);
1047 var_on_rejected.Bind(UndefinedConstant());
1048 Goto(&if_rejected_done);
1049 BIND(&if_rejected_done);
1051 PerformPromiseThen(context, promise, var_on_fulfilled.value(),
1052 var_on_rejected.value(),
1053 var_result_promise_or_capability.value());
1054 Return(var_result_promise.value());
1060 TF_BUILTIN(PromisePrototypeCatch, PromiseBuiltinsAssembler) {
1062 Node*
const receiver = Parameter(Descriptor::kReceiver);
1063 Node*
const on_fulfilled = UndefinedConstant();
1064 Node*
const on_rejected = Parameter(Descriptor::kOnRejected);
1065 Node*
const context = Parameter(Descriptor::kContext);
1068 Node*
const native_context = LoadNativeContext(context);
1069 Return(InvokeThen(native_context, receiver, on_fulfilled, on_rejected));
1073 TF_BUILTIN(PromiseResolveThenableJob, PromiseBuiltinsAssembler) {
1074 Node*
const native_context = Parameter(Descriptor::kContext);
1075 Node*
const promise_to_resolve = Parameter(Descriptor::kPromiseToResolve);
1076 Node*
const thenable = Parameter(Descriptor::kThenable);
1077 Node*
const then = Parameter(Descriptor::kThen);
1079 CSA_ASSERT(
this, TaggedIsNotSmi(thenable));
1080 CSA_ASSERT(
this, IsJSReceiver(thenable));
1081 CSA_ASSERT(
this, IsJSPromise(promise_to_resolve));
1082 CSA_ASSERT(
this, IsNativeContext(native_context));
1092 Label if_fast(
this), if_slow(
this, Label::kDeferred);
1093 Node*
const promise_then =
1094 LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
1095 GotoIfNot(WordEqual(then, promise_then), &if_slow);
1096 Node*
const thenable_map = LoadMap(thenable);
1097 GotoIfNot(IsJSPromiseMap(thenable_map), &if_slow);
1098 GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
1100 BranchIfPromiseSpeciesLookupChainIntact(native_context, thenable_map,
1101 &if_fast, &if_slow);
1131 TailCallBuiltin(Builtins::kPerformPromiseThen, native_context, thenable,
1132 UndefinedConstant(), UndefinedConstant(),
1133 promise_to_resolve);
1138 Node* resolve =
nullptr;
1139 Node* reject =
nullptr;
1140 std::tie(resolve, reject) = CreatePromiseResolvingFunctions(
1141 promise_to_resolve, FalseConstant(), native_context);
1143 Label if_exception(
this, Label::kDeferred);
1144 VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant());
1145 Node*
const result = CallJS(
1146 CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined),
1147 native_context, then, thenable, resolve, reject);
1148 GotoIfException(result, &if_exception, &var_exception);
1151 BIND(&if_exception);
1154 Node*
const result = CallJS(
1155 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1156 native_context, reject, UndefinedConstant(), var_exception.value());
1163 void PromiseBuiltinsAssembler::PromiseReactionJob(Node* context, Node* argument,
1165 Node* promise_or_capability,
1166 PromiseReaction::Type type) {
1167 CSA_ASSERT(
this, TaggedIsNotSmi(handler));
1168 CSA_ASSERT(
this, Word32Or(IsUndefined(handler), IsCallable(handler)));
1169 CSA_ASSERT(
this, TaggedIsNotSmi(promise_or_capability));
1171 Word32Or(Word32Or(IsJSPromise(promise_or_capability),
1172 IsPromiseCapability(promise_or_capability)),
1173 IsUndefined(promise_or_capability)));
1175 VARIABLE(var_handler_result, MachineRepresentation::kTagged, argument);
1176 Label if_handler_callable(
this), if_fulfill(
this), if_reject(
this),
1178 Branch(IsUndefined(handler),
1179 type == PromiseReaction::kFulfill ? &if_fulfill : &if_reject,
1180 &if_handler_callable);
1182 BIND(&if_handler_callable);
1184 Node*
const result = CallJS(
1185 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1186 context, handler, UndefinedConstant(), argument);
1187 GotoIfException(result, &if_reject, &var_handler_result);
1188 var_handler_result.Bind(result);
1189 Branch(IsUndefined(promise_or_capability), &if_internal, &if_fulfill);
1198 Return(UndefinedConstant());
1203 Label if_promise(
this), if_promise_capability(
this, Label::kDeferred);
1204 Node*
const value = var_handler_result.value();
1205 Branch(IsPromiseCapability(promise_or_capability), &if_promise_capability,
1213 TailCallBuiltin(Builtins::kResolvePromise, context, promise_or_capability,
1217 BIND(&if_promise_capability);
1221 Node*
const resolve = LoadObjectField(promise_or_capability,
1222 PromiseCapability::kResolveOffset);
1223 Node*
const result = CallJS(
1224 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1225 context, resolve, UndefinedConstant(), value);
1226 GotoIfException(result, &if_reject, &var_handler_result);
1232 if (type == PromiseReaction::kReject) {
1233 Label if_promise(
this), if_promise_capability(
this, Label::kDeferred);
1234 Node*
const reason = var_handler_result.value();
1235 Branch(IsPromiseCapability(promise_or_capability), &if_promise_capability,
1243 TailCallBuiltin(Builtins::kRejectPromise, context, promise_or_capability,
1244 reason, FalseConstant());
1247 BIND(&if_promise_capability);
1251 Label if_exception(
this, Label::kDeferred);
1252 VARIABLE(var_exception, MachineRepresentation::kTagged,
1254 Node*
const reject = LoadObjectField(promise_or_capability,
1255 PromiseCapability::kRejectOffset);
1256 Node*
const result = CallJS(
1257 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1258 context, reject, UndefinedConstant(), reason);
1259 GotoIfException(result, &if_exception, &var_exception);
1263 BIND(&if_exception);
1264 TailCallRuntime(Runtime::kReportMessage, context, var_exception.value());
1271 TailCallBuiltin(Builtins::kPromiseRejectReactionJob, context,
1272 var_handler_result.value(), UndefinedConstant(),
1273 promise_or_capability);
1278 TF_BUILTIN(PromiseFulfillReactionJob, PromiseBuiltinsAssembler) {
1279 Node*
const context = Parameter(Descriptor::kContext);
1280 Node*
const value = Parameter(Descriptor::kValue);
1281 Node*
const handler = Parameter(Descriptor::kHandler);
1282 Node*
const promise_or_capability =
1283 Parameter(Descriptor::kPromiseOrCapability);
1285 PromiseReactionJob(context, value, handler, promise_or_capability,
1286 PromiseReaction::kFulfill);
1290 TF_BUILTIN(PromiseRejectReactionJob, PromiseBuiltinsAssembler) {
1291 Node*
const context = Parameter(Descriptor::kContext);
1292 Node*
const reason = Parameter(Descriptor::kReason);
1293 Node*
const handler = Parameter(Descriptor::kHandler);
1294 Node*
const promise_or_capability =
1295 Parameter(Descriptor::kPromiseOrCapability);
1297 PromiseReactionJob(context, reason, handler, promise_or_capability,
1298 PromiseReaction::kReject);
1301 TF_BUILTIN(PromiseResolveTrampoline, PromiseBuiltinsAssembler) {
1303 Node* receiver = Parameter(Descriptor::kReceiver);
1304 Node* value = Parameter(Descriptor::kValue);
1305 Node* context = Parameter(Descriptor::kContext);
1308 ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
1312 Return(CallBuiltin(Builtins::kPromiseResolve, context, receiver, value));
1315 TF_BUILTIN(PromiseResolve, PromiseBuiltinsAssembler) {
1316 Node* constructor = Parameter(Descriptor::kConstructor);
1317 Node* value = Parameter(Descriptor::kValue);
1318 Node* context = Parameter(Descriptor::kContext);
1320 CSA_ASSERT(
this, IsJSReceiver(constructor));
1322 Node*
const native_context = LoadNativeContext(context);
1323 Node*
const promise_fun =
1324 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
1326 Label if_slow_constructor(
this, Label::kDeferred), if_need_to_allocate(
this);
1329 GotoIf(TaggedIsSmi(value), &if_need_to_allocate);
1330 Node*
const value_map = LoadMap(value);
1331 GotoIfNot(IsJSPromiseMap(value_map), &if_need_to_allocate);
1337 Node*
const promise_prototype =
1338 LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
1339 GotoIfNot(WordEqual(LoadMapPrototype(value_map), promise_prototype),
1340 &if_slow_constructor);
1341 GotoIf(IsPromiseSpeciesProtectorCellInvalid(), &if_slow_constructor);
1346 GotoIfNot(WordEqual(promise_fun, constructor), &if_slow_constructor);
1351 BIND(&if_slow_constructor);
1353 Node*
const value_constructor =
1354 GetProperty(context, value, isolate()->factory()->constructor_string());
1355 GotoIfNot(WordEqual(value_constructor, constructor), &if_need_to_allocate);
1359 BIND(&if_need_to_allocate);
1361 Label if_nativepromise(
this), if_notnativepromise(
this, Label::kDeferred);
1362 Branch(WordEqual(promise_fun, constructor), &if_nativepromise,
1363 &if_notnativepromise);
1367 BIND(&if_nativepromise);
1369 Node*
const result = AllocateAndInitJSPromise(context);
1370 CallBuiltin(Builtins::kResolvePromise, context, result, value);
1374 BIND(&if_notnativepromise);
1376 Node*
const debug_event = TrueConstant();
1377 Node*
const capability = CallBuiltin(Builtins::kNewPromiseCapability,
1378 context, constructor, debug_event);
1380 Node*
const resolve =
1381 LoadObjectField(capability, PromiseCapability::kResolveOffset);
1383 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1384 context, resolve, UndefinedConstant(), value);
1386 Node*
const result =
1387 LoadObjectField(capability, PromiseCapability::kPromiseOffset);
1394 TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) {
1395 Node*
const resolve = Parameter(Descriptor::kResolve);
1396 Node*
const reject = Parameter(Descriptor::kReject);
1397 Node*
const context = Parameter(Descriptor::kContext);
1399 Node*
const capability = LoadContextElement(context, kCapabilitySlot);
1401 Label if_alreadyinvoked(
this, Label::kDeferred);
1402 GotoIfNot(IsUndefined(
1403 LoadObjectField(capability, PromiseCapability::kResolveOffset)),
1404 &if_alreadyinvoked);
1405 GotoIfNot(IsUndefined(
1406 LoadObjectField(capability, PromiseCapability::kRejectOffset)),
1407 &if_alreadyinvoked);
1409 StoreObjectField(capability, PromiseCapability::kResolveOffset, resolve);
1410 StoreObjectField(capability, PromiseCapability::kRejectOffset, reject);
1412 Return(UndefinedConstant());
1414 BIND(&if_alreadyinvoked);
1415 ThrowTypeError(context, MessageTemplate::kPromiseExecutorAlreadyInvoked);
1418 TF_BUILTIN(PromiseReject, PromiseBuiltinsAssembler) {
1420 Node*
const receiver = Parameter(Descriptor::kReceiver);
1421 Node*
const reason = Parameter(Descriptor::kReason);
1422 Node*
const context = Parameter(Descriptor::kContext);
1425 ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
1428 Label if_nativepromise(
this), if_custompromise(
this, Label::kDeferred);
1429 Node*
const native_context = LoadNativeContext(context);
1431 Node*
const promise_fun =
1432 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
1433 Branch(WordEqual(promise_fun, receiver), &if_nativepromise,
1436 BIND(&if_nativepromise);
1438 Node*
const promise =
1439 AllocateAndSetJSPromise(context, v8::Promise::kRejected, reason);
1440 CallRuntime(Runtime::kPromiseRejectEventFromStack, context, promise,
1445 BIND(&if_custompromise);
1448 Node*
const debug_event = TrueConstant();
1449 Node*
const capability = CallBuiltin(Builtins::kNewPromiseCapability,
1450 context, receiver, debug_event);
1453 Node*
const reject =
1454 LoadObjectField(capability, PromiseCapability::kRejectOffset);
1455 CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1456 context, reject, UndefinedConstant(), reason);
1459 Node*
const promise =
1460 LoadObjectField(capability, PromiseCapability::kPromiseOffset);
1465 std::pair<Node*, Node*> PromiseBuiltinsAssembler::CreatePromiseFinallyFunctions(
1466 Node* on_finally, Node* constructor, Node* native_context) {
1467 Node*
const promise_context =
1468 CreatePromiseContext(native_context, kPromiseFinallyContextLength);
1469 StoreContextElementNoWriteBarrier(promise_context, kOnFinallySlot,
1471 StoreContextElementNoWriteBarrier(promise_context, kConstructorSlot,
1473 Node*
const map = LoadContextElement(
1474 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
1475 Node*
const then_finally_info = LoadContextElement(
1476 native_context, Context::PROMISE_THEN_FINALLY_SHARED_FUN);
1477 Node*
const then_finally = AllocateFunctionWithMapAndContext(
1478 map, then_finally_info, promise_context);
1479 Node*
const catch_finally_info = LoadContextElement(
1480 native_context, Context::PROMISE_CATCH_FINALLY_SHARED_FUN);
1481 Node*
const catch_finally = AllocateFunctionWithMapAndContext(
1482 map, catch_finally_info, promise_context);
1483 return std::make_pair(then_finally, catch_finally);
1486 TF_BUILTIN(PromiseValueThunkFinally, PromiseBuiltinsAssembler) {
1487 Node*
const context = Parameter(Descriptor::kContext);
1489 Node*
const value = LoadContextElement(context, kValueSlot);
1493 Node* PromiseBuiltinsAssembler::CreateValueThunkFunction(Node* value,
1494 Node* native_context) {
1495 Node*
const value_thunk_context = CreatePromiseContext(
1496 native_context, kPromiseValueThunkOrReasonContextLength);
1497 StoreContextElementNoWriteBarrier(value_thunk_context, kValueSlot, value);
1498 Node*
const map = LoadContextElement(
1499 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
1500 Node*
const value_thunk_info = LoadContextElement(
1501 native_context, Context::PROMISE_VALUE_THUNK_FINALLY_SHARED_FUN);
1502 Node*
const value_thunk = AllocateFunctionWithMapAndContext(
1503 map, value_thunk_info, value_thunk_context);
1507 TF_BUILTIN(PromiseThenFinally, PromiseBuiltinsAssembler) {
1508 CSA_ASSERT_JS_ARGC_EQ(
this, 1);
1510 Node*
const value = Parameter(Descriptor::kValue);
1511 Node*
const context = Parameter(Descriptor::kContext);
1514 Node*
const on_finally = LoadContextElement(context, kOnFinallySlot);
1517 CSA_ASSERT(
this, IsCallable(on_finally));
1520 Node*
const result = CallJS(
1521 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1522 context, on_finally, UndefinedConstant());
1525 Node*
const constructor = LoadContextElement(context, kConstructorSlot);
1528 CSA_ASSERT(
this, IsConstructor(constructor));
1531 Node*
const promise =
1532 CallBuiltin(Builtins::kPromiseResolve, context, constructor, result);
1535 Node*
const native_context = LoadNativeContext(context);
1536 Node*
const value_thunk = CreateValueThunkFunction(value, native_context);
1539 Return(InvokeThen(native_context, promise, value_thunk));
1542 TF_BUILTIN(PromiseThrowerFinally, PromiseBuiltinsAssembler) {
1543 Node*
const context = Parameter(Descriptor::kContext);
1545 Node*
const reason = LoadContextElement(context, kValueSlot);
1546 CallRuntime(Runtime::kThrow, context, reason);
1550 Node* PromiseBuiltinsAssembler::CreateThrowerFunction(Node* reason,
1551 Node* native_context) {
1552 Node*
const thrower_context = CreatePromiseContext(
1553 native_context, kPromiseValueThunkOrReasonContextLength);
1554 StoreContextElementNoWriteBarrier(thrower_context, kValueSlot, reason);
1555 Node*
const map = LoadContextElement(
1556 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
1557 Node*
const thrower_info = LoadContextElement(
1558 native_context, Context::PROMISE_THROWER_FINALLY_SHARED_FUN);
1559 Node*
const thrower =
1560 AllocateFunctionWithMapAndContext(map, thrower_info, thrower_context);
1564 TF_BUILTIN(PromiseCatchFinally, PromiseBuiltinsAssembler) {
1565 CSA_ASSERT_JS_ARGC_EQ(
this, 1);
1567 Node*
const reason = Parameter(Descriptor::kReason);
1568 Node*
const context = Parameter(Descriptor::kContext);
1571 Node*
const on_finally = LoadContextElement(context, kOnFinallySlot);
1574 CSA_ASSERT(
this, IsCallable(on_finally));
1577 Node* result = CallJS(
1578 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
1579 context, on_finally, UndefinedConstant());
1582 Node*
const constructor = LoadContextElement(context, kConstructorSlot);
1585 CSA_ASSERT(
this, IsConstructor(constructor));
1588 Node*
const promise =
1589 CallBuiltin(Builtins::kPromiseResolve, context, constructor, result);
1592 Node*
const native_context = LoadNativeContext(context);
1593 Node*
const thrower = CreateThrowerFunction(reason, native_context);
1596 Return(InvokeThen(native_context, promise, thrower));
1599 TF_BUILTIN(PromisePrototypeFinally, PromiseBuiltinsAssembler) {
1600 CSA_ASSERT_JS_ARGC_EQ(
this, 1);
1603 Node*
const receiver = Parameter(Descriptor::kReceiver);
1604 Node*
const on_finally = Parameter(Descriptor::kOnFinally);
1605 Node*
const context = Parameter(Descriptor::kContext);
1608 ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
1609 "Promise.prototype.finally");
1612 Node*
const native_context = LoadNativeContext(context);
1613 Node*
const promise_fun =
1614 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
1615 VARIABLE(var_constructor, MachineRepresentation::kTagged, promise_fun);
1616 Label slow_constructor(
this, Label::kDeferred), done_constructor(
this);
1617 Node*
const receiver_map = LoadMap(receiver);
1618 GotoIfNot(IsJSPromiseMap(receiver_map), &slow_constructor);
1619 BranchIfPromiseSpeciesLookupChainIntact(native_context, receiver_map,
1620 &done_constructor, &slow_constructor);
1621 BIND(&slow_constructor);
1623 Node*
const constructor =
1624 SpeciesConstructor(context, receiver, promise_fun);
1625 var_constructor.Bind(constructor);
1626 Goto(&done_constructor);
1628 BIND(&done_constructor);
1629 Node*
const constructor = var_constructor.value();
1632 CSA_ASSERT(
this, IsConstructor(constructor));
1634 VARIABLE(var_then_finally, MachineRepresentation::kTagged);
1635 VARIABLE(var_catch_finally, MachineRepresentation::kTagged);
1637 Label if_notcallable(
this, Label::kDeferred), perform_finally(
this);
1639 GotoIf(TaggedIsSmi(on_finally), &if_notcallable);
1640 GotoIfNot(IsCallable(on_finally), &if_notcallable);
1651 Node* then_finally =
nullptr;
1652 Node* catch_finally =
nullptr;
1653 std::tie(then_finally, catch_finally) =
1654 CreatePromiseFinallyFunctions(on_finally, constructor, native_context);
1655 var_then_finally.Bind(then_finally);
1656 var_catch_finally.Bind(catch_finally);
1657 Goto(&perform_finally);
1662 BIND(&if_notcallable);
1664 var_then_finally.Bind(on_finally);
1665 var_catch_finally.Bind(on_finally);
1666 Goto(&perform_finally);
1670 BIND(&perform_finally);
1671 Return(InvokeThen(native_context, receiver, var_then_finally.value(),
1672 var_catch_finally.value()));
1676 TF_BUILTIN(FulfillPromise, PromiseBuiltinsAssembler) {
1677 Node*
const promise = Parameter(Descriptor::kPromise);
1678 Node*
const value = Parameter(Descriptor::kValue);
1679 Node*
const context = Parameter(Descriptor::kContext);
1681 CSA_ASSERT(
this, TaggedIsNotSmi(promise));
1682 CSA_ASSERT(
this, IsJSPromise(promise));
1685 Node*
const reactions =
1686 LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
1691 StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, value);
1694 PromiseSetStatus(promise, Promise::kFulfilled);
1697 Return(TriggerPromiseReactions(context, reactions, value,
1698 PromiseReaction::kFulfill));
1702 TF_BUILTIN(RejectPromise, PromiseBuiltinsAssembler) {
1703 Node*
const promise = Parameter(Descriptor::kPromise);
1704 Node*
const reason = Parameter(Descriptor::kReason);
1705 Node*
const debug_event = Parameter(Descriptor::kDebugEvent);
1706 Node*
const context = Parameter(Descriptor::kContext);
1708 CSA_ASSERT(
this, TaggedIsNotSmi(promise));
1709 CSA_ASSERT(
this, IsJSPromise(promise));
1710 CSA_ASSERT(
this, IsBoolean(debug_event));
1711 Label if_runtime(
this, Label::kDeferred);
1717 GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
1724 GotoIfNot(PromiseHasHandler(promise), &if_runtime);
1728 LoadObjectField(promise, JSPromise::kReactionsOrResultOffset);
1733 StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, reason);
1736 PromiseSetStatus(promise, Promise::kRejected);
1739 Return(TriggerPromiseReactions(context, reactions, reason,
1740 PromiseReaction::kReject));
1743 TailCallRuntime(Runtime::kRejectPromise, context, promise, reason,
1748 TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) {
1749 Node*
const promise = Parameter(Descriptor::kPromise);
1750 Node*
const resolution = Parameter(Descriptor::kResolution);
1751 Node*
const context = Parameter(Descriptor::kContext);
1753 CSA_ASSERT(
this, TaggedIsNotSmi(promise));
1754 CSA_ASSERT(
this, IsJSPromise(promise));
1756 Label do_enqueue(
this), if_fulfill(
this), if_reject(
this, Label::kDeferred),
1757 if_runtime(
this, Label::kDeferred);
1758 VARIABLE(var_reason, MachineRepresentation::kTagged);
1759 VARIABLE(var_then, MachineRepresentation::kTagged);
1765 GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
1771 GotoIf(WordEqual(promise, resolution), &if_runtime);
1774 GotoIf(TaggedIsSmi(resolution), &if_fulfill);
1775 Node*
const resolution_map = LoadMap(resolution);
1776 GotoIfNot(IsJSReceiverMap(resolution_map), &if_fulfill);
1782 Label if_fast(
this), if_receiver(
this), if_slow(
this, Label::kDeferred);
1783 Node*
const native_context = LoadNativeContext(context);
1784 GotoIfForceSlowPath(&if_slow);
1785 GotoIf(IsPromiseThenProtectorCellInvalid(), &if_slow);
1786 GotoIfNot(IsJSPromiseMap(resolution_map), &if_receiver);
1787 Node*
const promise_prototype =
1788 LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
1789 Branch(WordEqual(LoadMapPrototype(resolution_map), promise_prototype),
1790 &if_fast, &if_slow);
1796 LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
1797 var_then.Bind(then);
1808 CSA_ASSERT(
this, IsJSReceiverMap(resolution_map));
1809 CSA_ASSERT(
this, Word32BinaryNot(IsPromiseThenProtectorCellInvalid()));
1810 Node*
const iterator_result_map =
1811 LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
1812 Branch(WordEqual(resolution_map, iterator_result_map), &if_fulfill,
1820 GetProperty(context, resolution, isolate()->factory()->then_string());
1823 GotoIfException(then, &if_reject, &var_reason);
1826 GotoIf(TaggedIsSmi(then), &if_fulfill);
1827 Node*
const then_map = LoadMap(then);
1828 GotoIfNot(IsCallableMap(then_map), &if_fulfill);
1829 var_then.Bind(then);
1837 Node*
const task = AllocatePromiseResolveThenableJobTask(
1838 promise, var_then.value(), resolution, native_context);
1839 TailCallBuiltin(Builtins::kEnqueueMicrotask, native_context, task);
1845 TailCallBuiltin(Builtins::kFulfillPromise, context, promise, resolution);
1849 Return(CallRuntime(Runtime::kResolvePromise, context, promise, resolution));
1854 TailCallBuiltin(Builtins::kRejectPromise, context, promise,
1855 var_reason.value(), FalseConstant());
1859 Node* PromiseBuiltinsAssembler::PerformPromiseAll(
1860 Node* context, Node* constructor, Node* capability,
1861 const IteratorRecord& iterator, Label* if_exception,
1862 Variable* var_exception) {
1863 IteratorBuiltinsAssembler iter_assembler(state());
1865 Node*
const native_context = LoadNativeContext(context);
1869 SetForwardingHandlerIfTrue(
1870 native_context, IsDebugActive(),
1871 LoadObjectField(capability, PromiseCapability::kRejectOffset));
1873 Node*
const resolve_element_context =
1874 CreatePromiseAllResolveElementContext(capability, native_context);
1876 TVARIABLE(Smi, var_index, SmiConstant(1));
1877 Label loop(
this, &var_index), done_loop(
this),
1878 too_many_elements(
this, Label::kDeferred),
1879 close_iterator(
this, Label::kDeferred);
1886 Node*
const fast_iterator_result_map =
1887 LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
1888 Node*
const next = iter_assembler.IteratorStep(
1889 native_context, iterator, &done_loop, fast_iterator_result_map,
1890 if_exception, var_exception);
1896 Node*
const next_value = iter_assembler.IteratorValue(
1897 native_context, next, fast_iterator_result_map, if_exception,
1901 TNode<Smi>
const index = var_index.value();
1902 GotoIf(SmiEqual(index, SmiConstant(PropertyArray::HashField::kMax)),
1903 &too_many_elements);
1906 var_index = SmiAdd(index, SmiConstant(1));
1910 TNode<Smi>
const remaining_elements_count = CAST(LoadContextElement(
1911 resolve_element_context, kPromiseAllResolveElementRemainingSlot));
1912 StoreContextElementNoWriteBarrier(
1913 resolve_element_context, kPromiseAllResolveElementRemainingSlot,
1914 SmiAdd(remaining_elements_count, SmiConstant(1)));
1927 Node*
const resolve_element_fun = CreatePromiseAllResolveElementFunction(
1928 resolve_element_context, index, native_context);
1944 Label if_fast(
this), if_slow(
this);
1945 GotoIfNotPromiseResolveLookupChainIntact(native_context, constructor,
1947 GotoIf(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(),
1949 GotoIf(TaggedIsSmi(next_value), &if_slow);
1950 Node*
const next_value_map = LoadMap(next_value);
1951 BranchIfPromiseThenLookupChainIntact(native_context, next_value_map,
1952 &if_fast, &if_slow);
1960 native_context, next_value, resolve_element_fun,
1961 LoadObjectField(capability, PromiseCapability::kRejectOffset),
1962 UndefinedConstant());
1969 Node*
const next_promise =
1970 InvokeResolve(native_context, constructor, next_value,
1971 &close_iterator, var_exception);
1976 GetProperty(native_context, next_promise, factory()->then_string());
1977 GotoIfException(then, &close_iterator, var_exception);
1979 Node*
const then_call =
1980 CallJS(CodeFactory::Call(isolate(),
1981 ConvertReceiverMode::kNotNullOrUndefined),
1982 native_context, then, next_promise, resolve_element_fun,
1983 LoadObjectField(capability, PromiseCapability::kRejectOffset));
1984 GotoIfException(then_call, &close_iterator, var_exception);
1988 SetPromiseHandledByIfTrue(
1989 native_context, IsDebugActive(), then_call, [=]() {
1991 return LoadObjectField(capability,
1992 PromiseCapability::kPromiseOffset);
1999 BIND(&too_many_elements);
2008 Node*
const result =
2009 CallRuntime(Runtime::kThrowRangeError, native_context,
2010 SmiConstant(MessageTemplate::kTooManyElementsInPromiseAll));
2011 GotoIfException(result, &close_iterator, var_exception);
2015 BIND(&close_iterator);
2018 CSA_ASSERT(
this, IsNotTheHole(var_exception->value()));
2019 iter_assembler.IteratorCloseOnException(native_context, iterator,
2020 if_exception, var_exception);
2025 Label resolve_promise(
this, Label::kDeferred), return_promise(
this);
2029 TNode<Smi> remaining_elements_count = CAST(LoadContextElement(
2030 resolve_element_context, kPromiseAllResolveElementRemainingSlot));
2031 remaining_elements_count = SmiSub(remaining_elements_count, SmiConstant(1));
2032 StoreContextElementNoWriteBarrier(resolve_element_context,
2033 kPromiseAllResolveElementRemainingSlot,
2034 remaining_elements_count);
2035 GotoIf(SmiEqual(remaining_elements_count, SmiConstant(0)),
2042 Node*
const values_array = LoadContextElement(
2043 resolve_element_context, kPromiseAllResolveElementValuesArraySlot);
2044 Node*
const old_elements = LoadElements(values_array);
2045 TNode<Smi>
const old_capacity = LoadFixedArrayBaseLength(old_elements);
2046 TNode<Smi>
const new_capacity = var_index.value();
2047 GotoIf(SmiGreaterThanOrEqual(old_capacity, new_capacity), &return_promise);
2048 Node*
const new_elements =
2049 AllocateFixedArray(PACKED_ELEMENTS, new_capacity, SMI_PARAMETERS,
2050 AllocationFlag::kAllowLargeObjectAllocation);
2051 CopyFixedArrayElements(PACKED_ELEMENTS, old_elements, PACKED_ELEMENTS,
2052 new_elements, SmiConstant(0), old_capacity,
2053 new_capacity, UPDATE_WRITE_BARRIER, SMI_PARAMETERS);
2054 StoreObjectField(values_array, JSArray::kElementsOffset, new_elements);
2055 Goto(&return_promise);
2061 BIND(&resolve_promise);
2063 Node*
const resolve =
2064 LoadObjectField(capability, PromiseCapability::kResolveOffset);
2065 Node*
const values_array = LoadContextElement(
2066 resolve_element_context, kPromiseAllResolveElementValuesArraySlot);
2067 Node*
const resolve_call = CallJS(
2068 CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
2069 native_context, resolve, UndefinedConstant(), values_array);
2070 GotoIfException(resolve_call, if_exception, var_exception);
2071 Goto(&return_promise);
2075 BIND(&return_promise);
2078 Node*
const promise =
2079 LoadObjectField(capability, PromiseCapability::kPromiseOffset);
2085 TF_BUILTIN(PromiseAll, PromiseBuiltinsAssembler) {
2086 IteratorBuiltinsAssembler iter_assembler(state());
2090 Node*
const receiver = Parameter(Descriptor::kReceiver);
2091 Node*
const context = Parameter(Descriptor::kContext);
2092 ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
2098 Node*
const debug_event = FalseConstant();
2099 Node*
const capability = CallBuiltin(Builtins::kNewPromiseCapability, context,
2100 receiver, debug_event);
2102 VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant());
2103 Label reject_promise(
this, &var_exception, Label::kDeferred);
2107 Node*
const iterable = Parameter(Descriptor::kIterable);
2108 IteratorRecord iterator = iter_assembler.GetIterator(
2109 context, iterable, &reject_promise, &var_exception);
2116 Node*
const result = PerformPromiseAll(
2117 context, receiver, capability, iterator, &reject_promise, &var_exception);
2121 BIND(&reject_promise);
2124 CSA_SLOW_ASSERT(
this, IsNotTheHole(var_exception.value()));
2125 Node*
const reject =
2126 LoadObjectField(capability, PromiseCapability::kRejectOffset);
2127 CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
2128 context, reject, UndefinedConstant(), var_exception.value());
2130 Node*
const promise =
2131 LoadObjectField(capability, PromiseCapability::kPromiseOffset);
2136 TF_BUILTIN(PromiseAllResolveElementClosure, PromiseBuiltinsAssembler) {
2137 TNode<Object> value = CAST(Parameter(Descriptor::kValue));
2138 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
2139 TNode<JSFunction>
function = CAST(Parameter(Descriptor::kJSTarget));
2141 Label already_called(
this, Label::kDeferred), resolve_promise(
this);
2148 GotoIf(IsNativeContext(context), &already_called);
2150 SmiEqual(LoadObjectField<Smi>(context, Context::kLengthOffset),
2151 SmiConstant(kPromiseAllResolveElementLength)));
2152 TNode<Context> native_context = LoadNativeContext(context);
2153 StoreObjectField(
function, JSFunction::kContextOffset, native_context);
2156 Label unreachable(
this, Label::kDeferred);
2157 STATIC_ASSERT(PropertyArray::kNoHashSentinel == 0);
2158 TNode<IntPtrT> identity_hash =
2159 LoadJSReceiverIdentityHash(
function, &unreachable);
2160 CSA_ASSERT(
this, IntPtrGreaterThan(identity_hash, IntPtrConstant(0)));
2161 TNode<IntPtrT> index = IntPtrSub(identity_hash, IntPtrConstant(1));
2164 TNode<JSArray> values_array = CAST(
2165 LoadContextElement(context, kPromiseAllResolveElementValuesArraySlot));
2166 TNode<FixedArray> elements = CAST(LoadElements(values_array));
2167 TNode<IntPtrT> values_length =
2168 LoadAndUntagObjectField(values_array, JSArray::kLengthOffset);
2169 Label if_inbounds(
this), if_outofbounds(
this), done(
this);
2170 Branch(IntPtrLessThan(index, values_length), &if_inbounds, &if_outofbounds);
2172 BIND(&if_outofbounds);
2175 TNode<IntPtrT> new_length = IntPtrAdd(index, IntPtrConstant(1));
2176 TNode<IntPtrT> elements_length =
2177 LoadAndUntagObjectField(elements, FixedArray::kLengthOffset);
2178 Label if_grow(
this, Label::kDeferred), if_nogrow(
this);
2179 Branch(IntPtrLessThan(index, elements_length), &if_nogrow, &if_grow);
2184 TNode<IntPtrT> new_elements_length =
2185 IntPtrMin(CalculateNewElementsCapacity(new_length),
2186 IntPtrConstant(PropertyArray::HashField::kMax + 1));
2187 CSA_ASSERT(
this, IntPtrLessThan(index, new_elements_length));
2188 CSA_ASSERT(
this, IntPtrLessThan(elements_length, new_elements_length));
2189 TNode<FixedArray> new_elements =
2190 CAST(AllocateFixedArray(PACKED_ELEMENTS, new_elements_length,
2191 AllocationFlag::kAllowLargeObjectAllocation));
2192 CopyFixedArrayElements(PACKED_ELEMENTS, elements, PACKED_ELEMENTS,
2193 new_elements, elements_length,
2194 new_elements_length);
2195 StoreFixedArrayElement(new_elements, index, value);
2198 StoreObjectField(values_array, JSArray::kElementsOffset, new_elements);
2199 StoreObjectFieldNoWriteBarrier(values_array, JSArray::kLengthOffset,
2200 SmiTag(new_length));
2208 StoreObjectFieldNoWriteBarrier(values_array, JSArray::kLengthOffset,
2209 SmiTag(new_length));
2210 StoreFixedArrayElement(elements, index, value);
2219 StoreFixedArrayElement(elements, index, value);
2224 TNode<Smi> remaining_elements_count =
2225 CAST(LoadContextElement(context, kPromiseAllResolveElementRemainingSlot));
2226 remaining_elements_count = SmiSub(remaining_elements_count, SmiConstant(1));
2227 StoreContextElement(context, kPromiseAllResolveElementRemainingSlot,
2228 remaining_elements_count);
2229 GotoIf(SmiEqual(remaining_elements_count, SmiConstant(0)), &resolve_promise);
2230 Return(UndefinedConstant());
2232 BIND(&resolve_promise);
2233 TNode<PromiseCapability> capability = CAST(
2234 LoadContextElement(context, kPromiseAllResolveElementCapabilitySlot));
2235 TNode<Object> resolve =
2236 LoadObjectField(capability, PromiseCapability::kResolveOffset);
2237 CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
2238 context, resolve, UndefinedConstant(), values_array);
2239 Return(UndefinedConstant());
2241 BIND(&already_called);
2242 Return(UndefinedConstant());
2250 TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
2251 IteratorBuiltinsAssembler iter_assembler(state());
2252 VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant());
2254 Node*
const receiver = Parameter(Descriptor::kReceiver);
2255 Node*
const context = Parameter(Descriptor::kContext);
2256 ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
2262 Node*
const debug_event = FalseConstant();
2263 Node*
const capability = CallBuiltin(Builtins::kNewPromiseCapability, context,
2264 receiver, debug_event);
2266 Node*
const resolve =
2267 LoadObjectField(capability, PromiseCapability::kResolveOffset);
2268 Node*
const reject =
2269 LoadObjectField(capability, PromiseCapability::kRejectOffset);
2271 Label close_iterator(
this, Label::kDeferred);
2272 Label reject_promise(
this, Label::kDeferred);
2276 SetForwardingHandlerIfTrue(context, IsDebugActive(), reject);
2280 Node*
const iterable = Parameter(Descriptor::kIterable);
2281 IteratorRecord iterator = iter_assembler.GetIterator(
2282 context, iterable, &reject_promise, &var_exception);
2286 Label loop(
this), break_loop(
this);
2290 Node*
const native_context = LoadNativeContext(context);
2291 Node*
const fast_iterator_result_map = LoadContextElement(
2292 native_context, Context::ITERATOR_RESULT_MAP_INDEX);
2297 Node*
const next = iter_assembler.IteratorStep(
2298 context, iterator, &break_loop, fast_iterator_result_map,
2299 &reject_promise, &var_exception);
2305 Node*
const next_value =
2306 iter_assembler.IteratorValue(context, next, fast_iterator_result_map,
2307 &reject_promise, &var_exception);
2310 Node*
const next_promise =
2311 InvokeResolve(native_context, receiver, next_value, &close_iterator,
2317 GetProperty(context, next_promise, factory()->then_string());
2318 GotoIfException(then, &close_iterator, &var_exception);
2320 Node*
const then_call =
2321 CallJS(CodeFactory::Call(isolate(),
2322 ConvertReceiverMode::kNotNullOrUndefined),
2323 context, then, next_promise, resolve, reject);
2324 GotoIfException(then_call, &close_iterator, &var_exception);
2328 SetPromiseHandledByIfTrue(context, IsDebugActive(), then_call, [=]() {
2330 return LoadObjectField(capability, PromiseCapability::kPromiseOffset);
2336 Return(LoadObjectField(capability, PromiseCapability::kPromiseOffset));
2339 BIND(&close_iterator);
2341 CSA_ASSERT(
this, IsNotTheHole(var_exception.value()));
2342 iter_assembler.IteratorCloseOnException(context, iterator, &reject_promise,
2346 BIND(&reject_promise);
2348 Node*
const reject =
2349 LoadObjectField(capability, PromiseCapability::kRejectOffset);
2350 CallJS(CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined),
2351 context, reject, UndefinedConstant(), var_exception.value());
2353 Node*
const promise =
2354 LoadObjectField(capability, PromiseCapability::kPromiseOffset);