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 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 Goto(&do_enqueue); | 678 Goto(&do_enqueue); |
679 | 679 |
680 Bind(&if_isnotpending); | 680 Bind(&if_isnotpending); |
681 { | 681 { |
682 Label if_fulfilled(this), if_rejected(this); | 682 Label if_fulfilled(this), if_rejected(this); |
683 Branch(SmiEqual(SmiConstant(v8::Promise::kFulfilled), thenable_status), | 683 Branch(SmiEqual(SmiConstant(v8::Promise::kFulfilled), thenable_status), |
684 &if_fulfilled, &if_rejected); | 684 &if_fulfilled, &if_rejected); |
685 | 685 |
686 Bind(&if_fulfilled); | 686 Bind(&if_fulfilled); |
687 { | 687 { |
688 CallRuntime(Runtime::kPromiseFulfill, context, promise, | 688 PromiseFulfill(context, promise, thenable_value, |
689 SmiConstant(v8::Promise::kFulfilled), thenable_value); | 689 v8::Promise::kFulfilled); |
690 PromiseSetHasHandler(promise); | 690 PromiseSetHasHandler(promise); |
691 Goto(&out); | 691 Goto(&out); |
692 } | 692 } |
693 | 693 |
694 Bind(&if_rejected); | 694 Bind(&if_rejected); |
695 { | 695 { |
696 Label reject(this); | 696 Label reject(this); |
697 Node* const has_handler = PromiseHasHandler(result); | 697 Node* const has_handler = PromiseHasHandler(result); |
698 | 698 |
699 // Promise has already been rejected, but had no handler. | 699 // Promise has already been rejected, but had no handler. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 Bind(&enqueue); | 750 Bind(&enqueue); |
751 // TODO(gsathya): Move this to TF | 751 // TODO(gsathya): Move this to TF |
752 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise, | 752 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise, |
753 result, var_then.value()); | 753 result, var_then.value()); |
754 Goto(&out); | 754 Goto(&out); |
755 } | 755 } |
756 | 756 |
757 // 7.b Return FulfillPromise(promise, resolution). | 757 // 7.b Return FulfillPromise(promise, resolution). |
758 Bind(&fulfill); | 758 Bind(&fulfill); |
759 { | 759 { |
760 CallRuntime(Runtime::kPromiseFulfill, context, promise, | 760 PromiseFulfill(context, promise, result, v8::Promise::kFulfilled); |
761 SmiConstant(v8::Promise::kFulfilled), result); | |
762 Goto(&out); | 761 Goto(&out); |
763 } | 762 } |
764 | 763 |
765 Bind(&if_cycle); | 764 Bind(&if_cycle); |
766 { | 765 { |
767 // 6.a Let selfResolutionError be a newly created TypeError object. | 766 // 6.a Let selfResolutionError be a newly created TypeError object. |
768 Node* const message_id = SmiConstant(MessageTemplate::kPromiseCyclic); | 767 Node* const message_id = SmiConstant(MessageTemplate::kPromiseCyclic); |
769 Node* const error = | 768 Node* const error = |
770 CallRuntime(Runtime::kNewTypeError, context, message_id, result); | 769 CallRuntime(Runtime::kNewTypeError, context, message_id, result); |
771 var_reason.Bind(error); | 770 var_reason.Bind(error); |
772 | 771 |
773 // 6.b Return RejectPromise(promise, selfResolutionError). | 772 // 6.b Return RejectPromise(promise, selfResolutionError). |
774 Goto(&if_rejectpromise); | 773 Goto(&if_rejectpromise); |
775 } | 774 } |
776 | 775 |
777 // 9.a Return RejectPromise(promise, then.[[Value]]). | 776 // 9.a Return RejectPromise(promise, then.[[Value]]). |
778 Bind(&if_rejectpromise); | 777 Bind(&if_rejectpromise); |
779 { | 778 { |
780 CallRuntime(Runtime::kPromiseReject, context, promise, var_reason.value(), | 779 CallRuntime(Runtime::kPromiseReject, context, promise, var_reason.value(), |
781 TrueConstant()); | 780 TrueConstant()); |
782 Goto(&out); | 781 Goto(&out); |
783 } | 782 } |
784 | 783 |
785 Bind(&out); | 784 Bind(&out); |
786 } | 785 } |
787 | 786 |
| 787 void PromiseBuiltinsAssembler::PromiseFulfill( |
| 788 Node* context, Node* promise, Node* result, |
| 789 v8::Promise::PromiseState status) { |
| 790 Label do_promisereset(this); |
| 791 |
| 792 Node* const status_smi = SmiConstant(static_cast<int>(status)); |
| 793 Node* const deferred_promise = |
| 794 LoadObjectField(promise, JSPromise::kDeferredPromiseOffset); |
| 795 |
| 796 GotoIf(IsUndefined(deferred_promise), &do_promisereset); |
| 797 |
| 798 Node* const tasks = |
| 799 status == v8::Promise::kFulfilled |
| 800 ? LoadObjectField(promise, JSPromise::kFulfillReactionsOffset) |
| 801 : LoadObjectField(promise, JSPromise::kRejectReactionsOffset); |
| 802 |
| 803 Node* const deferred_on_resolve = |
| 804 LoadObjectField(promise, JSPromise::kDeferredOnResolveOffset); |
| 805 Node* const deferred_on_reject = |
| 806 LoadObjectField(promise, JSPromise::kDeferredOnRejectOffset); |
| 807 |
| 808 Node* const info = AllocatePromiseReactionJobInfo( |
| 809 promise, result, tasks, deferred_promise, deferred_on_resolve, |
| 810 deferred_on_reject, context); |
| 811 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info, status_smi); |
| 812 Goto(&do_promisereset); |
| 813 |
| 814 Bind(&do_promisereset); |
| 815 { |
| 816 StoreObjectField(promise, JSPromise::kStatusOffset, status_smi); |
| 817 StoreObjectField(promise, JSPromise::kResultOffset, result); |
| 818 StoreObjectFieldRoot(promise, JSPromise::kDeferredPromiseOffset, |
| 819 Heap::kUndefinedValueRootIndex); |
| 820 StoreObjectFieldRoot(promise, JSPromise::kDeferredOnResolveOffset, |
| 821 Heap::kUndefinedValueRootIndex); |
| 822 StoreObjectFieldRoot(promise, JSPromise::kDeferredOnRejectOffset, |
| 823 Heap::kUndefinedValueRootIndex); |
| 824 StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset, |
| 825 Heap::kUndefinedValueRootIndex); |
| 826 StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset, |
| 827 Heap::kUndefinedValueRootIndex); |
| 828 } |
| 829 } |
| 830 |
788 // ES#sec-promise-reject-functions | 831 // ES#sec-promise-reject-functions |
789 // Promise Reject Functions | 832 // Promise Reject Functions |
790 BUILTIN(PromiseRejectClosure) { | 833 BUILTIN(PromiseRejectClosure) { |
791 HandleScope scope(isolate); | 834 HandleScope scope(isolate); |
792 | 835 |
793 Handle<Context> context(isolate->context(), isolate); | 836 Handle<Context> context(isolate->context(), isolate); |
794 | 837 |
795 if (PromiseUtils::HasAlreadyVisited(context)) { | 838 if (PromiseUtils::HasAlreadyVisited(context)) { |
796 return isolate->heap()->undefined_value(); | 839 return isolate->heap()->undefined_value(); |
797 } | 840 } |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1197 Node* debug_event = Parameter(2); | 1240 Node* debug_event = Parameter(2); |
1198 Node* context = Parameter(5); | 1241 Node* context = Parameter(5); |
1199 | 1242 |
1200 CSA_ASSERT_JS_ARGC_EQ(this, 2); | 1243 CSA_ASSERT_JS_ARGC_EQ(this, 2); |
1201 | 1244 |
1202 Return(NewPromiseCapability(context, constructor, debug_event)); | 1245 Return(NewPromiseCapability(context, constructor, debug_event)); |
1203 } | 1246 } |
1204 | 1247 |
1205 } // namespace internal | 1248 } // namespace internal |
1206 } // namespace v8 | 1249 } // namespace v8 |
OLD | NEW |