OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins-promise.h" | 5 #include "src/builtins/builtins-promise.h" |
6 #include "src/builtins/builtins-constructor.h" | 6 #include "src/builtins/builtins-constructor.h" |
7 #include "src/builtins/builtins-utils.h" | 7 #include "src/builtins/builtins-utils.h" |
8 #include "src/builtins/builtins.h" | 8 #include "src/builtins/builtins.h" |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stub-assembler.h" | 10 #include "src/code-stub-assembler.h" |
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 | 640 |
641 Node* const initial_proto_initial_map = | 641 Node* const initial_proto_initial_map = |
642 LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_MAP_INDEX); | 642 LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_MAP_INDEX); |
643 Node* const proto_map = LoadMap(LoadMapPrototype(map)); | 643 Node* const proto_map = LoadMap(LoadMapPrototype(map)); |
644 Node* const proto_has_initialmap = | 644 Node* const proto_has_initialmap = |
645 WordEqual(proto_map, initial_proto_initial_map); | 645 WordEqual(proto_map, initial_proto_initial_map); |
646 | 646 |
647 Branch(proto_has_initialmap, if_isunmodified, if_ismodified); | 647 Branch(proto_has_initialmap, if_isunmodified, if_ismodified); |
648 } | 648 } |
649 | 649 |
| 650 Node* PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobInfo( |
| 651 Node* thenable, Node* then, Node* resolve, Node* reject, Node* context) { |
| 652 Node* const info = Allocate(PromiseResolveThenableJobInfo::kSize); |
| 653 StoreMapNoWriteBarrier(info, |
| 654 Heap::kPromiseResolveThenableJobInfoMapRootIndex); |
| 655 StoreObjectFieldNoWriteBarrier( |
| 656 info, PromiseResolveThenableJobInfo::kThenableOffset, thenable); |
| 657 StoreObjectFieldNoWriteBarrier( |
| 658 info, PromiseResolveThenableJobInfo::kThenOffset, then); |
| 659 StoreObjectFieldNoWriteBarrier( |
| 660 info, PromiseResolveThenableJobInfo::kResolveOffset, resolve); |
| 661 StoreObjectFieldNoWriteBarrier( |
| 662 info, PromiseResolveThenableJobInfo::kRejectOffset, reject); |
| 663 StoreObjectFieldNoWriteBarrier(info, |
| 664 PromiseResolveThenableJobInfo::kDebugIdOffset, |
| 665 SmiConstant(kDebugPromiseNoID)); |
| 666 StoreObjectFieldNoWriteBarrier( |
| 667 info, PromiseResolveThenableJobInfo::kDebugNameOffset, |
| 668 SmiConstant(kDebugNotActive)); |
| 669 StoreObjectFieldNoWriteBarrier( |
| 670 info, PromiseResolveThenableJobInfo::kContextOffset, context); |
| 671 return info; |
| 672 } |
| 673 |
650 void PromiseBuiltinsAssembler::InternalResolvePromise(Node* context, | 674 void PromiseBuiltinsAssembler::InternalResolvePromise(Node* context, |
651 Node* promise, | 675 Node* promise, |
652 Node* result) { | 676 Node* result) { |
653 Isolate* isolate = this->isolate(); | 677 Isolate* isolate = this->isolate(); |
654 | 678 |
655 Variable var_reason(this, MachineRepresentation::kTagged), | 679 Variable var_reason(this, MachineRepresentation::kTagged), |
656 var_then(this, MachineRepresentation::kTagged); | 680 var_then(this, MachineRepresentation::kTagged); |
657 | 681 |
658 Label do_enqueue(this), fulfill(this), if_cycle(this, Label::kDeferred), | 682 Label do_enqueue(this), fulfill(this), if_cycle(this, Label::kDeferred), |
659 if_rejectpromise(this, Label::kDeferred), out(this); | 683 if_rejectpromise(this, Label::kDeferred), out(this); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 // 11. If IsCallable(thenAction) is false, then | 773 // 11. If IsCallable(thenAction) is false, then |
750 GotoIf(TaggedIsSmi(then), &fulfill); | 774 GotoIf(TaggedIsSmi(then), &fulfill); |
751 Node* const then_map = LoadMap(then); | 775 Node* const then_map = LoadMap(then); |
752 GotoUnless(IsCallableMap(then_map), &fulfill); | 776 GotoUnless(IsCallableMap(then_map), &fulfill); |
753 var_then.Bind(then); | 777 var_then.Bind(then); |
754 Goto(&do_enqueue); | 778 Goto(&do_enqueue); |
755 } | 779 } |
756 | 780 |
757 Bind(&do_enqueue); | 781 Bind(&do_enqueue); |
758 { | 782 { |
| 783 // TODO(gsathya): Add fast path for native promises with unmodified |
| 784 // PromiseThen (which don't need these resolving functions, but |
| 785 // instead can just call resolve/reject directly). |
| 786 Node* resolve = nullptr; |
| 787 Node* reject = nullptr; |
| 788 std::tie(resolve, reject) = CreatePromiseResolvingFunctions( |
| 789 promise, FalseConstant(), native_context); |
| 790 |
| 791 Node* const info = AllocatePromiseResolveThenableJobInfo( |
| 792 result, var_then.value(), resolve, reject, context); |
| 793 |
759 Label enqueue(this); | 794 Label enqueue(this); |
760 GotoUnless(IsDebugActive(), &enqueue); | 795 GotoUnless(IsDebugActive(), &enqueue); |
| 796 |
| 797 Node* const debug_id = CallRuntime(Runtime::kDebugNextMicrotaskId, context); |
| 798 Node* const debug_name = SmiConstant(kDebugPromiseResolveThenableJob); |
| 799 CallRuntime(Runtime::kDebugAsyncTaskEvent, context, |
| 800 SmiConstant(kDebugEnqueue), debug_id, debug_name); |
| 801 |
| 802 StoreObjectField(info, PromiseResolveThenableJobInfo::kDebugIdOffset, |
| 803 debug_id); |
| 804 StoreObjectField(info, PromiseResolveThenableJobInfo::kDebugNameOffset, |
| 805 debug_name); |
| 806 |
761 GotoIf(TaggedIsSmi(result), &enqueue); | 807 GotoIf(TaggedIsSmi(result), &enqueue); |
762 GotoUnless(HasInstanceType(result, JS_PROMISE_TYPE), &enqueue); | 808 GotoUnless(HasInstanceType(result, JS_PROMISE_TYPE), &enqueue); |
| 809 |
763 // Mark the dependency of the new promise on the resolution | 810 // Mark the dependency of the new promise on the resolution |
764 Node* const key = | 811 Node* const key = |
765 HeapConstant(isolate->factory()->promise_handled_by_symbol()); | 812 HeapConstant(isolate->factory()->promise_handled_by_symbol()); |
766 CallRuntime(Runtime::kSetProperty, context, result, key, promise, | 813 CallRuntime(Runtime::kSetProperty, context, result, key, promise, |
767 SmiConstant(STRICT)); | 814 SmiConstant(STRICT)); |
768 Goto(&enqueue); | 815 Goto(&enqueue); |
769 | 816 |
770 // 12. Perform EnqueueJob("PromiseJobs", | 817 // 12. Perform EnqueueJob("PromiseJobs", |
771 // PromiseResolveThenableJob, « promise, resolution, thenAction | 818 // PromiseResolveThenableJob, « promise, resolution, thenAction»). |
772 // »). | |
773 Bind(&enqueue); | 819 Bind(&enqueue); |
774 // TODO(gsathya): Move this to TF | 820 // TODO(gsathya): Move this to TF |
775 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise, | 821 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, info); |
776 result, var_then.value()); | |
777 Goto(&out); | 822 Goto(&out); |
778 } | 823 } |
779 | 824 |
780 // 7.b Return FulfillPromise(promise, resolution). | 825 // 7.b Return FulfillPromise(promise, resolution). |
781 Bind(&fulfill); | 826 Bind(&fulfill); |
782 { | 827 { |
783 PromiseFulfill(context, promise, result, v8::Promise::kFulfilled); | 828 PromiseFulfill(context, promise, result, v8::Promise::kFulfilled); |
784 Goto(&out); | 829 Goto(&out); |
785 } | 830 } |
786 | 831 |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 Node* debug_event = Parameter(2); | 1397 Node* debug_event = Parameter(2); |
1353 Node* context = Parameter(5); | 1398 Node* context = Parameter(5); |
1354 | 1399 |
1355 CSA_ASSERT_JS_ARGC_EQ(this, 2); | 1400 CSA_ASSERT_JS_ARGC_EQ(this, 2); |
1356 | 1401 |
1357 Return(NewPromiseCapability(context, constructor, debug_event)); | 1402 Return(NewPromiseCapability(context, constructor, debug_event)); |
1358 } | 1403 } |
1359 | 1404 |
1360 } // namespace internal | 1405 } // namespace internal |
1361 } // namespace v8 | 1406 } // namespace v8 |
OLD | NEW |