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

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

Issue 2590563003: [promises] Remove deferred object (Closed)
Patch Set: rebase Created 3 years, 11 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 Node* const promise_fun = 208 Node* const promise_fun =
195 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); 209 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
196 210
197 // 3. Let C be ? SpeciesConstructor(promise, %Promise%). 211 // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
198 Node* constructor = SpeciesConstructor(context, promise, promise_fun); 212 Node* constructor = SpeciesConstructor(context, promise, promise_fun);
199 213
200 // 4. Let resultCapability be ? NewPromiseCapability(C). 214 // 4. Let resultCapability be ? NewPromiseCapability(C).
201 Callable call_callable = CodeFactory::Call(isolate); 215 Callable call_callable = CodeFactory::Call(isolate);
202 Label fast_promise_capability(this), promise_capability(this), 216 Label fast_promise_capability(this), promise_capability(this),
203 perform_promise_then(this); 217 perform_promise_then(this);
204 Variable var_deferred(this, MachineRepresentation::kTagged); 218 Variable var_deferred_promise(this, MachineRepresentation::kTagged),
219 var_deferred_on_resolve(this, MachineRepresentation::kTagged),
220 var_deferred_on_reject(this, MachineRepresentation::kTagged);
205 221
206 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability, 222 Branch(WordEqual(promise_fun, constructor), &fast_promise_capability,
207 &promise_capability); 223 &promise_capability);
208 224
209 // TODO(gsathya): Remove deferred object and move
210 // NewPromiseCapabability functions to TF.
211 Bind(&fast_promise_capability); 225 Bind(&fast_promise_capability);
212 { 226 {
213 // TODO(gsathya): Move this to TF. 227 Node* const deferred_promise = AllocateAndInitPromise(context, promise);
214 Node* const promise_internal_capability = LoadContextElement( 228 PromiseInit(deferred_promise);
215 native_context, Context::INTERNAL_PROMISE_CAPABILITY_INDEX); 229 var_deferred_promise.Bind(deferred_promise);
216 Node* const capability = 230 var_deferred_on_resolve.Bind(UndefinedConstant());
217 CallJS(call_callable, context, promise_internal_capability, 231 var_deferred_on_reject.Bind(UndefinedConstant());
218 UndefinedConstant(), promise);
219 var_deferred.Bind(capability);
220 Goto(&perform_promise_then); 232 Goto(&perform_promise_then);
221 } 233 }
222 234
223 Bind(&promise_capability); 235 Bind(&promise_capability);
224 { 236 {
225 // TODO(gsathya): Move this to TF. 237 // TODO(gsathya): Move this to TF.
226 Node* const new_promise_capability = LoadContextElement( 238 Node* const new_promise_capability = LoadContextElement(
227 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX); 239 native_context, Context::NEW_PROMISE_CAPABILITY_INDEX);
228 Node* const capability = 240 Node* const deferred =
229 CallJS(call_callable, context, new_promise_capability, 241 CallJS(call_callable, context, new_promise_capability,
230 UndefinedConstant(), constructor); 242 UndefinedConstant(), constructor);
231 var_deferred.Bind(capability); 243 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
244 Node* key = HeapConstant(isolate->factory()->promise_string());
245 Node* const deferred_promise =
246 CallStub(getproperty_callable, context, deferred, key);
247 var_deferred_promise.Bind(deferred_promise);
248
249 key = HeapConstant(isolate->factory()->resolve_string());
250 Node* const deferred_on_resolve =
251 CallStub(getproperty_callable, context, deferred, key);
252 var_deferred_on_resolve.Bind(deferred_on_resolve);
253
254 key = HeapConstant(isolate->factory()->reject_string());
255 Node* const deferred_on_reject =
256 CallStub(getproperty_callable, context, deferred, key);
257 var_deferred_on_reject.Bind(deferred_on_reject);
258
232 Goto(&perform_promise_then); 259 Goto(&perform_promise_then);
233 } 260 }
234 261
235 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected, 262 // 5. Return PerformPromiseThen(promise, onFulfilled, onRejected,
236 // resultCapability). 263 // resultCapability).
237 Bind(&perform_promise_then); 264 Bind(&perform_promise_then);
238 Node* const result = InternalPerformPromiseThen( 265 Node* const result = InternalPerformPromiseThen(
239 context, promise, on_resolve, on_reject, var_deferred.value()); 266 context, promise, on_resolve, on_reject, var_deferred_promise.value(),
267 var_deferred_on_resolve.value(), var_deferred_on_reject.value());
240 return result; 268 return result;
241 } 269 }
242 270
243 Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(Node* context, 271 Node* PromiseBuiltinsAssembler::InternalPerformPromiseThen(
244 Node* promise, 272 Node* context, Node* promise, Node* on_resolve, Node* on_reject,
245 Node* on_resolve, 273 Node* deferred_promise, Node* deferred_on_resolve,
246 Node* on_reject, 274 Node* deferred_on_reject) {
247 Node* deferred) {
248 Node* const native_context = LoadNativeContext(context); 275 Node* const native_context = LoadNativeContext(context);
249 276
250 Variable var_on_resolve(this, MachineRepresentation::kTagged), 277 Variable var_on_resolve(this, MachineRepresentation::kTagged),
251 var_on_reject(this, MachineRepresentation::kTagged); 278 var_on_reject(this, MachineRepresentation::kTagged);
252 279
253 var_on_resolve.Bind(on_resolve); 280 var_on_resolve.Bind(on_resolve);
254 var_on_reject.Bind(on_reject); 281 var_on_reject.Bind(on_reject);
255 282
256 Label out(this), if_onresolvenotcallable(this), onrejectcheck(this), 283 Label out(this), if_onresolvenotcallable(this), onrejectcheck(this),
257 append_callbacks(this); 284 append_callbacks(this);
(...skipping 27 matching lines...) Expand all
285 } 312 }
286 } 313 }
287 314
288 Bind(&append_callbacks); 315 Bind(&append_callbacks);
289 { 316 {
290 Label fulfilled_check(this); 317 Label fulfilled_check(this);
291 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset); 318 Node* const status = LoadObjectField(promise, JSPromise::kStatusOffset);
292 GotoUnless(SmiEqual(status, SmiConstant(v8::Promise::kPending)), 319 GotoUnless(SmiEqual(status, SmiConstant(v8::Promise::kPending)),
293 &fulfilled_check); 320 &fulfilled_check);
294 321
295 Node* const existing_deferred = 322 Node* const existing_deferred_promise =
296 LoadObjectField(promise, JSPromise::kDeferredOffset); 323 LoadObjectField(promise, JSPromise::kDeferredPromiseOffset);
297 324
298 Label if_noexistingcallbacks(this), if_existingcallbacks(this); 325 Label if_noexistingcallbacks(this), if_existingcallbacks(this);
299 Branch(IsUndefined(existing_deferred), &if_noexistingcallbacks, 326 Branch(IsUndefined(existing_deferred_promise), &if_noexistingcallbacks,
300 &if_existingcallbacks); 327 &if_existingcallbacks);
301 328
302 Bind(&if_noexistingcallbacks); 329 Bind(&if_noexistingcallbacks);
303 { 330 {
304 // Store callbacks directly in the slots. 331 // Store callbacks directly in the slots.
305 StoreObjectField(promise, JSPromise::kDeferredOffset, deferred); 332 StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
333 deferred_promise);
334 StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
335 deferred_on_resolve);
336 StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
337 deferred_on_reject);
306 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset, 338 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
307 var_on_resolve.value()); 339 var_on_resolve.value());
308 StoreObjectField(promise, JSPromise::kRejectReactionsOffset, 340 StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
309 var_on_reject.value()); 341 var_on_reject.value());
310 Goto(&out); 342 Goto(&out);
311 } 343 }
312 344
313 Bind(&if_existingcallbacks); 345 Bind(&if_existingcallbacks);
314 { 346 {
315 Label if_singlecallback(this), if_multiplecallbacks(this); 347 Label if_singlecallback(this), if_multiplecallbacks(this);
316 BranchIfJSObject(existing_deferred, &if_singlecallback, 348 BranchIfJSObject(existing_deferred_promise, &if_singlecallback,
317 &if_multiplecallbacks); 349 &if_multiplecallbacks);
318 350
319 Bind(&if_singlecallback); 351 Bind(&if_singlecallback);
320 { 352 {
321 // Create new FixedArrays to store callbacks, and migrate 353 // Create new FixedArrays to store callbacks, and migrate
322 // existing callbacks. 354 // existing callbacks.
323 Node* const deferreds = 355 Node* const deferred_promise_arr =
324 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 356 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
325 StoreFixedArrayElement(deferreds, 0, existing_deferred); 357 StoreFixedArrayElement(deferred_promise_arr, 0,
326 StoreFixedArrayElement(deferreds, 1, deferred); 358 existing_deferred_promise);
359 StoreFixedArrayElement(deferred_promise_arr, 1, deferred_promise);
360
361 Node* const deferred_on_resolve_arr =
362 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
363 StoreFixedArrayElement(
364 deferred_on_resolve_arr, 0,
365 LoadObjectField(promise, JSPromise::kDeferredOnResolveOffset));
366 StoreFixedArrayElement(deferred_on_resolve_arr, 1, deferred_on_resolve);
367
368 Node* const deferred_on_reject_arr =
369 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
370 StoreFixedArrayElement(
371 deferred_on_reject_arr, 0,
372 LoadObjectField(promise, JSPromise::kDeferredOnRejectOffset));
373 StoreFixedArrayElement(deferred_on_reject_arr, 1, deferred_on_reject);
327 374
328 Node* const fulfill_reactions = 375 Node* const fulfill_reactions =
329 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 376 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
330 StoreFixedArrayElement( 377 StoreFixedArrayElement(
331 fulfill_reactions, 0, 378 fulfill_reactions, 0,
332 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset)); 379 LoadObjectField(promise, JSPromise::kFulfillReactionsOffset));
333 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value()); 380 StoreFixedArrayElement(fulfill_reactions, 1, var_on_resolve.value());
334 381
335 Node* const reject_reactions = 382 Node* const reject_reactions =
336 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); 383 AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2));
337 StoreFixedArrayElement( 384 StoreFixedArrayElement(
338 reject_reactions, 0, 385 reject_reactions, 0,
339 LoadObjectField(promise, JSPromise::kRejectReactionsOffset)); 386 LoadObjectField(promise, JSPromise::kRejectReactionsOffset));
340 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value()); 387 StoreFixedArrayElement(reject_reactions, 1, var_on_reject.value());
341 388
342 // Store new FixedArrays in promise. 389 // Store new FixedArrays in promise.
343 StoreObjectField(promise, JSPromise::kDeferredOffset, deferreds); 390 StoreObjectField(promise, JSPromise::kDeferredPromiseOffset,
391 deferred_promise_arr);
392 StoreObjectField(promise, JSPromise::kDeferredOnResolveOffset,
393 deferred_on_resolve_arr);
394 StoreObjectField(promise, JSPromise::kDeferredOnRejectOffset,
395 deferred_on_reject_arr);
344 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset, 396 StoreObjectField(promise, JSPromise::kFulfillReactionsOffset,
345 fulfill_reactions); 397 fulfill_reactions);
346 StoreObjectField(promise, JSPromise::kRejectReactionsOffset, 398 StoreObjectField(promise, JSPromise::kRejectReactionsOffset,
347 reject_reactions); 399 reject_reactions);
348 Goto(&out); 400 Goto(&out);
349 } 401 }
350 402
351 Bind(&if_multiplecallbacks); 403 Bind(&if_multiplecallbacks);
352 { 404 {
353 AppendPromiseCallback(JSPromise::kDeferredOffset, promise, deferred); 405 AppendPromiseCallback(JSPromise::kDeferredPromiseOffset, promise,
406 deferred_promise);
407 AppendPromiseCallback(JSPromise::kDeferredOnResolveOffset, promise,
408 deferred_on_resolve);
409 AppendPromiseCallback(JSPromise::kDeferredOnRejectOffset, promise,
410 deferred_on_reject);
354 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise, 411 AppendPromiseCallback(JSPromise::kFulfillReactionsOffset, promise,
355 var_on_resolve.value()); 412 var_on_resolve.value());
356 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise, 413 AppendPromiseCallback(JSPromise::kRejectReactionsOffset, promise,
357 var_on_reject.value()); 414 var_on_reject.value());
358 Goto(&out); 415 Goto(&out);
359 } 416 }
360 } 417 }
361 418
362 Bind(&fulfilled_check); 419 Bind(&fulfilled_check);
363 { 420 {
364 Label reject(this); 421 Label reject(this);
365 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset); 422 Node* const result = LoadObjectField(promise, JSPromise::kResultOffset);
366 GotoUnless(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)), 423 GotoUnless(WordEqual(status, SmiConstant(v8::Promise::kFulfilled)),
367 &reject); 424 &reject);
368 425
369 // TODO(gsathya): Move this to TF. 426 Node* info = AllocatePromiseReactionJobInfo(
370 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, result, 427 promise, result, var_on_resolve.value(), deferred_promise,
371 var_on_resolve.value(), deferred, 428 deferred_on_resolve, deferred_on_reject, context);
429 // TODO(gsathya): Move this to TF
430 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
372 SmiConstant(v8::Promise::kFulfilled)); 431 SmiConstant(v8::Promise::kFulfilled));
373 Goto(&out); 432 Goto(&out);
374 433
375 Bind(&reject); 434 Bind(&reject);
376 { 435 {
377 Node* const has_handler = PromiseHasHandler(promise); 436 Node* const has_handler = PromiseHasHandler(promise);
378 Label enqueue(this); 437 Label enqueue(this);
379 438
380 // TODO(gsathya): Fold these runtime calls and move to TF. 439 // TODO(gsathya): Fold these runtime calls and move to TF.
381 GotoIf(has_handler, &enqueue); 440 GotoIf(has_handler, &enqueue);
382 CallRuntime(Runtime::kPromiseRevokeReject, context, promise); 441 CallRuntime(Runtime::kPromiseRevokeReject, context, promise);
383 Goto(&enqueue); 442 Goto(&enqueue);
384 443
385 Bind(&enqueue); 444 Bind(&enqueue);
386 { 445 {
387 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, promise, 446 Node* info = AllocatePromiseReactionJobInfo(
388 result, var_on_reject.value(), deferred, 447 promise, result, var_on_reject.value(), deferred_promise,
448 deferred_on_resolve, deferred_on_reject, context);
449 // TODO(gsathya): Move this to TF
450 CallRuntime(Runtime::kEnqueuePromiseReactionJob, context, info,
389 SmiConstant(v8::Promise::kRejected)); 451 SmiConstant(v8::Promise::kRejected));
390
391 Goto(&out); 452 Goto(&out);
392 } 453 }
393 } 454 }
394 } 455 }
395 } 456 }
396 457
397 Bind(&out); 458 Bind(&out);
398 PromiseSetHasHandler(promise); 459 PromiseSetHasHandler(promise);
399 460 return deferred_promise;
400 // TODO(gsathya): This call will be removed once we don't have to
401 // deal with deferred objects.
402 Isolate* isolate = this->isolate();
403 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
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 } 461 }
410 462
411 // Promise fast path implementations rely on unmodified JSPromise instances. 463 // Promise fast path implementations rely on unmodified JSPromise instances.
412 // We use a fairly coarse granularity for this and simply check whether both 464 // 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 465 // the promise itself is unmodified (i.e. its map has not changed) and its
414 // prototype is unmodified. 466 // prototype is unmodified.
415 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp 467 // TODO(gsathya): Refactor this out to prevent code dupe with builtins-regexp
416 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise, 468 void PromiseBuiltinsAssembler::BranchIfFastPath(Node* context, Node* promise,
417 Label* if_isunmodified, 469 Label* if_isunmodified,
418 Label* if_ismodified) { 470 Label* if_ismodified) {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 Node* const key = 602 Node* const key =
551 HeapConstant(isolate->factory()->promise_handled_by_symbol()); 603 HeapConstant(isolate->factory()->promise_handled_by_symbol());
552 CallRuntime(Runtime::kSetProperty, context, result, key, promise, 604 CallRuntime(Runtime::kSetProperty, context, result, key, promise,
553 SmiConstant(STRICT)); 605 SmiConstant(STRICT));
554 Goto(&enqueue); 606 Goto(&enqueue);
555 607
556 // 12. Perform EnqueueJob("PromiseJobs", 608 // 12. Perform EnqueueJob("PromiseJobs",
557 // PromiseResolveThenableJob, « promise, resolution, thenAction 609 // PromiseResolveThenableJob, « promise, resolution, thenAction
558 // »). 610 // »).
559 Bind(&enqueue); 611 Bind(&enqueue);
612 // TODO(gsathya): Move this to TF
560 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise, 613 CallRuntime(Runtime::kEnqueuePromiseResolveThenableJob, context, promise,
561 result, var_then.value()); 614 result, var_then.value());
562 Goto(&out); 615 Goto(&out);
563 } 616 }
564 617
565 // 7.b Return FulfillPromise(promise, resolution). 618 // 7.b Return FulfillPromise(promise, resolution).
566 Bind(&fulfill); 619 Bind(&fulfill);
567 { 620 {
568 CallRuntime(Runtime::kPromiseFulfill, context, promise, 621 CallRuntime(Runtime::kPromiseFulfill, context, promise,
569 SmiConstant(v8::Promise::kFulfilled), result); 622 SmiConstant(v8::Promise::kFulfilled), result);
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 Node* const message_id = 813 Node* const message_id =
761 SmiConstant(MessageTemplate::kResolverNotAFunction); 814 SmiConstant(MessageTemplate::kResolverNotAFunction);
762 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor); 815 CallRuntime(Runtime::kThrowTypeError, context, message_id, executor);
763 Return(UndefinedConstant()); // Never reached. 816 Return(UndefinedConstant()); // Never reached.
764 } 817 }
765 } 818 }
766 819
767 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { 820 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
768 Node* const parent = Parameter(1); 821 Node* const parent = Parameter(1);
769 Node* const context = Parameter(4); 822 Node* const context = Parameter(4);
770 Node* const instance = AllocateJSPromise(context); 823 Return(AllocateAndInitPromise(context, parent));
771 PromiseInit(instance);
772
773 Label out(this);
774 GotoUnless(IsPromiseHookEnabled(), &out);
775 CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
776 Goto(&out);
777 Bind(&out);
778
779 Return(instance);
780 } 824 }
781 825
782 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { 826 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) {
783 Node* const status = Parameter(1); 827 Node* const status = Parameter(1);
784 Node* const result = Parameter(2); 828 Node* const result = Parameter(2);
785 Node* const context = Parameter(5); 829 Node* const context = Parameter(5);
786 830
787 Node* const instance = AllocateJSPromise(context); 831 Node* const instance = AllocateJSPromise(context);
788 PromiseSet(instance, status, result); 832 PromiseSet(instance, status, result);
789 833
(...skipping 17 matching lines...) Expand all
807 Return(result); 851 Return(result);
808 852
809 Bind(&if_notpromise); 853 Bind(&if_notpromise);
810 Return(FalseConstant()); 854 Return(FalseConstant());
811 } 855 }
812 856
813 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) { 857 TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) {
814 Node* const promise = Parameter(1); 858 Node* const promise = Parameter(1);
815 Node* const on_resolve = Parameter(2); 859 Node* const on_resolve = Parameter(2);
816 Node* const on_reject = Parameter(3); 860 Node* const on_reject = Parameter(3);
817 Node* const deferred = Parameter(4); 861 Node* const deferred_promise = Parameter(4);
818 Node* const context = Parameter(7); 862 Node* const context = Parameter(7);
819 863
820 Node* const result = InternalPerformPromiseThen(context, promise, on_resolve, 864 // No deferred_on_resolve/deferred_on_reject because this is just an
821 on_reject, deferred); 865 // internal promise created by async-await.
866 Node* const result = InternalPerformPromiseThen(
867 context, promise, on_resolve, on_reject, deferred_promise,
868 UndefinedConstant(), UndefinedConstant());
822 869
823 // TODO(gsathya): This is unused, but value is returned according to spec. 870 // TODO(gsathya): This is unused, but value is returned according to spec.
824 Return(result); 871 Return(result);
825 } 872 }
826 873
827 // ES#sec-promise.prototype.then 874 // ES#sec-promise.prototype.then
828 // Promise.prototype.catch ( onFulfilled, onRejected ) 875 // Promise.prototype.catch ( onFulfilled, onRejected )
829 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) { 876 TF_BUILTIN(PromiseThen, PromiseBuiltinsAssembler) {
830 // 1. Let promise be the this value. 877 // 1. Let promise be the this value.
831 Node* const promise = Parameter(0); 878 Node* const promise = Parameter(0);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 { 951 {
905 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception); 952 CallJS(call_callable, context, on_reject, UndefinedConstant(), exception);
906 Return(UndefinedConstant()); 953 Return(UndefinedConstant());
907 } 954 }
908 } 955 }
909 956
910 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) { 957 TF_BUILTIN(PromiseHandle, PromiseBuiltinsAssembler) {
911 Node* const promise = Parameter(1); 958 Node* const promise = Parameter(1);
912 Node* const value = Parameter(2); 959 Node* const value = Parameter(2);
913 Node* const handler = Parameter(3); 960 Node* const handler = Parameter(3);
914 Node* const deferred = Parameter(4); 961 Node* const deferred_promise = Parameter(4);
915 Node* const context = Parameter(7); 962 Node* const deferred_on_resolve = Parameter(5);
963 Node* const deferred_on_reject = Parameter(6);
964 Node* const context = Parameter(9);
916 Isolate* isolate = this->isolate(); 965 Isolate* isolate = this->isolate();
917 966
918 // Get promise from deferred
919 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
920 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
921 Node* const key = HeapConstant(isolate->factory()->promise_string());
922 Node* const deferred_promise =
923 CallStub(getproperty_callable, context, deferred, key);
924
925 Variable var_reason(this, MachineRepresentation::kTagged); 967 Variable var_reason(this, MachineRepresentation::kTagged);
926 968
927 Node* const is_debug_active = IsDebugActive(); 969 Node* const is_debug_active = IsDebugActive();
928 Label run_handler(this), if_rejectpromise(this), promisehook_before(this), 970 Label run_handler(this), if_rejectpromise(this), promisehook_before(this),
929 promisehook_after(this), debug_pop(this); 971 promisehook_after(this), debug_pop(this);
930 972
931 GotoUnless(is_debug_active, &promisehook_before); 973 GotoUnless(is_debug_active, &promisehook_before);
932 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise); 974 CallRuntime(Runtime::kDebugPushPromise, context, deferred_promise);
933 Goto(&promisehook_before); 975 Goto(&promisehook_before);
934 976
935 Bind(&promisehook_before); 977 Bind(&promisehook_before);
936 { 978 {
937 GotoUnless(IsPromiseHookEnabled(), &run_handler); 979 GotoUnless(IsPromiseHookEnabled(), &run_handler);
938 CallRuntime(Runtime::kPromiseHookBefore, context, promise); 980 CallRuntime(Runtime::kPromiseHookBefore, context, promise);
939 Goto(&run_handler); 981 Goto(&run_handler);
940 } 982 }
941 983
942 Bind(&run_handler); 984 Bind(&run_handler);
943 { 985 {
944 Callable call_callable = CodeFactory::Call(isolate); 986 Callable call_callable = CodeFactory::Call(isolate);
945
946 Node* const result = 987 Node* const result =
947 CallJS(call_callable, context, handler, UndefinedConstant(), value); 988 CallJS(call_callable, context, handler, UndefinedConstant(), value);
948 989
949 GotoIfException(result, &if_rejectpromise, &var_reason); 990 GotoIfException(result, &if_rejectpromise, &var_reason);
950 991
951 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
952 Node* const key = HeapConstant(isolate->factory()->resolve_string());
953 Node* const on_resolve =
954 CallStub(getproperty_callable, context, deferred, key);
955
956 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred); 992 Label if_internalhandler(this), if_customhandler(this, Label::kDeferred);
957 Branch(IsUndefined(on_resolve), &if_internalhandler, &if_customhandler); 993 Branch(IsUndefined(deferred_on_resolve), &if_internalhandler,
994 &if_customhandler);
958 995
959 Bind(&if_internalhandler); 996 Bind(&if_internalhandler);
960 InternalResolvePromise(context, deferred_promise, result); 997 InternalResolvePromise(context, deferred_promise, result);
961 Goto(&promisehook_after); 998 Goto(&promisehook_after);
962 999
963 Bind(&if_customhandler); 1000 Bind(&if_customhandler);
964 { 1001 {
965 Node* const maybe_exception = CallJS(call_callable, context, on_resolve, 1002 Node* const maybe_exception =
966 UndefinedConstant(), result); 1003 CallJS(call_callable, context, deferred_on_resolve,
1004 UndefinedConstant(), result);
967 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason); 1005 GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
968 Goto(&promisehook_after); 1006 Goto(&promisehook_after);
969 } 1007 }
970 } 1008 }
971 1009
972 Bind(&if_rejectpromise); 1010 Bind(&if_rejectpromise);
973 { 1011 {
974 // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
975 Node* const key = HeapConstant(isolate->factory()->reject_string());
976 Node* const on_reject =
977 CallStub(getproperty_callable, context, deferred, key);
978
979 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate); 1012 Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
980 CallStub(promise_handle_reject, context, deferred_promise, on_reject, 1013 CallStub(promise_handle_reject, context, deferred_promise,
981 var_reason.value()); 1014 deferred_on_reject, var_reason.value());
982 Goto(&promisehook_after); 1015 Goto(&promisehook_after);
983 } 1016 }
984 1017
985 Bind(&promisehook_after); 1018 Bind(&promisehook_after);
986 { 1019 {
987 GotoUnless(IsPromiseHookEnabled(), &debug_pop); 1020 GotoUnless(IsPromiseHookEnabled(), &debug_pop);
988 CallRuntime(Runtime::kPromiseHookAfter, context, promise); 1021 CallRuntime(Runtime::kPromiseHookAfter, context, promise);
989 Goto(&debug_pop); 1022 Goto(&debug_pop);
990 } 1023 }
991 1024
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 CallStub(getproperty_callable, context, promise, then_str); 1064 CallStub(getproperty_callable, context, promise, then_str);
1032 Callable call_callable = CodeFactory::Call(isolate); 1065 Callable call_callable = CodeFactory::Call(isolate);
1033 Node* const result = 1066 Node* const result =
1034 CallJS(call_callable, context, then, promise, on_resolve, on_reject); 1067 CallJS(call_callable, context, then, promise, on_resolve, on_reject);
1035 Return(result); 1068 Return(result);
1036 } 1069 }
1037 } 1070 }
1038 1071
1039 } // namespace internal 1072 } // namespace internal
1040 } // namespace v8 1073 } // 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