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

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

Issue 2590563003: [promises] Remove deferred object (Closed)
Patch Set: Remove comment 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
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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::AllocateAndInitPromise(Node* context,
20 Node* parent) {
21 Node* const instance = AllocateJSPromise(context);
22 PromiseInit(instance);
23
24 Label out(this);
25 GotoUnless(IsPromiseHookEnabled(), &out);
26 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
27 Goto(&out);
28
29 Bind(&out);
30 return instance;
31 }
32
19 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( 33 Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
20 Node* promise, Node* debug_event, Node* native_context) { 34 Node* promise, Node* debug_event, Node* native_context) {
21 Node* const context = 35 Node* const context =
22 Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength)); 36 Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength));
23 StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex); 37 StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex);
24 StoreObjectFieldNoWriteBarrier( 38 StoreObjectFieldNoWriteBarrier(
25 context, FixedArray::kLengthOffset, 39 context, FixedArray::kLengthOffset,
26 SmiConstant(PromiseUtils::kPromiseContextLength)); 40 SmiConstant(PromiseUtils::kPromiseContextLength));
27 41
28 Node* const empty_fn = 42 Node* const empty_fn =
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 Node* new_elements = AllocateFixedArray(kind, new_capacity, mode, flags); 188 Node* new_elements = AllocateFixedArray(kind, new_capacity, mode, flags);
175 189
176 CopyFixedArrayElements(kind, elements, new_elements, length, barrier_mode, 190 CopyFixedArrayElements(kind, elements, new_elements, length, barrier_mode,
177 mode); 191 mode);
178 StoreFixedArrayElement(new_elements, length, value, barrier_mode, 192 StoreFixedArrayElement(new_elements, length, value, barrier_mode,
179 additional_offset, mode); 193 additional_offset, mode);
180 194
181 StoreObjectField(promise, offset, new_elements); 195 StoreObjectField(promise, offset, new_elements);
182 } 196 }
183 197
184 Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(Node* context, 198 Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(
185 Node* promise, 199 Node* context, Node* promise, Node* on_resolve, Node* on_reject,
186 Node* on_resolve, 200 Node* deferred_promise, Node* deferred_on_resolve,
187 Node* on_reject, 201 Node* deferred_on_reject) {
188 Node* deferred) {
189 Node* const native_context = LoadNativeContext(context); 202 Node* const native_context = LoadNativeContext(context);
190 203
191 Variable var_on_resolve(this, MachineRepresentation::kTagged), 204 Variable var_on_resolve(this, MachineRepresentation::kTagged),
192 var_on_reject(this, MachineRepresentation::kTagged); 205 var_on_reject(this, MachineRepresentation::kTagged);
193 206
194 var_on_resolve.Bind(on_resolve); 207 var_on_resolve.Bind(on_resolve);
195 var_on_reject.Bind(on_reject); 208 var_on_reject.Bind(on_reject);
196 209
197 Label out(this), if_onresolvenotcallable(this), onrejectcheck(this), 210 Label out(this), if_onresolvenotcallable(this), onrejectcheck(this),
198 append_callbacks(this); 211 append_callbacks(this);
(...skipping 27 matching lines...) Expand all
226 } 239 }
227 } 240 }
228 241
229 Bind(&append_callbacks); 242 Bind(&append_callbacks);
230 { 243 {
231 Label fulfilled_check(this); 244 Label fulfilled_check(this);
232 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset); 245 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset);
233 GotoUnless(SmiEqual(status, SmiConstant(kPromisePending)), 246 GotoUnless(SmiEqual(status, SmiConstant(kPromisePending)),
234 &fulfilled_check); 247 &fulfilled_check);
235 248
236 Node* const existing_deferred = 249 Node* const existing_deferred_promise =
237 LoadObjectField(promise, JSPromise::kDeferredOffset); 250 LoadObjectField(promise, JSPromise::kDeferredPromiseOffset);
238 251
239 Label if_noexistingcallbacks(this), if_existingcallbacks(this); 252 Label if_noexistingcallbacks(this), if_existingcallbacks(this);
240 Branch(IsUndefined(existing_deferred), &if_noexistingcallbacks, 253 Branch(IsUndefined(existing_deferred_promise), &if_noexistingcallbacks,
241 &if_existingcallbacks); 254 &if_existingcallbacks);
242 255
243 Bind(&if_noexistingcallbacks); 256 Bind(&if_noexistingcallbacks);
244 { 257 {
245 // Store callbacks directly in the slots. 258 // Store callbacks directly in the slots.
246 StoreObjectField(promise, JSPromise::kDeferredOffset, deferred); 259 StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
260 deferred_promise);
261 StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
262 deferred_on_resolve);
263 StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
264 deferred_on_reject);
247 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset, 265 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
248 var_on_resolve.value()); 266 var_on_resolve.value());
249 StoreObjectField(promise, JSPromise::kRejectReactionsOffset, 267 StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
250 var_on_reject.value()); 268 var_on_reject.value());
251 Goto(&out); 269 Goto(&out);
252 } 270 }
253 271
254 Bind(&if_existingcallbacks); 272 Bind(&if_existingcallbacks);
255 { 273 {
256 Label if_singlecallback(this), if_multiplecallbacks(this); 274 Label if_singlecallback(this), if_multiplecallbacks(this);
257 BranchIfJSObject(existing_deferred, &if_singlecallback, 275 BranchIfJSObject(existing_deferred_promise, &if_singlecallback,
258 &if_multiplecallbacks); 276 &if_multiplecallbacks);
259 277
260 Bind(&if_singlecallback); 278 Bind(&if_singlecallback);
261 { 279 {
262 // Create new FixedArrays to store callbacks, and migrate 280 // Create new FixedArrays to store callbacks, and migrate
263 // existing callbacks. 281 // existing callbacks.
264 Node* const deferreds = 282 Node* const deferred_promises =
265 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 283 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
266 StoreFixedArrayElement(deferreds, 0, existing_deferred); 284 StoreFixedArrayElement(deferred_promises, 0, existing_deferred_promise);
267 StoreFixedArrayElement(deferreds, 1, deferred); 285 StoreFixedArrayElement(deferred_promises, 1, deferred_promise);
286
287 Node* const deferred_on_resolves =
288 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
289 StoreFixedArrayElement(
290 deferred_on_resolves, 0,
291 LoadObjectField(promise, JSPromise::kDeferredOnResolveOffset));
292 StoreFixedArrayElement(deferred_on_resolve, 1, deferred_on_resolve);
293
294 Node* const deferred_on_rejects =
295 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
296 StoreFixedArrayElement(
297 deferred_on_rejects, 0,
298 LoadObjectField(promise, JSPromise::kDeferredOnRejectOffset));
299 StoreFixedArrayElement(deferred_on_rejects, 1, deferred_on_reject);
268 300
269 Node* const fulfill_reactions = 301 Node* const fulfill_reactions =
270 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 302 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
271 StoreFixedArrayElement( 303 StoreFixedArrayElement(
272 fulfill_reactions, 0, 304 fulfill_reactions, 0,
273 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset)); 305 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset));
274 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value()); 306 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value());
275 307
276 Node* const reject_reactions = 308 Node* const reject_reactions =
277 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 309 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
278 StoreFixedArrayElement( 310 StoreFixedArrayElement(
279 reject_reactions, 0, 311 reject_reactions, 0,
280 LoadObjectField(promise, JSPromise::kRejectReactionsOffset)); 312 LoadObjectField(promise, JSPromise::kRejectReactionsOffset));
281 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value()); 313 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value());
282 314
283 // Store new FixedArrays in promise. 315 // Store new FixedArrays in promise.
284 StoreObjectField(promise, JSPromise::kDeferredOffset, deferreds); 316 StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
caitp 2016/12/20 02:53:01 The multiple chains case seems likely to regress w
317 deferred_promises);
318 StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
319 deferred_on_resolves);
320 StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
321 deferred_on_rejects);
285 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset, 322 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
286 fulfill_reactions); 323 fulfill_reactions);
287 StoreObjectField(promise, JSPromise::kRejectReactionsOffset, 324 StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
288 reject_reactions); 325 reject_reactions);
289 Goto(&out); 326 Goto(&out);
290 } 327 }
291 328
292 Bind(&if_multiplecallbacks); 329 Bind(&if_multiplecallbacks);
293 { 330 {
294 AppendPromiseCallback(JSPromise::kDeferredOffset, promise, deferred); 331 AppendPromiseCallback(JSPromise::kDeferredPromiseOffset, promise,
332 deferred_promise);
333 AppendPromiseCallback(JSPromise::kDeferredOnResolveOffset, promise,
334 deferred_on_resolve);
335 AppendPromiseCallback(JSPromise::kDeferredOnRejectOffset, promise,
336 deferred_on_reject);
295 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise, 337 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise,
296 var_on_resolve.value()); 338 var_on_resolve.value());
297 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise, 339 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise,
298 var_on_reject.value()); 340 var_on_reject.value());
299 Goto(&out); 341 Goto(&out);
300 } 342 }
301 } 343 }
302 344
303 Bind(&fulfilled_check); 345 Bind(&fulfilled_check);
304 { 346 {
305 Label reject(this); 347 Label reject(this);
306 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset); 348 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset);
307 GotoUnless(WordEqual(status, SmiConstant(kPromiseFulfilled)), &reject); 349 GotoUnless(WordEqual(status, SmiConstant(kPromiseFulfilled)), &reject);
308 350
309 // TODO(gsathya): Move this to TF. 351 Node* info = AllocatePromiseReactionJobInfo(
310 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, result, 352 promise, result, var_on_resolve.value(), deferred_promise,
311 var_on_resolve.value(), deferred, 353 deferred_on_resolve, deferred_on_reject, context);
354 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
312 SmiConstant(kPromiseFulfilled)); 355 SmiConstant(kPromiseFulfilled));
313 Goto(&out); 356 Goto(&out);
314 357
315 Bind(&reject); 358 Bind(&reject);
316 { 359 {
317 Node* const has_handler = PromiseHasHandler(promise); 360 Node* const has_handler = PromiseHasHandler(promise);
318 Label enqueue(this); 361 Label enqueue(this);
319 362
320 // TODO(gsathya): Fold these runtime calls and move to TF. 363 // TODO(gsathya): Fold these runtime calls and move to TF.
321 GotoIf(has_handler, &enqueue); 364 GotoIf(has_handler, &enqueue);
322 CallRuntime(Runtime::kPromiseRevokeReject, context, promise); 365 CallRuntime(Runtime::kPromiseRevokeReject, context, promise);
323 Goto(&enqueue); 366 Goto(&enqueue);
324 367
325 Bind(&enqueue); 368 Bind(&enqueue);
326 { 369 {
327 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, 370 Node* info = AllocatePromiseReactionJobInfo(
328 result, var_on_reject.value(), deferred, 371 promise, result, var_on_reject.value(), deferred_promise,
372 deferred_on_resolve, deferred_on_reject, context);
373 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
329 SmiConstant(kPromiseRejected)); 374 SmiConstant(kPromiseRejected));
330 375
331 Goto(&out); 376 Goto(&out);
332 } 377 }
333 } 378 }
334 } 379 }
335 } 380 }
336 381
337 Bind(&out); 382 Bind(&out);
338 PromiseSetHasHandler(promise); 383 PromiseSetHasHandler(promise);
339 384 return deferred_promise;
340 // TODO(gsathya): This call will be removed once we don't have to
341 // deal with deferred objects.
342 Isolate* isolate = this->isolate();
343 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
344 Node* const key =
345 HeapConstant(isolate->factory()->NewStringFromAsciiChecked("promise"));
346 Node* const result = CallStub(getproperty_callable, context, deferred, key);
347
348 return result;
349 } 385 }
350 386
351 // Promise fast path implementations rely on unmodified JSPromise instances. 387 // Promise fast path implementations rely on unmodified JSPromise instances.
352 // We use a fairly coarse granularity for this and simply check whether both 388 // We use a fairly coarse granularity for this and simply check whether both
353 // the promise itself is unmodified (i.e. its map has not changed) and its 389 // the promise itself is unmodified (i.e. its map has not changed) and its
354 // prototype is unmodified. 390 // prototype is unmodified.
355 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp 391 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp
356 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise, 392 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise,
357 Label* if_isunmodified, 393 Label* if_isunmodified,
358 Label* if_ismodified) { 394 Label* if_ismodified) {
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 Node* const message_id = 734 Node* const message_id =
699 SmiConstant(MessageTemplate::kResolverNotAFunction); 735 SmiConstant(MessageTemplate::kResolverNotAFunction);
700 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); 736 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
701 Return(UndefinedConstant()); // Never reached. 737 Return(UndefinedConstant()); // Never reached.
702 } 738 }
703 } 739 }
704 740
705 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { 741 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
706 Node* const parent = Parameter(1); 742 Node* const parent = Parameter(1);
707 Node* const context = Parameter(4); 743 Node* const context = Parameter(4);
708 Node* const instance = AllocateJSPromise(context); 744 Return(AllocateAndInitPromise(context, parent));
709 PromiseInit(instance);
710
711 Label out(this);
712 GotoUnless(IsPromiseHookEnabled(), &out);
713 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
714 Goto(&out);
715 Bind(&out);
716
717 Return(instance);
718 } 745 }
719 746
720 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { 747 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) {
721 Node* const status = Parameter(1); 748 Node* const status = Parameter(1);
722 Node* const result = Parameter(2); 749 Node* const result = Parameter(2);
723 Node* const context = Parameter(5); 750 Node* const context = Parameter(5);
724 751
725 Node* const instance = AllocateJSPromise(context); 752 Node* const instance = AllocateJSPromise(context);
726 PromiseSet(instance, status, result); 753 PromiseSet(instance, status, result);
727 754
(...skipping 17 matching lines...) Expand all
745 Return(result); 772 Return(result);
746 773
747 Bind(&if_notpromise); 774 Bind(&if_notpromise);
748 Return(FalseConstant()); 775 Return(FalseConstant());
749 } 776 }
750 777
751 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) { 778 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) {
752 Node* const promise = Parameter(1); 779 Node* const promise = Parameter(1);
753 Node* const on_resolve = Parameter(2); 780 Node* const on_resolve = Parameter(2);
754 Node* const on_reject = Parameter(3); 781 Node* const on_reject = Parameter(3);
755 Node* const deferred = Parameter(4); 782 Node* const deferred_promise = Parameter(4);
756 Node* const context = Parameter(7); 783 Node* const context = Parameter(7);
757 784
758 Node* const result = InternalPerformPromiseThen(context, promise, on_resolve, 785 // No deferred_on_resolve/deferred_on_reject because this is just an
759 on_reject, deferred); 786 // internal promise created by async-await.
787 Node* const result = InternalPerformPromiseThen(
788 context, promise, on_resolve, on_reject, deferred_promise,
789 UndefinedConstant(), UndefinedConstant());
760 790
761 // TODO(gsathya): This is unused, but value is returned according to spec. 791 // TODO(gsathya): This is unused, but value is returned according to spec.
762 Return(result); 792 Return(result);
763 } 793 }
764 794
765 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) { 795 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) {
766 // 1. Let promise be the this value. 796 // 1. Let promise be the this value.
767 Node* const promise = Parameter(0); 797 Node* const promise = Parameter(0);
768 Node* const on_resolve = Parameter(1); 798 Node* const on_resolve = Parameter(1);
769 Node* const on_reject = Parameter(2); 799 Node* const on_reject = Parameter(2);
770 Node* const context = Parameter(5); 800 Node* const context = Parameter(5);
771 Isolate* isolate = this->isolate(); 801 Isolate* isolate = this->isolate();
772 802
773 // 2. If IsPromise(promise) is false, throw a TypeError exception. 803 // 2. If IsPromise(promise) is false, throw a TypeError exception.
774 ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE, 804 ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE,
775 "Promise.prototype.then"); 805 "Promise.prototype.then");
776 806
777 Node* const native_context = LoadNativeContext(context); 807 Node* const native_context = LoadNativeContext(context);
778 Node* const promise_fun = 808 Node* const promise_fun =
779 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); 809 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
780 810
781 // 3. Let C be ? SpeciesConstructor(promise, %Promise%). 811 // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
782 Node* constructor = SpeciesConstructor(context, promise, promise_fun); 812 Node* constructor = SpeciesConstructor(context, promise, promise_fun);
783 813
784 // 4. Let resultCapability be ? NewPromiseCapability(C). 814 // 4. Let resultCapability be ? NewPromiseCapability(C).
785 Callable call_callable = CodeFactory::Call(isolate); 815 Callable call_callable = CodeFactory::Call(isolate);
786 Label fast_promise_capability(this), promise_capability(this), 816 Label fast_promise_capability(this), promise_capability(this),
787 perform_promise_then(this); 817 perform_promise_then(this);
788 Variable var_deferred(this, MachineRepresentation::kTagged); 818 Variable var_deferred_promise(this, MachineRepresentation::kTagged),
819 var_deferred_on_resolve(this, MachineRepresentation::kTagged),
820 var_deferred_on_reject(this, MachineRepresentation::kTagged);
789 821
790 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, 822 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability,
791 &promise_capability); 823 &promise_capability);
792 824
793 // TODO(gsathya): Remove deferred object and move
794 // NewPromiseCapabability functions to TF.
795 Bind(&fast_promise_capability); 825 Bind(&fast_promise_capability);
796 { 826 {
797 // TODO(gsathya): Move this to TF. 827 Node* const deferred_promise = AllocateAndInitPromise(context, promise);
798 Node* const promise_internal_capability = LoadContextElement( 828 PromiseInit(deferred_promise);
799 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); 829 var_deferred_promise.Bind(deferred_promise);
800 Node* const capability = 830 var_deferred_on_resolve.Bind(UndefinedConstant());
801 CallJS(call_callable, context, promise_internal_capability, 831 var_deferred_on_reject.Bind(UndefinedConstant());
802 UndefinedConstant(), promise);
803 var_deferred.Bind(capability);
804 Goto(&perform_promise_then); 832 Goto(&perform_promise_then);
805 } 833 }
806 834
807 Bind(&promise_capability); 835 Bind(&promise_capability);
808 { 836 {
809 // TODO(gsathya): Move this to TF. 837 // TODO(gsathya): Move this to TF.
810 Node* const new_promise_capability = LoadContextElement( 838 Node* const new_promise_capability = LoadContextElement(
811 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); 839 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX);
812 Node* const capability = 840 Node* const deferred =
813 CallJS(call_callable, context, new_promise_capability, 841 CallJS(call_callable, context, new_promise_capability,
814 UndefinedConstant(), constructor); 842 UndefinedConstant(), constructor);
815 var_deferred.Bind(capability); 843 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
844 Node* key = HeapConstant(isolate->factory()->promise_string());
845 Node* const deferred_promise =
846 CallStub(getproperty_callable, context, deferred, key);
847 var_deferred_promise.Bind(deferred_promise);
848
849 key = HeapConstant(isolate->factory()->resolve_string());
850 Node* const deferred_on_resolve =
851 CallStub(getproperty_callable, context, deferred, key);
852 var_deferred_on_resolve.Bind(deferred_on_resolve);
853
854 key = HeapConstant(isolate->factory()->reject_string());
855 Node* const deferred_on_reject =
856 CallStub(getproperty_callable, context, deferred, key);
857 var_deferred_on_reject.Bind(deferred_on_reject);
858
816 Goto(&perform_promise_then); 859 Goto(&perform_promise_then);
817 } 860 }
818 861
819 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, 862 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
820 // resultCapability). 863 // resultCapability).
821 Bind(&perform_promise_then); 864 Bind(&perform_promise_then);
822 Node* const result = InternalPerformPromiseThen( 865 Node* const result = InternalPerformPromiseThen(
823 context, promise, on_resolve, on_reject, var_deferred.value()); 866 context, promise, on_resolve, on_reject, var_deferred_promise.value(),
867 var_deferred_on_resolve.value(), var_deferred_on_reject.value());
824 Return(result); 868 Return(result);
825 } 869 }
826 870
827 // ES#sec-promise-resolve-functions 871 // ES#sec-promise-resolve-functions
828 // Promise Resolve Functions 872 // Promise Resolve Functions
829 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) { 873 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) {
830 Node* const value = Parameter(1); 874 Node* const value = Parameter(1);
831 Node* const context = Parameter(4); 875 Node* const context = Parameter(4);
832 876
833 Label out(this); 877 Label out(this);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 { 936 {
893 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception); 937 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception);
894 Return(UndefinedConstant()); 938 Return(UndefinedConstant());
895 } 939 }
896 } 940 }
897 941
898 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { 942 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) {
899 Node* const promise = Parameter(1); 943 Node* const promise = Parameter(1);
900 Node* const value = Parameter(2); 944 Node* const value = Parameter(2);
901 Node* const handler = Parameter(3); 945 Node* const handler = Parameter(3);
902 Node* const deferred = Parameter(4); 946 Node* const deferred_promise = Parameter(4);
903 Node* const context = Parameter(7); 947 Node* const deferred_on_resolve = Parameter(5);
948 Node* const deferred_on_reject = Parameter(6);
949 Node* const context = Parameter(9);
904 Isolate* isolate = this->isolate(); 950 Isolate* isolate = this->isolate();
905 951
906 // Get promise from deferred 952 // Get promise from deferred
907 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
908 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
909 Node* const key = HeapConstant(isolate->factory()->promise_string());
910 Node* const deferred_promise =
911 CallStub(getproperty_callable, context, deferred, key);
912
913 Variable var_reason(this, MachineRepresentation::kTagged); 953 Variable var_reason(this, MachineRepresentation::kTagged);
914 954
915 Node* const is_debug_active = IsDebugActive(); 955 Node* const is_debug_active = IsDebugActive();
916 Label run_handler(this), if_rejectpromise(this), promisehook_before(this), 956 Label run_handler(this), if_rejectpromise(this), promisehook_before(this),
917 promisehook_after(this), debug_pop(this); 957 promisehook_after(this), debug_pop(this);
918 958
919 GotoUnless(is_debug_active, &promisehook_before); 959 GotoUnless(is_debug_active, &promisehook_before);
920 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); 960 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise);
921 Goto(&promisehook_before); 961 Goto(&promisehook_before);
922 962
923 Bind(&promisehook_before); 963 Bind(&promisehook_before);
924 { 964 {
925 GotoUnless(IsPromiseHookEnabled(), &run_handler); 965 GotoUnless(IsPromiseHookEnabled(), &run_handler);
926 CallRuntime(Runtime::kPromiseHookBefore, context, promise); 966 CallRuntime(Runtime::kPromiseHookBefore, context, promise);
927 Goto(&run_handler); 967 Goto(&run_handler);
928 } 968 }
929 969
930 Bind(&run_handler); 970 Bind(&run_handler);
931 { 971 {
932 Callable call_callable = CodeFactory::Call(isolate); 972 Callable call_callable = CodeFactory::Call(isolate);
933
934 Node* const result = 973 Node* const result =
935 CallJS(call_callable, context, handler, UndefinedConstant(), value); 974 CallJS(call_callable, context, handler, UndefinedConstant(), value);
936 975
937 GotoIfException(result, &if_rejectpromise, &var_reason); 976 GotoIfException(result, &if_rejectpromise, &var_reason);
938 977
939 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. 978 Node* const on_resolve = deferred_on_resolve;
940 Node* const key = HeapConstant(isolate->factory()->resolve_string());
941 Node* const on_resolve =
942 CallStub(getproperty_callable, context, deferred, key);
943 979
944 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); 980 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
945 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); 981 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler);
946 982
947 Bind(&if_internalhandler); 983 Bind(&if_internalhandler);
948 InternalResolvePromise(context, deferred_promise, result, 984 InternalResolvePromise(context, deferred_promise, result,
949 &promisehook_after); 985 &promisehook_after);
950 986
951 Bind(&if_customhandler); 987 Bind(&if_customhandler);
952 { 988 {
953 Node* const maybe_exception = CallJS(call_callable, context, on_resolve, 989 Node* const maybe_exception = CallJS(call_callable, context, on_resolve,
954 UndefinedConstant(), result); 990 UndefinedConstant(), result);
955 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); 991 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
956 Goto(&promisehook_after); 992 Goto(&promisehook_after);
957 } 993 }
958 } 994 }
959 995
960 Bind(&if_rejectpromise); 996 Bind(&if_rejectpromise);
961 { 997 {
962 // TODO(gsathya): Remove this lookup by getting rid of the deferred object. 998 Node* const on_reject = deferred_on_reject;
963 Node* const key = HeapConstant(isolate->factory()->reject_string());
964 Node* const on_reject =
965 CallStub(getproperty_callable, context, deferred, key);
966
967 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); 999 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
968 CallStub(promise_handle_reject, context, deferred_promise, on_reject, 1000 CallStub(promise_handle_reject, context, deferred_promise, on_reject,
969 var_reason.value()); 1001 var_reason.value());
970 Goto(&promisehook_after); 1002 Goto(&promisehook_after);
971 } 1003 }
972 1004
973 Bind(&promisehook_after); 1005 Bind(&promisehook_after);
974 { 1006 {
975 GotoUnless(IsPromiseHookEnabled(), &debug_pop); 1007 GotoUnless(IsPromiseHookEnabled(), &debug_pop);
976 CallRuntime(Runtime::kPromiseHookAfter, context, promise); 1008 CallRuntime(Runtime::kPromiseHookAfter, context, promise);
977 Goto(&debug_pop); 1009 Goto(&debug_pop);
978 } 1010 }
979 1011
980 Bind(&debug_pop); 1012 Bind(&debug_pop);
981 { 1013 {
982 Label out(this); 1014 Label out(this);
983 1015
984 GotoUnless(is_debug_active, &out); 1016 GotoUnless(is_debug_active, &out);
985 CallRuntime(Runtime::kDebugPopPromise, context); 1017 CallRuntime(Runtime::kDebugPopPromise, context);
986 Goto(&out); 1018 Goto(&out);
987 1019
988 Bind(&out); 1020 Bind(&out);
989 Return(UndefinedConstant()); 1021 Return(UndefinedConstant());
990 } 1022 }
991 } 1023 }
992 1024
993 } // namespace internal 1025 } // namespace internal
994 } // namespace v8 1026 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698