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" |
11 #include "src/promise-utils.h" | 11 #include "src/promise-utils.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 typedef compiler::Node Node; | 16 typedef compiler::Node Node; |
17 typedef CodeStubAssembler::ParameterMode ParameterMode; | 17 typedef CodeStubAssembler::ParameterMode ParameterMode; |
18 typedef compiler::CodeAssemblerState CodeAssemblerState; | 18 typedef compiler::CodeAssemblerState CodeAssemblerState; |
19 | 19 |
20 Node* PromiseBuiltinsAssembler::AllocateAndInitPromise(Node* context, | 20 Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) { |
21 Node* parent) { | 21 Node* const native_context = LoadNativeContext(context); |
| 22 Node* const promise_fun = |
| 23 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); |
| 24 Node* const initial_map = |
| 25 LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset); |
| 26 Node* const instance = AllocateJSObjectFromMap(initial_map); |
| 27 return instance; |
| 28 } |
| 29 |
| 30 void PromiseBuiltinsAssembler::PromiseInit(Node* promise) { |
| 31 StoreObjectField(promise, JSPromise::kStatusOffset, |
| 32 SmiConstant(v8::Promise::kPending)); |
| 33 StoreObjectField(promise, JSPromise::kFlagsOffset, SmiConstant(0)); |
| 34 } |
| 35 |
| 36 Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context) { |
| 37 return AllocateAndInitJSPromise(context, UndefinedConstant()); |
| 38 } |
| 39 |
| 40 Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context, |
| 41 Node* parent) { |
22 Node* const instance = AllocateJSPromise(context); | 42 Node* const instance = AllocateJSPromise(context); |
23 PromiseInit(instance); | 43 PromiseInit(instance); |
24 | 44 |
25 Label out(this); | 45 Label out(this); |
26 GotoUnless(IsPromiseHookEnabled(), &out); | 46 GotoUnless(IsPromiseHookEnabled(), &out); |
27 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent); | 47 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent); |
28 Goto(&out); | 48 Goto(&out); |
29 | 49 |
30 Bind(&out); | 50 Bind(&out); |
31 return instance; | 51 return instance; |
32 } | 52 } |
33 | 53 |
| 54 Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise(Node* context, |
| 55 Node* status, |
| 56 Node* result) { |
| 57 CSA_ASSERT(this, TaggedIsSmi(status)); |
| 58 |
| 59 Node* const instance = AllocateJSPromise(context); |
| 60 |
| 61 StoreObjectFieldNoWriteBarrier(instance, JSPromise::kStatusOffset, status); |
| 62 StoreObjectFieldNoWriteBarrier(instance, JSPromise::kResultOffset, result); |
| 63 StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset, |
| 64 SmiConstant(0)); |
| 65 |
| 66 Label out(this); |
| 67 GotoUnless(IsPromiseHookEnabled(), &out); |
| 68 CallRuntime(Runtime::kPromiseHookInit, context, instance, |
| 69 UndefinedConstant()); |
| 70 Goto(&out); |
| 71 |
| 72 Bind(&out); |
| 73 return instance; |
| 74 } |
| 75 |
34 std::pair<Node*, Node*> | 76 std::pair<Node*, Node*> |
35 PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions( | 77 PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions( |
36 Node* promise, Node* debug_event, Node* native_context) { | 78 Node* promise, Node* debug_event, Node* native_context) { |
37 Node* const promise_context = CreatePromiseResolvingFunctionsContext( | 79 Node* const promise_context = CreatePromiseResolvingFunctionsContext( |
38 promise, debug_event, native_context); | 80 promise, debug_event, native_context); |
39 Node* const map = LoadContextElement( | 81 Node* const map = LoadContextElement( |
40 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); | 82 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); |
41 Node* const resolve_info = | 83 Node* const resolve_info = |
42 LoadContextElement(native_context, Context::PROMISE_RESOLVE_SHARED_FUN); | 84 LoadContextElement(native_context, Context::PROMISE_RESOLVE_SHARED_FUN); |
43 Node* const resolve = | 85 Node* const resolve = |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 perform_promise_then(this); | 372 perform_promise_then(this); |
331 Variable var_deferred_promise(this, MachineRepresentation::kTagged), | 373 Variable var_deferred_promise(this, MachineRepresentation::kTagged), |
332 var_deferred_on_resolve(this, MachineRepresentation::kTagged), | 374 var_deferred_on_resolve(this, MachineRepresentation::kTagged), |
333 var_deferred_on_reject(this, MachineRepresentation::kTagged); | 375 var_deferred_on_reject(this, MachineRepresentation::kTagged); |
334 | 376 |
335 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, | 377 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, |
336 &promise_capability); | 378 &promise_capability); |
337 | 379 |
338 Bind(&fast_promise_capability); | 380 Bind(&fast_promise_capability); |
339 { | 381 { |
340 Node* const deferred_promise = AllocateAndInitPromise(context, promise); | 382 Node* const deferred_promise = AllocateAndInitJSPromise(context, promise); |
341 var_deferred_promise.Bind(deferred_promise); | 383 var_deferred_promise.Bind(deferred_promise); |
342 var_deferred_on_resolve.Bind(UndefinedConstant()); | 384 var_deferred_on_resolve.Bind(UndefinedConstant()); |
343 var_deferred_on_reject.Bind(UndefinedConstant()); | 385 var_deferred_on_reject.Bind(UndefinedConstant()); |
344 Goto(&perform_promise_then); | 386 Goto(&perform_promise_then); |
345 } | 387 } |
346 | 388 |
347 Bind(&promise_capability); | 389 Bind(&promise_capability); |
348 { | 390 { |
349 Node* const capability = NewPromiseCapability(context, constructor); | 391 Node* const capability = NewPromiseCapability(context, constructor); |
350 var_deferred_promise.Bind( | 392 var_deferred_promise.Bind( |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 | 826 |
785 Node* const executor_map = LoadMap(executor); | 827 Node* const executor_map = LoadMap(executor); |
786 GotoUnless(IsCallableMap(executor_map), &if_notcallable); | 828 GotoUnless(IsCallableMap(executor_map), &if_notcallable); |
787 | 829 |
788 Node* const native_context = LoadNativeContext(context); | 830 Node* const native_context = LoadNativeContext(context); |
789 Node* const promise_fun = | 831 Node* const promise_fun = |
790 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); | 832 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); |
791 Node* const is_debug_active = IsDebugActive(); | 833 Node* const is_debug_active = IsDebugActive(); |
792 Label if_targetisnotmodified(this), | 834 Label if_targetisnotmodified(this), |
793 if_targetismodified(this, Label::kDeferred), run_executor(this), | 835 if_targetismodified(this, Label::kDeferred), run_executor(this), |
794 debug_push(this), init(this); | 836 debug_push(this); |
795 | 837 |
796 Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified, | 838 Branch(WordEqual(promise_fun, new_target), &if_targetisnotmodified, |
797 &if_targetismodified); | 839 &if_targetismodified); |
798 | 840 |
799 Variable var_result(this, MachineRepresentation::kTagged), | 841 Variable var_result(this, MachineRepresentation::kTagged), |
800 var_reject_call(this, MachineRepresentation::kTagged), | 842 var_reject_call(this, MachineRepresentation::kTagged), |
801 var_reason(this, MachineRepresentation::kTagged); | 843 var_reason(this, MachineRepresentation::kTagged); |
802 | 844 |
803 Bind(&if_targetisnotmodified); | 845 Bind(&if_targetisnotmodified); |
804 { | 846 { |
805 Node* const instance = AllocateJSPromise(context); | 847 Node* const instance = AllocateAndInitJSPromise(context); |
806 var_result.Bind(instance); | 848 var_result.Bind(instance); |
807 Goto(&init); | 849 Goto(&debug_push); |
808 } | 850 } |
809 | 851 |
810 Bind(&if_targetismodified); | 852 Bind(&if_targetismodified); |
811 { | 853 { |
812 ConstructorBuiltinsAssembler constructor_assembler(this->state()); | 854 ConstructorBuiltinsAssembler constructor_assembler(this->state()); |
813 Node* const instance = constructor_assembler.EmitFastNewObject( | 855 Node* const instance = constructor_assembler.EmitFastNewObject( |
814 context, promise_fun, new_target); | 856 context, promise_fun, new_target); |
| 857 PromiseInit(instance); |
| 858 var_result.Bind(instance); |
815 | 859 |
816 var_result.Bind(instance); | |
817 Goto(&init); | |
818 } | |
819 | |
820 Bind(&init); | |
821 { | |
822 PromiseInit(var_result.value()); | |
823 GotoUnless(IsPromiseHookEnabled(), &debug_push); | 860 GotoUnless(IsPromiseHookEnabled(), &debug_push); |
824 CallRuntime(Runtime::kPromiseHookInit, context, var_result.value(), | 861 CallRuntime(Runtime::kPromiseHookInit, context, instance, |
825 UndefinedConstant()); | 862 UndefinedConstant()); |
826 Goto(&debug_push); | 863 Goto(&debug_push); |
827 } | 864 } |
828 | 865 |
829 Bind(&debug_push); | 866 Bind(&debug_push); |
830 { | 867 { |
831 GotoUnless(is_debug_active, &run_executor); | 868 GotoUnless(is_debug_active, &run_executor); |
832 CallRuntime(Runtime::kDebugPushPromise, context, var_result.value()); | 869 CallRuntime(Runtime::kDebugPushPromise, context, var_result.value()); |
833 Goto(&run_executor); | 870 Goto(&run_executor); |
834 } | 871 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 Node* const message_id = | 916 Node* const message_id = |
880 SmiConstant(MessageTemplate::kResolverNotAFunction); | 917 SmiConstant(MessageTemplate::kResolverNotAFunction); |
881 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); | 918 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); |
882 Return(UndefinedConstant()); // Never reached. | 919 Return(UndefinedConstant()); // Never reached. |
883 } | 920 } |
884 } | 921 } |
885 | 922 |
886 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { | 923 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { |
887 Node* const parent = Parameter(1); | 924 Node* const parent = Parameter(1); |
888 Node* const context = Parameter(4); | 925 Node* const context = Parameter(4); |
889 Return(AllocateAndInitPromise(context, parent)); | 926 Return(AllocateAndInitJSPromise(context, parent)); |
890 } | 927 } |
891 | 928 |
892 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { | 929 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { |
893 Node* const status = Parameter(1); | 930 Node* const status = Parameter(1); |
894 Node* const result = Parameter(2); | 931 Node* const result = Parameter(2); |
895 Node* const context = Parameter(5); | 932 Node* const context = Parameter(5); |
896 | 933 |
897 Node* const instance = AllocateJSPromise(context); | 934 Node* const instance = AllocateAndSetJSPromise(context, status, result); |
898 PromiseSet(instance, status, result); | |
899 | |
900 Label out(this); | |
901 GotoUnless(IsPromiseHookEnabled(), &out); | |
902 CallRuntime(Runtime::kPromiseHookInit, context, instance, | |
903 UndefinedConstant()); | |
904 Goto(&out); | |
905 Bind(&out); | |
906 Return(instance); | 935 Return(instance); |
907 } | 936 } |
908 | 937 |
909 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { | 938 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { |
910 Node* const maybe_promise = Parameter(1); | 939 Node* const maybe_promise = Parameter(1); |
911 Label if_notpromise(this, Label::kDeferred); | 940 Label if_notpromise(this, Label::kDeferred); |
912 | 941 |
913 GotoIf(TaggedIsSmi(maybe_promise), &if_notpromise); | 942 GotoIf(TaggedIsSmi(maybe_promise), &if_notpromise); |
914 | 943 |
915 Node* const result = | 944 Node* const result = |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 Node* debug_event = Parameter(2); | 1197 Node* debug_event = Parameter(2); |
1169 Node* context = Parameter(5); | 1198 Node* context = Parameter(5); |
1170 | 1199 |
1171 CSA_ASSERT_JS_ARGC_EQ(this, 2); | 1200 CSA_ASSERT_JS_ARGC_EQ(this, 2); |
1172 | 1201 |
1173 Return(NewPromiseCapability(context, constructor, debug_event)); | 1202 Return(NewPromiseCapability(context, constructor, debug_event)); |
1174 } | 1203 } |
1175 | 1204 |
1176 } // namespace internal | 1205 } // namespace internal |
1177 } // namespace v8 | 1206 } // namespace v8 |
OLD | NEW |