Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(689)

Side by Side Diff: src/builtins/builtins-promise.cc

Issue 2567333002: [promises] port NewPromiseCapability to TF (Closed)
Patch Set: git rid of stuff that snuck into patch Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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::CreatePromiseResolvingFunctionsContext( 19 Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context,
20 Node* promise, Node* debug_event, Node* native_context) { 20 Node* constructor,
21 Node* const context = 21 Node* debug_event) {
22 Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength)); 22 if (debug_event == nullptr) {
23 StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex); 23 debug_event = TrueConstant();
24 }
25
26 Node* native_context = LoadNativeContext(context);
27
28 Node* map = LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex);
29 Node* capability = AllocateJSObjectFromMap(map);
30
24 StoreObjectFieldNoWriteBarrier( 31 StoreObjectFieldNoWriteBarrier(
25 context, FixedArray::kLengthOffset, 32 capability, JSPromiseCapability::kPromiseOffset, UndefinedConstant());
26 SmiConstant(PromiseUtils::kPromiseContextLength)); 33 StoreObjectFieldNoWriteBarrier(
34 capability, JSPromiseCapability::kResolveOffset, UndefinedConstant());
35 StoreObjectFieldNoWriteBarrier(capability, JSPromiseCapability::kRejectOffset,
36 UndefinedConstant());
27 37
28 Node* const empty_fn = 38 Variable var_result(this, MachineRepresentation::kTagged);
29 LoadContextElement(native_context, Context::CLOSURE_INDEX); 39 var_result.Bind(capability);
30 StoreContextElementNoWriteBarrier(context, Context::CLOSURE_INDEX, empty_fn); 40
41 Label if_builtin_promise(this), if_custom_promise(this), out(this);
gsathya 2016/12/29 21:48:47 if_custom_promise can be deferred
42 Branch(WordEqual(constructor,
43 LoadContextElement(native_context,
44 Context::PROMISE_FUNCTION_INDEX)),
45 &if_builtin_promise, &if_custom_promise);
46
47 Bind(&if_builtin_promise);
48 {
49 Node* promise = AllocateJSPromise(context);
50 PromiseInit(promise);
51 StoreObjectFieldNoWriteBarrier(
52 capability, JSPromiseCapability::kPromiseOffset, promise);
53
54 Node* resolve = nullptr;
55 Node* reject = nullptr;
56
57 std::tie(resolve, reject) =
58 CreatePromiseResolvingFunctions(promise, debug_event, native_context);
59 StoreObjectField(capability, JSPromiseCapability::kResolveOffset, resolve);
60 StoreObjectField(capability, JSPromiseCapability::kRejectOffset, reject);
61
62 GotoUnless(IsPromiseHookEnabled(), &out);
63 CallRuntime(Runtime::kPromiseHookInit, context, promise,
64 UndefinedConstant());
65 Goto(&out);
66 }
67
68 Bind(&if_custom_promise);
69 {
70 Label if_notcallable(this, Label::kDeferred);
71 Node* executor_context =
72 CreatePromiseGetCapabilitiesExecutorContext(capability, native_context);
73 Node* executor_info = LoadContextElement(
74 native_context, Context::PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN);
75 Node* function_map = LoadContextElement(
76 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
77 Node* executor = AllocateFunctionWithMapAndContext(
78 function_map, executor_info, executor_context);
79
80 Node* promise = ConstructJS(CodeFactory::Construct(isolate()), context,
81 constructor, executor);
82
83 Node* resolve =
84 LoadObjectField(capability, JSPromiseCapability::kResolveOffset);
85 GotoIf(TaggedIsSmi(resolve), &if_notcallable);
86 GotoUnless(IsCallableMap(LoadMap(resolve)), &if_notcallable);
87
88 Node* reject =
89 LoadObjectField(capability, JSPromiseCapability::kRejectOffset);
90 GotoIf(TaggedIsSmi(reject), &if_notcallable);
91 GotoUnless(IsCallableMap(LoadMap(reject)), &if_notcallable);
92
93 StoreObjectField(capability, JSPromiseCapability::kPromiseOffset, promise);
94
95 Goto(&out);
96
97 Bind(&if_notcallable);
98 Node* message = SmiConstant(MessageTemplate::kPromiseNonCallable);
99 StoreObjectField(capability, JSPromiseCapability::kPromiseOffset,
100 UndefinedConstant());
101 StoreObjectField(capability, JSPromiseCapability::kResolveOffset,
102 UndefinedConstant());
103 StoreObjectField(capability, JSPromiseCapability::kRejectOffset,
104 UndefinedConstant());
105 CallRuntime(Runtime::kThrowTypeError, context, message);
106 var_result.Bind(UndefinedConstant());
107 Goto(&out);
108 }
109
110 Bind(&out);
111 return var_result.value();
112 }
113
114 Node* PromiseBuiltinsAssembler::NewInternalPromiseCapability(Node* context,
115 Node* parent) {
116 Node* promise = AllocateJSPromise(context);
117 PromiseInit(promise);
118
119 Label out(this);
120
121 Node* map = LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex);
122 Node* capability = AllocateJSObjectFromMap(map);
123 StoreObjectFieldNoWriteBarrier(capability,
124 JSPromiseCapability::kPromiseOffset, promise);
125 StoreObjectFieldNoWriteBarrier(
126 capability, JSPromiseCapability::kResolveOffset, UndefinedConstant());
127 StoreObjectFieldNoWriteBarrier(capability, JSPromiseCapability::kRejectOffset,
128 UndefinedConstant());
129
130 GotoUnless(IsPromiseHookEnabled(), &out);
131 CallRuntime(Runtime::kPromiseHookInit, context, promise, parent);
132 Goto(&out);
133
134 Bind(&out);
135 return capability;
136 }
137
138 Node* PromiseBuiltinsAssembler::CreatePromiseContext(Node* native_context,
139 int slots) {
140 DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS);
141 Node* script = LoadContextElement(native_context, Context::CLOSURE_INDEX);
142 Node* map = HeapConstant(isolate()->factory()->function_context_map());
143 Node* context = Allocate(FixedArray::SizeFor(slots));
144 StoreMapNoWriteBarrier(context, map);
145 StoreObjectFieldNoWriteBarrier(context, FixedArray::kLengthOffset,
146 SmiConstant(slots));
147 StoreContextElementNoWriteBarrier(context, Context::CLOSURE_INDEX, script);
31 StoreContextElementNoWriteBarrier(context, Context::PREVIOUS_INDEX, 148 StoreContextElementNoWriteBarrier(context, Context::PREVIOUS_INDEX,
32 UndefinedConstant()); 149 UndefinedConstant());
33 StoreContextElementNoWriteBarrier(context, Context::EXTENSION_INDEX, 150 StoreContextElementNoWriteBarrier(context, Context::EXTENSION_INDEX,
34 TheHoleConstant()); 151 TheHoleConstant());
35 StoreContextElementNoWriteBarrier(context, Context::NATIVE_CONTEXT_INDEX, 152 StoreContextElementNoWriteBarrier(context, Context::NATIVE_CONTEXT_INDEX,
36 native_context); 153 native_context);
154 return context;
155 }
156
157 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
158 Node* promise, Node* debug_event, Node* native_context) {
159 Node* const context =
160 CreatePromiseContext(native_context, PromiseUtils::kPromiseContextLength);
37 StoreContextElementNoWriteBarrier(context, PromiseUtils::kAlreadyVisitedSlot, 161 StoreContextElementNoWriteBarrier(context, PromiseUtils::kAlreadyVisitedSlot,
38 SmiConstant(0)); 162 SmiConstant(0));
39 StoreContextElementNoWriteBarrier(context, PromiseUtils::kPromiseSlot, 163 StoreContextElementNoWriteBarrier(context, PromiseUtils::kPromiseSlot,
40 promise); 164 promise);
41 StoreContextElementNoWriteBarrier(context, PromiseUtils::kDebugEventSlot, 165 StoreContextElementNoWriteBarrier(context, PromiseUtils::kDebugEventSlot,
42 debug_event); 166 debug_event);
43 return context; 167 return context;
44 } 168 }
45 169
170 Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext(
171 Node* promise_capability, Node* native_context) {
172 int kSize = GetPromiseCapabilityExecutor::kContextLength;
173 Node* context = CreatePromiseContext(native_context, kSize);
174 StoreContextElementNoWriteBarrier(
175 context, GetPromiseCapabilityExecutor::kCapabilitySlot,
176 promise_capability);
177 return context;
178 }
179
46 std::pair<Node*, Node*> 180 std::pair<Node*, Node*>
47 PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions( 181 PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions(
48 Node* promise, Node* debug_event, Node* native_context) { 182 Node* promise, Node* debug_event, Node* native_context) {
49 Node* const promise_context = CreatePromiseResolvingFunctionsContext( 183 Node* const promise_context = CreatePromiseResolvingFunctionsContext(
50 promise, debug_event, native_context); 184 promise, debug_event, native_context);
51 Node* const map = LoadContextElement( 185 Node* const map = LoadContextElement(
52 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); 186 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
53 Node* const resolve_info = 187 Node* const resolve_info =
54 LoadContextElement(native_context, Context::PROMISE_RESOLVE_SHARED_FUN); 188 LoadContextElement(native_context, Context::PROMISE_RESOLVE_SHARED_FUN);
55 Node* const resolve = 189 Node* const resolve =
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 333
200 // 4. Let resultCapability be ? NewPromiseCapability(C). 334 // 4. Let resultCapability be ? NewPromiseCapability(C).
201 Callable call_callable = CodeFactory::Call(isolate); 335 Callable call_callable = CodeFactory::Call(isolate);
202 Label fast_promise_capability(this), promise_capability(this), 336 Label fast_promise_capability(this), promise_capability(this),
203 perform_promise_then(this); 337 perform_promise_then(this);
204 Variable var_deferred(this, MachineRepresentation::kTagged); 338 Variable var_deferred(this, MachineRepresentation::kTagged);
205 339
206 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, 340 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability,
207 &promise_capability); 341 &promise_capability);
208 342
209 // TODO(gsathya): Remove deferred object and move 343 // TODO(gsathya): Remove deferred object.
210 // NewPromiseCapabability functions to TF.
211 Bind(&fast_promise_capability); 344 Bind(&fast_promise_capability);
212 { 345 {
213 // TODO(gsathya): Move this to TF. 346 Node* const capability = NewInternalPromiseCapability(context, promise);
214 Node* const promise_internal_capability = LoadContextElement(
215 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX);
216 Node* const capability =
217 CallJS(call_callable, context, promise_internal_capability,
218 UndefinedConstant(), promise);
219 var_deferred.Bind(capability); 347 var_deferred.Bind(capability);
220 Goto(&perform_promise_then); 348 Goto(&perform_promise_then);
221 } 349 }
222 350
223 Bind(&promise_capability); 351 Bind(&promise_capability);
224 { 352 {
225 // TODO(gsathya): Move this to TF. 353 Node* const capability = NewPromiseCapability(context, constructor);
226 Node* const new_promise_capability = LoadContextElement(
227 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX);
228 Node* const capability =
229 CallJS(call_callable, context, new_promise_capability,
230 UndefinedConstant(), constructor);
231 var_deferred.Bind(capability); 354 var_deferred.Bind(capability);
232 Goto(&perform_promise_then); 355 Goto(&perform_promise_then);
233 } 356 }
234 357
235 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, 358 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
236 // resultCapability). 359 // resultCapability).
237 Bind(&perform_promise_then); 360 Bind(&perform_promise_then);
238 Node* const result = InternalPerformPromiseThen( 361 Node* const result = InternalPerformPromiseThen(
239 context, promise, on_resolve, on_reject, var_deferred.value()); 362 context, promise, on_resolve, on_reject, var_deferred.value());
240 return result; 363 return result;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 513
391 Goto(&out); 514 Goto(&out);
392 } 515 }
393 } 516 }
394 } 517 }
395 } 518 }
396 519
397 Bind(&out); 520 Bind(&out);
398 PromiseSetHasHandler(promise); 521 PromiseSetHasHandler(promise);
399 522
400 // TODO(gsathya): This call will be removed once we don't have to 523 CSA_ASSERT(this, HasInstanceType(deferred, JS_PROMISE_CAPABILITY_TYPE));
401 // deal with deferred objects. 524 Node* then_promise =
402 Isolate* isolate = this->isolate(); 525 LoadObjectField(deferred, JSPromiseCapability::kPromiseOffset);
403 Callable getproperty_callable = CodeFactory::GetProperty(isolate); 526 return then_promise;
404 Node* const key =
405 HeapConstant(isolate->factory()->NewStringFromAsciiChecked("promise"));
406 Node* const result = CallStub(getproperty_callable, context, deferred, key);
407
408 return result;
409 } 527 }
410 528
411 // Promise fast path implementations rely on unmodified JSPromise instances. 529 // Promise fast path implementations rely on unmodified JSPromise instances.
412 // We use a fairly coarse granularity for this and simply check whether both 530 // We use a fairly coarse granularity for this and simply check whether both
413 // the promise itself is unmodified (i.e. its map has not changed) and its 531 // the promise itself is unmodified (i.e. its map has not changed) and its
414 // prototype is unmodified. 532 // prototype is unmodified.
415 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp 533 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp
416 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise, 534 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise,
417 Label* if_isunmodified, 535 Label* if_isunmodified,
418 Label* if_ismodified) { 536 Label* if_ismodified) {
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 handle(PromiseUtils::GetDebugEvent(context), isolate); 729 handle(PromiseUtils::GetDebugEvent(context), isolate);
612 MaybeHandle<Object> maybe_result; 730 MaybeHandle<Object> maybe_result;
613 Handle<Object> argv[] = {promise, value, debug_event}; 731 Handle<Object> argv[] = {promise, value, debug_event};
614 RETURN_FAILURE_ON_EXCEPTION( 732 RETURN_FAILURE_ON_EXCEPTION(
615 isolate, Execution::Call(isolate, isolate->promise_internal_reject(), 733 isolate, Execution::Call(isolate, isolate->promise_internal_reject(),
616 isolate->factory()->undefined_value(), 734 isolate->factory()->undefined_value(),
617 arraysize(argv), argv)); 735 arraysize(argv), argv));
618 return isolate->heap()->undefined_value(); 736 return isolate->heap()->undefined_value();
619 } 737 }
620 738
621 // ES#sec-createresolvingfunctions
622 // CreateResolvingFunctions ( promise )
623 TF_BUILTIN(CreateResolvingFunctions, PromiseBuiltinsAssembler) {
624 Node* const promise = Parameter(1);
625 Node* const debug_event = Parameter(2);
626 Node* const context = Parameter(5);
627 Node* const native_context = LoadNativeContext(context);
628
629 Node* resolve = nullptr;
630 Node* reject = nullptr;
631
632 std::tie(resolve, reject) =
633 CreatePromiseResolvingFunctions(promise, debug_event, native_context);
634
635 Node* const kSize = IntPtrConstant(2);
636 const ElementsKind kind = FAST_ELEMENTS;
637 const WriteBarrierMode barrier_mode = SKIP_WRITE_BARRIER;
638 const ParameterMode parameter_mode = INTPTR_PARAMETERS;
639 Node* const arr = AllocateFixedArray(kind, kSize, parameter_mode);
640 StoreFixedArrayElement(arr, 0, resolve, barrier_mode);
641 StoreFixedArrayElement(arr, 1, reject, barrier_mode);
642
643 Node* const array_map = LoadJSArrayElementsMap(kind, native_context);
644 Node* const length = SmiTag(kSize);
645 Node* const result = AllocateUninitializedJSArrayWithoutElements(
646 kind, array_map, length, nullptr);
647
648 StoreObjectField(result, JSObject::kElementsOffset, arr);
649 Return(result);
650 }
651
652 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { 739 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
653 Node* const executor = Parameter(1); 740 Node* const executor = Parameter(1);
654 Node* const new_target = Parameter(2); 741 Node* const new_target = Parameter(2);
655 Node* const context = Parameter(4); 742 Node* const context = Parameter(4);
656 Isolate* isolate = this->isolate(); 743 Isolate* isolate = this->isolate();
657 744
658 Label if_targetisundefined(this, Label::kDeferred); 745 Label if_targetisundefined(this, Label::kDeferred);
659 746
660 GotoIf(IsUndefined(new_target), &if_targetisundefined); 747 GotoIf(IsUndefined(new_target), &if_targetisundefined);
661 748
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 995
909 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { 996 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) {
910 Node* const promise = Parameter(1); 997 Node* const promise = Parameter(1);
911 Node* const value = Parameter(2); 998 Node* const value = Parameter(2);
912 Node* const handler = Parameter(3); 999 Node* const handler = Parameter(3);
913 Node* const deferred = Parameter(4); 1000 Node* const deferred = Parameter(4);
914 Node* const context = Parameter(7); 1001 Node* const context = Parameter(7);
915 Isolate* isolate = this->isolate(); 1002 Isolate* isolate = this->isolate();
916 1003
917 // Get promise from deferred 1004 // Get promise from deferred
918 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. 1005 CSA_ASSERT(this, HasInstanceType(deferred, JS_PROMISE_CAPABILITY_TYPE));
919 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
920 Node* const key = HeapConstant(isolate->factory()->promise_string());
921 Node* const deferred_promise = 1006 Node* const deferred_promise =
922 CallStub(getproperty_callable, context, deferred, key); 1007 LoadObjectField(deferred, JSPromiseCapability::kPromiseOffset);
923 1008
924 Variable var_reason(this, MachineRepresentation::kTagged); 1009 Variable var_reason(this, MachineRepresentation::kTagged);
925 1010
926 Node* const is_debug_active = IsDebugActive(); 1011 Node* const is_debug_active = IsDebugActive();
927 Label run_handler(this), if_rejectpromise(this), promisehook_before(this), 1012 Label run_handler(this), if_rejectpromise(this), promisehook_before(this),
928 promisehook_after(this), debug_pop(this); 1013 promisehook_after(this), debug_pop(this);
929 1014
930 GotoUnless(is_debug_active, &promisehook_before); 1015 GotoUnless(is_debug_active, &promisehook_before);
931 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); 1016 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise);
932 Goto(&promisehook_before); 1017 Goto(&promisehook_before);
933 1018
934 Bind(&promisehook_before); 1019 Bind(&promisehook_before);
935 { 1020 {
936 GotoUnless(IsPromiseHookEnabled(), &run_handler); 1021 GotoUnless(IsPromiseHookEnabled(), &run_handler);
937 CallRuntime(Runtime::kPromiseHookBefore, context, promise); 1022 CallRuntime(Runtime::kPromiseHookBefore, context, promise);
938 Goto(&run_handler); 1023 Goto(&run_handler);
939 } 1024 }
940 1025
941 Bind(&run_handler); 1026 Bind(&run_handler);
942 { 1027 {
943 Callable call_callable = CodeFactory::Call(isolate); 1028 Callable call_callable = CodeFactory::Call(isolate);
944 1029
945 Node* const result = 1030 Node* const result =
946 CallJS(call_callable, context, handler, UndefinedConstant(), value); 1031 CallJS(call_callable, context, handler, UndefinedConstant(), value);
947 1032
948 GotoIfException(result, &if_rejectpromise, &var_reason); 1033 GotoIfException(result, &if_rejectpromise, &var_reason);
949 1034
950 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
951 Node* const key = HeapConstant(isolate->factory()->resolve_string());
952 Node* const on_resolve = 1035 Node* const on_resolve =
953 CallStub(getproperty_callable, context, deferred, key); 1036 LoadObjectField(deferred, JSPromiseCapability::kResolveOffset);
954 1037
955 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); 1038 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
956 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); 1039 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler);
957 1040
958 Bind(&if_internalhandler); 1041 Bind(&if_internalhandler);
959 InternalResolvePromise(context, deferred_promise, result); 1042 InternalResolvePromise(context, deferred_promise, result);
960 Goto(&promisehook_after); 1043 Goto(&promisehook_after);
961 1044
962 Bind(&if_customhandler); 1045 Bind(&if_customhandler);
963 { 1046 {
964 Node* const maybe_exception = CallJS(call_callable, context, on_resolve, 1047 Node* const maybe_exception = CallJS(call_callable, context, on_resolve,
965 UndefinedConstant(), result); 1048 UndefinedConstant(), result);
966 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); 1049 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
967 Goto(&promisehook_after); 1050 Goto(&promisehook_after);
968 } 1051 }
969 } 1052 }
970 1053
971 Bind(&if_rejectpromise); 1054 Bind(&if_rejectpromise);
972 { 1055 {
973 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
974 Node* const key = HeapConstant(isolate->factory()->reject_string());
975 Node* const on_reject = 1056 Node* const on_reject =
976 CallStub(getproperty_callable, context, deferred, key); 1057 LoadObjectField(deferred, JSPromiseCapability::kRejectOffset);
977 1058
978 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); 1059 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
979 CallStub(promise_handle_reject, context, deferred_promise, on_reject, 1060 CallStub(promise_handle_reject, context, deferred_promise, on_reject,
980 var_reason.value()); 1061 var_reason.value());
981 Goto(&promisehook_after); 1062 Goto(&promisehook_after);
982 } 1063 }
983 1064
984 Bind(&promisehook_after); 1065 Bind(&promisehook_after);
985 { 1066 {
986 GotoUnless(IsPromiseHookEnabled(), &debug_pop); 1067 GotoUnless(IsPromiseHookEnabled(), &debug_pop);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 Callable getproperty_callable = CodeFactory::GetProperty(isolate); 1108 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
1028 Node* const then = 1109 Node* const then =
1029 CallStub(getproperty_callable, context, promise, then_str); 1110 CallStub(getproperty_callable, context, promise, then_str);
1030 Callable call_callable = CodeFactory::Call(isolate); 1111 Callable call_callable = CodeFactory::Call(isolate);
1031 Node* const result = 1112 Node* const result =
1032 CallJS(call_callable, context, then, promise, on_resolve, on_reject); 1113 CallJS(call_callable, context, then, promise, on_resolve, on_reject);
1033 Return(result); 1114 Return(result);
1034 } 1115 }
1035 } 1116 }
1036 1117
1118 TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) {
1119 Node* const resolve = Parameter(1);
1120 Node* const reject = Parameter(2);
1121 Node* const context = Parameter(5);
1122
1123 Node* const capability = LoadContextElement(
1124 context, GetPromiseCapabilityExecutor::kCapabilitySlot);
1125
1126 Label if_alreadyinvoked(this, Label::kDeferred);
1127 GotoIf(WordNotEqual(
1128 LoadObjectField(capability, JSPromiseCapability::kResolveOffset),
1129 UndefinedConstant()),
1130 &if_alreadyinvoked);
1131 GotoIf(WordNotEqual(
1132 LoadObjectField(capability, JSPromiseCapability::kRejectOffset),
1133 UndefinedConstant()),
1134 &if_alreadyinvoked);
1135
1136 StoreObjectField(capability, JSPromiseCapability::kResolveOffset, resolve);
1137 StoreObjectField(capability, JSPromiseCapability::kRejectOffset, reject);
1138
1139 Return(UndefinedConstant());
1140
1141 Bind(&if_alreadyinvoked);
1142 Node* message = SmiConstant(MessageTemplate::kPromiseExecutorAlreadyInvoked);
1143 Return(CallRuntime(Runtime::kThrowTypeError, context, message));
1144 }
1145
1146 TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) {
1147 Node* constructor = Parameter(1);
1148 Node* debug_event = Parameter(2);
1149 Node* context = Parameter(5);
1150
1151 CSA_ASSERT_JS_ARGC_EQ(this, 2);
1152
1153 Return(NewPromiseCapability(context, constructor, debug_event));
1154 }
1155
1156 TF_BUILTIN(NewInternalPromiseCapability, PromiseBuiltinsAssembler) {
1157 Node* parent = Parameter(1);
1158 Node* context = Parameter(4);
1159 CSA_ASSERT_JS_ARGC_EQ(this, 1);
1160
1161 Return(NewInternalPromiseCapability(context, parent));
1162 }
1163
1037 } // namespace internal 1164 } // namespace internal
1038 } // namespace v8 1165 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698