Chromium Code Reviews| 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-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
| 7 #include "src/builtins/builtins.h" | 7 #include "src/builtins/builtins.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/code-stub-assembler.h" | 9 #include "src/code-stub-assembler.h" |
| 10 #include "src/promise-utils.h" | 10 #include "src/promise-utils.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 | 14 |
| 15 typedef compiler::Node Node; | 15 typedef compiler::Node Node; |
| 16 typedef CodeStubAssembler::ParameterMode ParameterMode; | 16 typedef CodeStubAssembler::ParameterMode ParameterMode; |
| 17 typedef compiler::CodeAssemblerState CodeAssemblerState; | 17 typedef compiler::CodeAssemblerState CodeAssemblerState; |
| 18 | 18 |
| 19 Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext( | |
| 20 Node* promise_capability, Node* native_context) { | |
| 21 Node* context = Allocate( | |
| 22 FixedArray::SizeFor(GetPromiseCapabilityExecutor::kContextLength)); | |
| 23 Node* map = HeapConstant(isolate()->factory()->function_context_map()); | |
| 24 StoreMapNoWriteBarrier(context, map); | |
| 25 StoreObjectFieldNoWriteBarrier( | |
| 26 context, FixedArray::kLengthOffset, | |
| 27 SmiConstant(GetPromiseCapabilityExecutor::kContextLength)); | |
| 28 | |
| 29 Node* script = LoadContextElement(native_context, Context::CLOSURE_INDEX); | |
| 30 StoreContextElement(context, Context::CLOSURE_INDEX, script); | |
| 31 StoreContextElement(context, Context::PREVIOUS_INDEX, UndefinedConstant()); | |
| 32 StoreContextElement(context, Context::EXTENSION_INDEX, TheHoleConstant()); | |
| 33 StoreContextElement(context, Context::NATIVE_CONTEXT_INDEX, native_context); | |
|
gsathya
2016/12/21 01:02:33
You refactor this to reuse CreatePromiseResolvingF
| |
| 34 StoreContextElement(context, GetPromiseCapabilityExecutor::kCapabilitySlot, | |
|
gsathya
2016/12/21 01:02:33
StoreContextElementNoWriteBarrier
Igor Sheludko
2016/12/21 12:00:45
We can use it for all the stores because the objec
| |
| 35 promise_capability); | |
| 36 return context; | |
| 37 } | |
| 38 | |
| 39 Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context, | |
| 40 Node* constructor, | |
| 41 Node* debug_event) { | |
| 42 if (debug_event == nullptr) { | |
| 43 debug_event = TrueConstant(); | |
| 44 } | |
| 45 | |
| 46 Node* native_context = LoadNativeContext(context); | |
| 47 | |
| 48 Node* capability = Allocate(JSPromiseCapability::kSize); | |
| 49 StoreMapNoWriteBarrier(capability, Heap::kJSPromiseCapabilityMapRootIndex); | |
|
gsathya
2016/12/21 01:02:33
Why not use AllocateJSObjectFromMap here?
caitp
2016/12/21 21:01:13
Done.
| |
| 50 StoreObjectFieldNoWriteBarrier(capability, JSObject::kPropertiesOffset, | |
| 51 EmptyFixedArrayConstant()); | |
| 52 StoreObjectFieldNoWriteBarrier(capability, JSObject::kElementsOffset, | |
| 53 EmptyFixedArrayConstant()); | |
| 54 StoreObjectFieldNoWriteBarrier( | |
| 55 capability, JSPromiseCapability::kPromiseOffset, UndefinedConstant()); | |
| 56 StoreObjectFieldNoWriteBarrier( | |
| 57 capability, JSPromiseCapability::kResolveOffset, UndefinedConstant()); | |
| 58 StoreObjectFieldNoWriteBarrier(capability, JSPromiseCapability::kRejectOffset, | |
| 59 UndefinedConstant()); | |
| 60 | |
| 61 Variable var_result(this, MachineRepresentation::kTagged); | |
| 62 var_result.Bind(capability); | |
| 63 | |
| 64 Label if_builtin_promise(this), if_custom_promise(this), out(this); | |
| 65 Branch(WordEqual(constructor, | |
| 66 LoadContextElement(native_context, | |
| 67 Context::PROMISE_FUNCTION_INDEX)), | |
| 68 &if_builtin_promise, &if_custom_promise); | |
| 69 | |
| 70 Bind(&if_builtin_promise); | |
| 71 { | |
| 72 Node* promise = AllocateJSPromise(context); | |
| 73 PromiseInit(promise); | |
| 74 StoreObjectFieldNoWriteBarrier( | |
| 75 capability, JSPromiseCapability::kPromiseOffset, promise); | |
| 76 | |
| 77 Node* resolve = nullptr; | |
| 78 Node* reject = nullptr; | |
| 79 | |
| 80 std::tie(resolve, reject) = | |
| 81 CreatePromiseResolvingFunctions(promise, debug_event, native_context); | |
| 82 StoreObjectField(capability, JSPromiseCapability::kResolveOffset, resolve); | |
| 83 StoreObjectField(capability, JSPromiseCapability::kRejectOffset, reject); | |
| 84 | |
| 85 GotoUnless(IsPromiseHookEnabled(), &out); | |
| 86 CallRuntime(Runtime::kPromiseHookInit, context, promise, | |
| 87 UndefinedConstant()); | |
| 88 Goto(&out); | |
| 89 } | |
| 90 | |
| 91 Bind(&if_custom_promise); | |
| 92 { | |
| 93 Label if_notcallable(this, Label::kDeferred); | |
| 94 Node* executor_context = | |
| 95 CreatePromiseGetCapabilitiesExecutorContext(capability, native_context); | |
| 96 Node* executor_info = LoadContextElement( | |
| 97 native_context, Context::PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN); | |
| 98 Node* function_map = LoadContextElement( | |
| 99 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); | |
| 100 Node* executor = AllocateFunctionWithMapAndContext( | |
| 101 function_map, executor_info, executor_context); | |
| 102 | |
| 103 Node* promise = ConstructJS(CodeFactory::Construct(isolate()), context, | |
| 104 constructor, executor); | |
| 105 | |
| 106 Node* resolve = | |
| 107 LoadObjectField(capability, JSPromiseCapability::kResolveOffset); | |
| 108 GotoIf(TaggedIsSmi(resolve), &if_notcallable); | |
| 109 GotoUnless(IsCallableMap(LoadMap(resolve)), &if_notcallable); | |
| 110 | |
| 111 Node* reject = | |
| 112 LoadObjectField(capability, JSPromiseCapability::kRejectOffset); | |
| 113 GotoIf(TaggedIsSmi(reject), &if_notcallable); | |
| 114 GotoUnless(IsCallableMap(LoadMap(reject)), &if_notcallable); | |
| 115 | |
| 116 StoreObjectField(capability, JSPromiseCapability::kPromiseOffset, promise); | |
| 117 | |
| 118 Goto(&out); | |
| 119 | |
| 120 Bind(&if_notcallable); | |
| 121 Node* message = SmiConstant(MessageTemplate::kPromiseNonCallable); | |
| 122 StoreObjectField(capability, JSPromiseCapability::kPromiseOffset, | |
| 123 UndefinedConstant()); | |
| 124 StoreObjectField(capability, JSPromiseCapability::kResolveOffset, | |
| 125 UndefinedConstant()); | |
| 126 StoreObjectField(capability, JSPromiseCapability::kRejectOffset, | |
| 127 UndefinedConstant()); | |
| 128 CallRuntime(Runtime::kThrowTypeError, context, message); | |
| 129 var_result.Bind(UndefinedConstant()); | |
| 130 Goto(&out); | |
| 131 } | |
| 132 | |
| 133 Bind(&out); | |
| 134 return var_result.value(); | |
| 135 } | |
| 136 | |
| 137 Node* PromiseBuiltinsAssembler::NewInternalPromiseCapability(Node* context, | |
| 138 Node* parent) { | |
| 139 Node* promise = AllocateJSPromise(context); | |
| 140 PromiseInit(promise); | |
| 141 | |
| 142 Label out(this); | |
| 143 | |
| 144 Node* capability = Allocate(JSPromiseCapability::kSize); | |
| 145 StoreMapNoWriteBarrier(capability, Heap::kJSPromiseCapabilityMapRootIndex); | |
| 146 StoreObjectFieldNoWriteBarrier(capability, JSObject::kPropertiesOffset, | |
| 147 EmptyFixedArrayConstant()); | |
| 148 StoreObjectFieldNoWriteBarrier(capability, JSObject::kElementsOffset, | |
| 149 EmptyFixedArrayConstant()); | |
| 150 StoreObjectFieldNoWriteBarrier(capability, | |
| 151 JSPromiseCapability::kPromiseOffset, promise); | |
| 152 StoreObjectFieldNoWriteBarrier( | |
| 153 capability, JSPromiseCapability::kResolveOffset, UndefinedConstant()); | |
| 154 StoreObjectFieldNoWriteBarrier(capability, JSPromiseCapability::kRejectOffset, | |
| 155 UndefinedConstant()); | |
| 156 | |
| 157 GotoUnless(IsPromiseHookEnabled(), &out); | |
| 158 CallRuntime(Runtime::kPromiseHookInit, context, promise, parent); | |
| 159 Goto(&out); | |
| 160 | |
| 161 Bind(&out); | |
| 162 return capability; | |
| 163 } | |
| 164 | |
| 19 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( | 165 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( |
| 20 Node* promise, Node* debug_event, Node* native_context) { | 166 Node* promise, Node* debug_event, Node* native_context) { |
| 21 Node* const context = | 167 Node* const context = |
| 22 Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength)); | 168 Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength)); |
| 23 StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex); | 169 StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex); |
| 24 StoreObjectFieldNoWriteBarrier( | 170 StoreObjectFieldNoWriteBarrier( |
| 25 context, FixedArray::kLengthOffset, | 171 context, FixedArray::kLengthOffset, |
| 26 SmiConstant(PromiseUtils::kPromiseContextLength)); | 172 SmiConstant(PromiseUtils::kPromiseContextLength)); |
| 27 | 173 |
| 28 Node* const empty_fn = | 174 Node* const empty_fn = |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 | 477 |
| 332 Goto(&out); | 478 Goto(&out); |
| 333 } | 479 } |
| 334 } | 480 } |
| 335 } | 481 } |
| 336 } | 482 } |
| 337 | 483 |
| 338 Bind(&out); | 484 Bind(&out); |
| 339 PromiseSetHasHandler(promise); | 485 PromiseSetHasHandler(promise); |
| 340 | 486 |
| 341 // TODO(gsathya): This call will be removed once we don't have to | 487 CSA_ASSERT(this, HasInstanceType(deferred, JS_PROMISE_CAPABILITY_TYPE)); |
| 342 // deal with deferred objects. | 488 Node* then_promise = |
| 343 Isolate* isolate = this->isolate(); | 489 LoadObjectField(deferred, JSPromiseCapability::kPromiseOffset); |
| 344 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | 490 return then_promise; |
| 345 Node* const key = | |
| 346 HeapConstant(isolate->factory()->NewStringFromAsciiChecked("promise")); | |
| 347 Node* const result = CallStub(getproperty_callable, context, deferred, key); | |
| 348 | |
| 349 return result; | |
| 350 } | 491 } |
| 351 | 492 |
| 352 // Promise fast path implementations rely on unmodified JSPromise instances. | 493 // Promise fast path implementations rely on unmodified JSPromise instances. |
| 353 // We use a fairly coarse granularity for this and simply check whether both | 494 // We use a fairly coarse granularity for this and simply check whether both |
| 354 // the promise itself is unmodified (i.e. its map has not changed) and its | 495 // the promise itself is unmodified (i.e. its map has not changed) and its |
| 355 // prototype is unmodified. | 496 // prototype is unmodified. |
| 356 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp | 497 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp |
| 357 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise, | 498 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise, |
| 358 Label* if_isunmodified, | 499 Label* if_isunmodified, |
| 359 Label* if_ismodified) { | 500 Label* if_ismodified) { |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 788 perform_promise_then(this); | 929 perform_promise_then(this); |
| 789 Variable var_deferred(this, MachineRepresentation::kTagged); | 930 Variable var_deferred(this, MachineRepresentation::kTagged); |
| 790 | 931 |
| 791 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, | 932 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, |
| 792 &promise_capability); | 933 &promise_capability); |
| 793 | 934 |
| 794 // TODO(gsathya): Remove deferred object and move | 935 // TODO(gsathya): Remove deferred object and move |
| 795 // NewPromiseCapabability functions to TF. | 936 // NewPromiseCapabability functions to TF. |
| 796 Bind(&fast_promise_capability); | 937 Bind(&fast_promise_capability); |
| 797 { | 938 { |
| 798 // TODO(gsathya): Move this to TF. | 939 Node* const capability = NewInternalPromiseCapability(context, promise); |
| 799 Node* const promise_internal_capability = LoadContextElement( | |
| 800 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); | |
| 801 Node* const capability = | |
| 802 CallJS(call_callable, context, promise_internal_capability, | |
| 803 UndefinedConstant(), promise); | |
| 804 var_deferred.Bind(capability); | 940 var_deferred.Bind(capability); |
| 805 Goto(&perform_promise_then); | 941 Goto(&perform_promise_then); |
| 806 } | 942 } |
| 807 | 943 |
| 808 Bind(&promise_capability); | 944 Bind(&promise_capability); |
| 809 { | 945 { |
| 810 // TODO(gsathya): Move this to TF. | 946 Node* const capability = NewPromiseCapability(context, constructor); |
| 811 Node* const new_promise_capability = LoadContextElement( | |
| 812 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); | |
| 813 Node* const capability = | |
| 814 CallJS(call_callable, context, new_promise_capability, | |
| 815 UndefinedConstant(), constructor); | |
| 816 var_deferred.Bind(capability); | 947 var_deferred.Bind(capability); |
| 817 Goto(&perform_promise_then); | 948 Goto(&perform_promise_then); |
| 818 } | 949 } |
| 819 | 950 |
| 820 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, | 951 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, |
| 821 // resultCapability). | 952 // resultCapability). |
| 822 Bind(&perform_promise_then); | 953 Bind(&perform_promise_then); |
| 823 Node* const result = InternalPerformPromiseThen( | 954 Node* const result = InternalPerformPromiseThen( |
| 824 context, promise, on_resolve, on_reject, var_deferred.value()); | 955 context, promise, on_resolve, on_reject, var_deferred.value()); |
| 825 Return(result); | 956 Return(result); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 898 | 1029 |
| 899 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { | 1030 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { |
| 900 Node* const promise = Parameter(1); | 1031 Node* const promise = Parameter(1); |
| 901 Node* const value = Parameter(2); | 1032 Node* const value = Parameter(2); |
| 902 Node* const handler = Parameter(3); | 1033 Node* const handler = Parameter(3); |
| 903 Node* const deferred = Parameter(4); | 1034 Node* const deferred = Parameter(4); |
| 904 Node* const context = Parameter(7); | 1035 Node* const context = Parameter(7); |
| 905 Isolate* isolate = this->isolate(); | 1036 Isolate* isolate = this->isolate(); |
| 906 | 1037 |
| 907 // Get promise from deferred | 1038 // Get promise from deferred |
| 908 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | 1039 CSA_ASSERT(this, HasInstanceType(deferred, JS_PROMISE_CAPABILITY_TYPE)); |
| 909 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | |
| 910 Node* const key = HeapConstant(isolate->factory()->promise_string()); | |
| 911 Node* const deferred_promise = | 1040 Node* const deferred_promise = |
| 912 CallStub(getproperty_callable, context, deferred, key); | 1041 LoadObjectField(deferred, JSPromiseCapability::kPromiseOffset); |
| 913 | 1042 |
| 914 Variable var_reason(this, MachineRepresentation::kTagged); | 1043 Variable var_reason(this, MachineRepresentation::kTagged); |
| 915 | 1044 |
| 916 Node* const is_debug_active = IsDebugActive(); | 1045 Node* const is_debug_active = IsDebugActive(); |
| 917 Label run_handler(this), if_rejectpromise(this), promisehook_before(this), | 1046 Label run_handler(this), if_rejectpromise(this), promisehook_before(this), |
| 918 promisehook_after(this), debug_pop(this); | 1047 promisehook_after(this), debug_pop(this); |
| 919 | 1048 |
| 920 GotoUnless(is_debug_active, &promisehook_before); | 1049 GotoUnless(is_debug_active, &promisehook_before); |
| 921 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); | 1050 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); |
| 922 Goto(&promisehook_before); | 1051 Goto(&promisehook_before); |
| 923 | 1052 |
| 924 Bind(&promisehook_before); | 1053 Bind(&promisehook_before); |
| 925 { | 1054 { |
| 926 GotoUnless(IsPromiseHookEnabled(), &run_handler); | 1055 GotoUnless(IsPromiseHookEnabled(), &run_handler); |
| 927 CallRuntime(Runtime::kPromiseHookBefore, context, promise); | 1056 CallRuntime(Runtime::kPromiseHookBefore, context, promise); |
| 928 Goto(&run_handler); | 1057 Goto(&run_handler); |
| 929 } | 1058 } |
| 930 | 1059 |
| 931 Bind(&run_handler); | 1060 Bind(&run_handler); |
| 932 { | 1061 { |
| 933 Callable call_callable = CodeFactory::Call(isolate); | 1062 Callable call_callable = CodeFactory::Call(isolate); |
| 934 | 1063 |
| 935 Node* const result = | 1064 Node* const result = |
| 936 CallJS(call_callable, context, handler, UndefinedConstant(), value); | 1065 CallJS(call_callable, context, handler, UndefinedConstant(), value); |
| 937 | 1066 |
| 938 GotoIfException(result, &if_rejectpromise, &var_reason); | 1067 GotoIfException(result, &if_rejectpromise, &var_reason); |
| 939 | 1068 |
| 940 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | |
| 941 Node* const key = HeapConstant(isolate->factory()->resolve_string()); | |
| 942 Node* const on_resolve = | 1069 Node* const on_resolve = |
| 943 CallStub(getproperty_callable, context, deferred, key); | 1070 LoadObjectField(deferred, JSPromiseCapability::kResolveOffset); |
| 944 | 1071 |
| 945 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); | 1072 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); |
| 946 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); | 1073 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); |
| 947 | 1074 |
| 948 Bind(&if_internalhandler); | 1075 Bind(&if_internalhandler); |
| 949 InternalResolvePromise(context, deferred_promise, result, | 1076 InternalResolvePromise(context, deferred_promise, result, |
| 950 &promisehook_after); | 1077 &promisehook_after); |
| 951 | 1078 |
| 952 Bind(&if_customhandler); | 1079 Bind(&if_customhandler); |
| 953 { | 1080 { |
| 954 Node* const maybe_exception = CallJS(call_callable, context, on_resolve, | 1081 Node* const maybe_exception = CallJS(call_callable, context, on_resolve, |
| 955 UndefinedConstant(), result); | 1082 UndefinedConstant(), result); |
| 956 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); | 1083 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); |
| 957 Goto(&promisehook_after); | 1084 Goto(&promisehook_after); |
| 958 } | 1085 } |
| 959 } | 1086 } |
| 960 | 1087 |
| 961 Bind(&if_rejectpromise); | 1088 Bind(&if_rejectpromise); |
| 962 { | 1089 { |
| 963 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. | |
| 964 Node* const key = HeapConstant(isolate->factory()->reject_string()); | |
| 965 Node* const on_reject = | 1090 Node* const on_reject = |
| 966 CallStub(getproperty_callable, context, deferred, key); | 1091 LoadObjectField(deferred, JSPromiseCapability::kRejectOffset); |
| 967 | 1092 |
| 968 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); | 1093 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); |
| 969 CallStub(promise_handle_reject, context, deferred_promise, on_reject, | 1094 CallStub(promise_handle_reject, context, deferred_promise, on_reject, |
| 970 var_reason.value()); | 1095 var_reason.value()); |
| 971 Goto(&promisehook_after); | 1096 Goto(&promisehook_after); |
| 972 } | 1097 } |
| 973 | 1098 |
| 974 Bind(&promisehook_after); | 1099 Bind(&promisehook_after); |
| 975 { | 1100 { |
| 976 GotoUnless(IsPromiseHookEnabled(), &debug_pop); | 1101 GotoUnless(IsPromiseHookEnabled(), &debug_pop); |
| 977 CallRuntime(Runtime::kPromiseHookAfter, context, promise); | 1102 CallRuntime(Runtime::kPromiseHookAfter, context, promise); |
| 978 Goto(&debug_pop); | 1103 Goto(&debug_pop); |
| 979 } | 1104 } |
| 980 | 1105 |
| 981 Bind(&debug_pop); | 1106 Bind(&debug_pop); |
| 982 { | 1107 { |
| 983 Label out(this); | 1108 Label out(this); |
| 984 | 1109 |
| 985 GotoUnless(is_debug_active, &out); | 1110 GotoUnless(is_debug_active, &out); |
| 986 CallRuntime(Runtime::kDebugPopPromise, context); | 1111 CallRuntime(Runtime::kDebugPopPromise, context); |
| 987 Goto(&out); | 1112 Goto(&out); |
| 988 | 1113 |
| 989 Bind(&out); | 1114 Bind(&out); |
| 990 Return(UndefinedConstant()); | 1115 Return(UndefinedConstant()); |
| 991 } | 1116 } |
| 992 } | 1117 } |
| 993 | 1118 |
| 1119 TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) { | |
| 1120 Node* const resolve = Parameter(1); | |
| 1121 Node* const reject = Parameter(2); | |
| 1122 Node* const context = Parameter(5); | |
| 1123 | |
| 1124 Node* const capability = LoadContextElement( | |
| 1125 context, GetPromiseCapabilityExecutor::kCapabilitySlot); | |
| 1126 | |
| 1127 Label if_alreadyinvoked(this, Label::kDeferred); | |
| 1128 GotoIf(WordNotEqual( | |
| 1129 LoadObjectField(capability, JSPromiseCapability::kResolveOffset), | |
| 1130 UndefinedConstant()), | |
| 1131 &if_alreadyinvoked); | |
| 1132 GotoIf(WordNotEqual( | |
| 1133 LoadObjectField(capability, JSPromiseCapability::kRejectOffset), | |
| 1134 UndefinedConstant()), | |
| 1135 &if_alreadyinvoked); | |
| 1136 | |
| 1137 StoreObjectField(capability, JSPromiseCapability::kResolveOffset, resolve); | |
| 1138 StoreObjectField(capability, JSPromiseCapability::kRejectOffset, reject); | |
| 1139 | |
| 1140 Return(UndefinedConstant()); | |
| 1141 | |
| 1142 Bind(&if_alreadyinvoked); | |
| 1143 Node* message = SmiConstant(MessageTemplate::kPromiseExecutorAlreadyInvoked); | |
| 1144 Return(CallRuntime(Runtime::kThrowTypeError, context, message)); | |
| 1145 } | |
| 1146 | |
| 1147 TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) { | |
| 1148 Node* constructor = Parameter(1); | |
| 1149 Node* debug_event = Parameter(2); | |
| 1150 Node* context = Parameter(5); | |
| 1151 | |
| 1152 CSA_ASSERT_JS_ARGC_EQ(this, 2); | |
| 1153 | |
| 1154 Return(NewPromiseCapability(context, constructor, debug_event)); | |
| 1155 } | |
| 1156 | |
| 1157 TF_BUILTIN(NewInternalPromiseCapability, PromiseBuiltinsAssembler) { | |
| 1158 Node* parent = Parameter(1); | |
| 1159 Node* context = Parameter(4); | |
| 1160 CSA_ASSERT_JS_ARGC_EQ(this, 1); | |
| 1161 | |
| 1162 Return(NewInternalPromiseCapability(context, parent)); | |
| 1163 } | |
| 1164 | |
| 994 } // namespace internal | 1165 } // namespace internal |
| 995 } // namespace v8 | 1166 } // namespace v8 |
| OLD | NEW |