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

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

Issue 2590563003: [promises] Remove deferred object (Closed)
Patch Set: fix test 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::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(v8::Promise::kPending)), 246 GotoUnless(SmiEqual(status, SmiConstant(v8::Promise::kPending)),
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_promise_arr =
265 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 283 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
266 StoreFixedArrayElement(deferreds, 0, existing_deferred); 284 StoreFixedArrayElement(deferred_promise_arr, 0,
267 StoreFixedArrayElement(deferreds, 1, deferred); 285 existing_deferred_promise);
286 StoreFixedArrayElement(deferred_promise_arr, 1, deferred_promise);
jgruber 2016/12/21 08:08:28 Maybe refactor this into a NewFixedArrayWithElemen
gsathya 2016/12/21 19:26:28 This is slightly tricky and doesn't conform togeth
287
288 Node* const deferred_on_resolve_arr =
289 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
290 StoreFixedArrayElement(
291 deferred_on_resolve_arr, 0,
292 LoadObjectField(promise, JSPromise::kDeferredOnResolveOffset));
293 StoreFixedArrayElement(deferred_on_resolve_arr, 1, deferred_on_resolve);
294
295 Node* const deferred_on_reject_arr =
296 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
297 StoreFixedArrayElement(
298 deferred_on_reject_arr, 0,
299 LoadObjectField(promise, JSPromise::kDeferredOnRejectOffset));
300 StoreFixedArrayElement(deferred_on_reject_arr, 1, deferred_on_reject);
268 301
269 Node* const fulfill_reactions = 302 Node* const fulfill_reactions =
270 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 303 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
271 StoreFixedArrayElement( 304 StoreFixedArrayElement(
272 fulfill_reactions, 0, 305 fulfill_reactions, 0,
273 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset)); 306 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset));
274 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value()); 307 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value());
275 308
276 Node* const reject_reactions = 309 Node* const reject_reactions =
277 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 310 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
278 StoreFixedArrayElement( 311 StoreFixedArrayElement(
279 reject_reactions, 0, 312 reject_reactions, 0,
280 LoadObjectField(promise, JSPromise::kRejectReactionsOffset)); 313 LoadObjectField(promise, JSPromise::kRejectReactionsOffset));
281 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value()); 314 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value());
282 315
283 // Store new FixedArrays in promise. 316 // Store new FixedArrays in promise.
284 StoreObjectField(promise, JSPromise::kDeferredOffset, deferreds); 317 StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
318 deferred_promise_arr);
319 StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
320 deferred_on_resolve_arr);
321 StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
322 deferred_on_reject_arr);
285 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset, 323 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
286 fulfill_reactions); 324 fulfill_reactions);
287 StoreObjectField(promise, JSPromise::kRejectReactionsOffset, 325 StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
288 reject_reactions); 326 reject_reactions);
289 Goto(&out); 327 Goto(&out);
290 } 328 }
291 329
292 Bind(&if_multiplecallbacks); 330 Bind(&if_multiplecallbacks);
293 { 331 {
294 AppendPromiseCallback(JSPromise::kDeferredOffset, promise, deferred); 332 AppendPromiseCallback(JSPromise::kDeferredPromiseOffset, promise,
333 deferred_promise);
334 AppendPromiseCallback(JSPromise::kDeferredOnResolveOffset, promise,
335 deferred_on_resolve);
336 AppendPromiseCallback(JSPromise::kDeferredOnRejectOffset, promise,
337 deferred_on_reject);
295 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise, 338 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise,
296 var_on_resolve.value()); 339 var_on_resolve.value());
297 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise, 340 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise,
298 var_on_reject.value()); 341 var_on_reject.value());
299 Goto(&out); 342 Goto(&out);
300 } 343 }
301 } 344 }
302 345
303 Bind(&fulfilled_check); 346 Bind(&fulfilled_check);
304 { 347 {
305 Label reject(this); 348 Label reject(this);
306 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset); 349 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset);
307 GotoUnless(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)), 350 GotoUnless(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)),
308 &reject); 351 &reject);
309 352
310 // TODO(gsathya): Move this to TF. 353 Node* info = AllocatePromiseReactionJobInfo(
311 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, result, 354 promise, result, var_on_resolve.value(), deferred_promise,
312 var_on_resolve.value(), deferred, 355 deferred_on_resolve, deferred_on_reject, context);
356 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
jgruber 2016/12/21 08:08:28 It'd be awesome to move this to CSA as well at som
gsathya 2016/12/21 19:26:28 Done.
313 SmiConstant(v8::Promise::kFulfilled)); 357 SmiConstant(v8::Promise::kFulfilled));
314 Goto(&out); 358 Goto(&out);
315 359
316 Bind(&reject); 360 Bind(&reject);
317 { 361 {
318 Node* const has_handler = PromiseHasHandler(promise); 362 Node* const has_handler = PromiseHasHandler(promise);
319 Label enqueue(this); 363 Label enqueue(this);
320 364
321 // TODO(gsathya): Fold these runtime calls and move to TF. 365 // TODO(gsathya): Fold these runtime calls and move to TF.
322 GotoIf(has_handler, &enqueue); 366 GotoIf(has_handler, &enqueue);
323 CallRuntime(Runtime::kPromiseRevokeReject, context, promise); 367 CallRuntime(Runtime::kPromiseRevokeReject, context, promise);
324 Goto(&enqueue); 368 Goto(&enqueue);
325 369
326 Bind(&enqueue); 370 Bind(&enqueue);
327 { 371 {
328 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, 372 Node* info = AllocatePromiseReactionJobInfo(
329 result, var_on_reject.value(), deferred, 373 promise, result, var_on_reject.value(), deferred_promise,
374 deferred_on_resolve, deferred_on_reject, context);
375 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
330 SmiConstant(v8::Promise::kRejected)); 376 SmiConstant(v8::Promise::kRejected));
331
332 Goto(&out); 377 Goto(&out);
333 } 378 }
334 } 379 }
335 } 380 }
336 } 381 }
337 382
338 Bind(&out); 383 Bind(&out);
339 PromiseSetHasHandler(promise); 384 PromiseSetHasHandler(promise);
jgruber 2016/12/21 08:08:28 By the way, we could make PromiseSetHasHandler che
jgruber 2016/12/21 08:45:07 CL for that here: https://codereview.chromium.org/
gsathya 2016/12/21 19:26:28 Thanks!
340 385 return deferred_promise;
341 // TODO(gsathya): This call will be removed once we don't have to
342 // deal with deferred objects.
343 Isolate* isolate = this->isolate();
344 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
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 } 386 }
351 387
352 // Promise fast path implementations rely on unmodified JSPromise instances. 388 // Promise fast path implementations rely on unmodified JSPromise instances.
353 // We use a fairly coarse granularity for this and simply check whether both 389 // 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 390 // the promise itself is unmodified (i.e. its map has not changed) and its
355 // prototype is unmodified. 391 // prototype is unmodified.
356 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp 392 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp
357 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise, 393 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise,
358 Label* if_isunmodified, 394 Label* if_isunmodified,
359 Label* if_ismodified) { 395 Label* if_ismodified) {
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 Node* const message_id = 735 Node* const message_id =
700 SmiConstant(MessageTemplate::kResolverNotAFunction); 736 SmiConstant(MessageTemplate::kResolverNotAFunction);
701 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); 737 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
702 Return(UndefinedConstant()); // Never reached. 738 Return(UndefinedConstant()); // Never reached.
703 } 739 }
704 } 740 }
705 741
706 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { 742 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
707 Node* const parent = Parameter(1); 743 Node* const parent = Parameter(1);
708 Node* const context = Parameter(4); 744 Node* const context = Parameter(4);
709 Node* const instance = AllocateJSPromise(context); 745 Return(AllocateAndInitPromise(context, parent));
710 PromiseInit(instance);
711
712 Label out(this);
713 GotoUnless(IsPromiseHookEnabled(), &out);
714 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
715 Goto(&out);
716 Bind(&out);
717
718 Return(instance);
719 } 746 }
720 747
721 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { 748 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) {
722 Node* const status = Parameter(1); 749 Node* const status = Parameter(1);
723 Node* const result = Parameter(2); 750 Node* const result = Parameter(2);
724 Node* const context = Parameter(5); 751 Node* const context = Parameter(5);
725 752
726 Node* const instance = AllocateJSPromise(context); 753 Node* const instance = AllocateJSPromise(context);
727 PromiseSet(instance, status, result); 754 PromiseSet(instance, status, result);
728 755
(...skipping 17 matching lines...) Expand all
746 Return(result); 773 Return(result);
747 774
748 Bind(&if_notpromise); 775 Bind(&if_notpromise);
749 Return(FalseConstant()); 776 Return(FalseConstant());
750 } 777 }
751 778
752 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) { 779 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) {
753 Node* const promise = Parameter(1); 780 Node* const promise = Parameter(1);
754 Node* const on_resolve = Parameter(2); 781 Node* const on_resolve = Parameter(2);
755 Node* const on_reject = Parameter(3); 782 Node* const on_reject = Parameter(3);
756 Node* const deferred = Parameter(4); 783 Node* const deferred_promise = Parameter(4);
757 Node* const context = Parameter(7); 784 Node* const context = Parameter(7);
758 785
759 Node* const result = InternalPerformPromiseThen(context, promise, on_resolve, 786 // No deferred_on_resolve/deferred_on_reject because this is just an
760 on_reject, deferred); 787 // internal promise created by async-await.
788 Node* const result = InternalPerformPromiseThen(
789 context, promise, on_resolve, on_reject, deferred_promise,
790 UndefinedConstant(), UndefinedConstant());
761 791
762 // TODO(gsathya): This is unused, but value is returned according to spec. 792 // TODO(gsathya): This is unused, but value is returned according to spec.
763 Return(result); 793 Return(result);
764 } 794 }
765 795
766 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) { 796 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) {
767 // 1. Let promise be the this value. 797 // 1. Let promise be the this value.
768 Node* const promise = Parameter(0); 798 Node* const promise = Parameter(0);
769 Node* const on_resolve = Parameter(1); 799 Node* const on_resolve = Parameter(1);
770 Node* const on_reject = Parameter(2); 800 Node* const on_reject = Parameter(2);
771 Node* const context = Parameter(5); 801 Node* const context = Parameter(5);
772 Isolate* isolate = this->isolate(); 802 Isolate* isolate = this->isolate();
773 803
774 // 2. If IsPromise(promise) is false, throw a TypeError exception. 804 // 2. If IsPromise(promise) is false, throw a TypeError exception.
775 ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE, 805 ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE,
776 "Promise.prototype.then"); 806 "Promise.prototype.then");
777 807
778 Node* const native_context = LoadNativeContext(context); 808 Node* const native_context = LoadNativeContext(context);
779 Node* const promise_fun = 809 Node* const promise_fun =
780 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); 810 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
781 811
782 // 3. Let C be ? SpeciesConstructor(promise, %Promise%). 812 // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
783 Node* constructor = SpeciesConstructor(context, promise, promise_fun); 813 Node* constructor = SpeciesConstructor(context, promise, promise_fun);
784 814
785 // 4. Let resultCapability be ? NewPromiseCapability(C). 815 // 4. Let resultCapability be ? NewPromiseCapability(C).
786 Callable call_callable = CodeFactory::Call(isolate); 816 Callable call_callable = CodeFactory::Call(isolate);
787 Label fast_promise_capability(this), promise_capability(this), 817 Label fast_promise_capability(this), promise_capability(this),
788 perform_promise_then(this); 818 perform_promise_then(this);
789 Variable var_deferred(this, MachineRepresentation::kTagged); 819 Variable var_deferred_promise(this, MachineRepresentation::kTagged),
820 var_deferred_on_resolve(this, MachineRepresentation::kTagged),
821 var_deferred_on_reject(this, MachineRepresentation::kTagged);
790 822
791 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, 823 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability,
792 &promise_capability); 824 &promise_capability);
793 825
794 // TODO(gsathya): Remove deferred object and move
795 // NewPromiseCapabability functions to TF.
796 Bind(&fast_promise_capability); 826 Bind(&fast_promise_capability);
797 { 827 {
798 // TODO(gsathya): Move this to TF. 828 Node* const deferred_promise = AllocateAndInitPromise(context, promise);
799 Node* const promise_internal_capability = LoadContextElement( 829 PromiseInit(deferred_promise);
800 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); 830 var_deferred_promise.Bind(deferred_promise);
801 Node* const capability = 831 var_deferred_on_resolve.Bind(UndefinedConstant());
802 CallJS(call_callable, context, promise_internal_capability, 832 var_deferred_on_reject.Bind(UndefinedConstant());
803 UndefinedConstant(), promise);
804 var_deferred.Bind(capability);
805 Goto(&perform_promise_then); 833 Goto(&perform_promise_then);
806 } 834 }
807 835
808 Bind(&promise_capability); 836 Bind(&promise_capability);
809 { 837 {
810 // TODO(gsathya): Move this to TF. 838 // TODO(gsathya): Move this to TF.
811 Node* const new_promise_capability = LoadContextElement( 839 Node* const new_promise_capability = LoadContextElement(
812 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); 840 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX);
813 Node* const capability = 841 Node* const deferred =
814 CallJS(call_callable, context, new_promise_capability, 842 CallJS(call_callable, context, new_promise_capability,
815 UndefinedConstant(), constructor); 843 UndefinedConstant(), constructor);
816 var_deferred.Bind(capability); 844 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
845 Node* key = HeapConstant(isolate->factory()->promise_string());
846 Node* const deferred_promise =
847 CallStub(getproperty_callable, context, deferred, key);
848 var_deferred_promise.Bind(deferred_promise);
849
850 key = HeapConstant(isolate->factory()->resolve_string());
851 Node* const deferred_on_resolve =
852 CallStub(getproperty_callable, context, deferred, key);
853 var_deferred_on_resolve.Bind(deferred_on_resolve);
854
855 key = HeapConstant(isolate->factory()->reject_string());
856 Node* const deferred_on_reject =
857 CallStub(getproperty_callable, context, deferred, key);
858 var_deferred_on_reject.Bind(deferred_on_reject);
859
817 Goto(&perform_promise_then); 860 Goto(&perform_promise_then);
818 } 861 }
819 862
820 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, 863 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
821 // resultCapability). 864 // resultCapability).
822 Bind(&perform_promise_then); 865 Bind(&perform_promise_then);
823 Node* const result = InternalPerformPromiseThen( 866 Node* const result = InternalPerformPromiseThen(
824 context, promise, on_resolve, on_reject, var_deferred.value()); 867 context, promise, on_resolve, on_reject, var_deferred_promise.value(),
868 var_deferred_on_resolve.value(), var_deferred_on_reject.value());
825 Return(result); 869 Return(result);
826 } 870 }
827 871
828 // ES#sec-promise-resolve-functions 872 // ES#sec-promise-resolve-functions
829 // Promise Resolve Functions 873 // Promise Resolve Functions
830 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) { 874 TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) {
831 Node* const value = Parameter(1); 875 Node* const value = Parameter(1);
832 Node* const context = Parameter(4); 876 Node* const context = Parameter(4);
833 877
834 Label out(this); 878 Label out(this);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 { 937 {
894 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception); 938 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception);
895 Return(UndefinedConstant()); 939 Return(UndefinedConstant());
896 } 940 }
897 } 941 }
898 942
899 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { 943 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) {
900 Node* const promise = Parameter(1); 944 Node* const promise = Parameter(1);
901 Node* const value = Parameter(2); 945 Node* const value = Parameter(2);
902 Node* const handler = Parameter(3); 946 Node* const handler = Parameter(3);
903 Node* const deferred = Parameter(4); 947 Node* const deferred_promise = Parameter(4);
904 Node* const context = Parameter(7); 948 Node* const deferred_on_resolve = Parameter(5);
949 Node* const deferred_on_reject = Parameter(6);
950 Node* const context = Parameter(9);
905 Isolate* isolate = this->isolate(); 951 Isolate* isolate = this->isolate();
906 952
907 // Get promise from deferred 953 // Get promise from deferred
jgruber 2016/12/21 08:08:28 Leftover comment?
gsathya 2016/12/21 19:26:28 Done.
908 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
909 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
910 Node* const key = HeapConstant(isolate->factory()->promise_string());
911 Node* const deferred_promise =
912 CallStub(getproperty_callable, context, deferred, key);
913
914 Variable var_reason(this, MachineRepresentation::kTagged); 954 Variable var_reason(this, MachineRepresentation::kTagged);
915 955
916 Node* const is_debug_active = IsDebugActive(); 956 Node* const is_debug_active = IsDebugActive();
917 Label run_handler(this), if_rejectpromise(this), promisehook_before(this), 957 Label run_handler(this), if_rejectpromise(this), promisehook_before(this),
918 promisehook_after(this), debug_pop(this); 958 promisehook_after(this), debug_pop(this);
919 959
920 GotoUnless(is_debug_active, &promisehook_before); 960 GotoUnless(is_debug_active, &promisehook_before);
921 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); 961 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise);
922 Goto(&promisehook_before); 962 Goto(&promisehook_before);
923 963
924 Bind(&promisehook_before); 964 Bind(&promisehook_before);
925 { 965 {
926 GotoUnless(IsPromiseHookEnabled(), &run_handler); 966 GotoUnless(IsPromiseHookEnabled(), &run_handler);
927 CallRuntime(Runtime::kPromiseHookBefore, context, promise); 967 CallRuntime(Runtime::kPromiseHookBefore, context, promise);
928 Goto(&run_handler); 968 Goto(&run_handler);
929 } 969 }
930 970
931 Bind(&run_handler); 971 Bind(&run_handler);
932 { 972 {
933 Callable call_callable = CodeFactory::Call(isolate); 973 Callable call_callable = CodeFactory::Call(isolate);
934
935 Node* const result = 974 Node* const result =
936 CallJS(call_callable, context, handler, UndefinedConstant(), value); 975 CallJS(call_callable, context, handler, UndefinedConstant(), value);
937 976
938 GotoIfException(result, &if_rejectpromise, &var_reason); 977 GotoIfException(result, &if_rejectpromise, &var_reason);
939 978
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 =
943 CallStub(getproperty_callable, context, deferred, key);
944
945 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); 979 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
946 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); 980 Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
981 &if_customhandler);
947 982
948 Bind(&if_internalhandler); 983 Bind(&if_internalhandler);
949 InternalResolvePromise(context, deferred_promise, result, 984 InternalResolvePromise(context, deferred_promise, result,
950 &promisehook_after); 985 &promisehook_after);
951 986
952 Bind(&if_customhandler); 987 Bind(&if_customhandler);
953 { 988 {
954 Node* const maybe_exception = CallJS(call_callable, context, on_resolve, 989 Node* const maybe_exception =
955 UndefinedConstant(), result); 990 CallJS(call_callable, context, deferred_on_resolve,
991 UndefinedConstant(), result);
956 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); 992 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
957 Goto(&promisehook_after); 993 Goto(&promisehook_after);
958 } 994 }
959 } 995 }
960 996
961 Bind(&if_rejectpromise); 997 Bind(&if_rejectpromise);
962 { 998 {
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 =
966 CallStub(getproperty_callable, context, deferred, key);
967
968 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); 999 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
969 CallStub(promise_handle_reject, context, deferred_promise, on_reject, 1000 CallStub(promise_handle_reject, context, deferred_promise,
970 var_reason.value()); 1001 deferred_on_reject, var_reason.value());
971 Goto(&promisehook_after); 1002 Goto(&promisehook_after);
972 } 1003 }
973 1004
974 Bind(&promisehook_after); 1005 Bind(&promisehook_after);
975 { 1006 {
976 GotoUnless(IsPromiseHookEnabled(), &debug_pop); 1007 GotoUnless(IsPromiseHookEnabled(), &debug_pop);
977 CallRuntime(Runtime::kPromiseHookAfter, context, promise); 1008 CallRuntime(Runtime::kPromiseHookAfter, context, promise);
978 Goto(&debug_pop); 1009 Goto(&debug_pop);
979 } 1010 }
980 1011
981 Bind(&debug_pop); 1012 Bind(&debug_pop);
982 { 1013 {
983 Label out(this); 1014 Label out(this);
984 1015
985 GotoUnless(is_debug_active, &out); 1016 GotoUnless(is_debug_active, &out);
986 CallRuntime(Runtime::kDebugPopPromise, context); 1017 CallRuntime(Runtime::kDebugPopPromise, context);
987 Goto(&out); 1018 Goto(&out);
988 1019
989 Bind(&out); 1020 Bind(&out);
990 Return(UndefinedConstant()); 1021 Return(UndefinedConstant());
991 } 1022 }
992 } 1023 }
993 1024
994 } // namespace internal 1025 } // namespace internal
995 } // namespace v8 1026 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698