OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 (function(global, utils, extrasUtils) { | 5 (function(global, utils, extrasUtils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 } | 286 } |
287 | 287 |
288 // Export to bindings | 288 // Export to bindings |
289 function DoRejectPromise(promise, reason) { | 289 function DoRejectPromise(promise, reason) { |
290 %PromiseReject(promise, reason, true); | 290 %PromiseReject(promise, reason, true); |
291 PromiseSet(promise, kRejected, reason); | 291 PromiseSet(promise, kRejected, reason); |
292 } | 292 } |
293 | 293 |
294 // ES#sec-newpromisecapability | 294 // ES#sec-newpromisecapability |
295 // NewPromiseCapability ( C ) | 295 // NewPromiseCapability ( C ) |
296 function NewPromiseCapability(C, debugEvent) { | 296 function NewPromiseCapability(C, debugEvent, doNotCreateCallbacks) { |
Dan Ehrenberg
2016/11/18 08:05:38
Style suggestion: Rather than making this extra bo
gsathya
2016/11/18 08:34:28
Do you mean a function like --
NewPromiseCapabilit
Dan Ehrenberg
2016/11/18 08:55:37
I was imagining that all of that would be part of
| |
297 if (C === GlobalPromise) { | 297 if (C === GlobalPromise) { |
298 // Optimized case, avoid extra closure. | 298 // Optimized case, avoid extra closure. |
299 var promise = PromiseCreate(); | 299 var promise = PromiseCreate(); |
300 | |
301 // The resultCapability.promise is only ever fulfilled internally, | |
302 // so we don't need the closures to protect against accidentally | |
303 // calling them multiple times. | |
caitp
2016/11/18 05:47:15
I like that this is all documented so nicely. Sinc
gsathya
2016/11/18 06:02:28
This is used by PromiseThen as well which is why I
Dan Ehrenberg
2016/11/18 08:05:38
Could you mention this in the commit message? Does
gsathya
2016/11/18 08:34:27
This isn't a new change. This piece of code was sp
| |
304 if (doNotCreateCallbacks) { | |
305 return { | |
306 promise: promise, | |
307 resolve: UNDEFINED, | |
308 reject: UNDEFINED | |
309 }; | |
310 } | |
311 | |
300 // TODO(gsathya): Remove container for callbacks when this is | 312 // TODO(gsathya): Remove container for callbacks when this is |
301 // moved to CPP/TF. | 313 // moved to CPP/TF. |
302 var callbacks = %create_resolving_functions(promise, debugEvent); | 314 var callbacks = %create_resolving_functions(promise, debugEvent); |
303 return { | 315 return { |
304 promise: promise, | 316 promise: promise, |
305 resolve: callbacks[kResolveCallback], | 317 resolve: callbacks[kResolveCallback], |
306 reject: callbacks[kRejectCallback] | 318 reject: callbacks[kRejectCallback] |
307 }; | 319 }; |
308 } | 320 } |
309 | 321 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 // ES#sec-promise.prototype.then | 385 // ES#sec-promise.prototype.then |
374 // Promise.prototype.then ( onFulfilled, onRejected ) | 386 // Promise.prototype.then ( onFulfilled, onRejected ) |
375 // Multi-unwrapped chaining with thenable coercion. | 387 // Multi-unwrapped chaining with thenable coercion. |
376 function PromiseThen(onResolve, onReject) { | 388 function PromiseThen(onResolve, onReject) { |
377 var status = GET_PRIVATE(this, promiseStateSymbol); | 389 var status = GET_PRIVATE(this, promiseStateSymbol); |
378 if (IS_UNDEFINED(status)) { | 390 if (IS_UNDEFINED(status)) { |
379 throw %make_type_error(kNotAPromise, this); | 391 throw %make_type_error(kNotAPromise, this); |
380 } | 392 } |
381 | 393 |
382 var constructor = SpeciesConstructor(this, GlobalPromise); | 394 var constructor = SpeciesConstructor(this, GlobalPromise); |
383 var resultCapability; | |
384 | 395 |
385 // The resultCapability.promise is only ever fulfilled internally, | 396 // Pass false for debugEvent so .then chaining does not trigger |
386 // so we don't need the closures to protect against accidentally | 397 // redundant ExceptionEvents. |
387 // calling them multiple times. | 398 var resultCapability = NewPromiseCapability( |
388 if (constructor === GlobalPromise) { | 399 constructor, false, constructor === GlobalPromise); |
Dan Ehrenberg
2016/11/18 08:05:38
Not sure why you do this comparison. Seems like av
gsathya
2016/11/18 08:34:27
Yes, but this comparison is required to not create
Dan Ehrenberg
2016/11/18 08:55:37
I'd suggest factoring all this logic into NewPromi
| |
389 // TODO(gsathya): Combine this into NewPromiseCapability. | 400 |
390 resultCapability = { | |
391 promise: PromiseCreate(), | |
392 resolve: UNDEFINED, | |
393 reject: UNDEFINED | |
394 }; | |
395 } else { | |
396 // Pass false for debugEvent so .then chaining does not trigger | |
397 // redundant ExceptionEvents. | |
398 resultCapability = NewPromiseCapability(constructor, false); | |
399 } | |
400 return PerformPromiseThen(this, onResolve, onReject, resultCapability); | 401 return PerformPromiseThen(this, onResolve, onReject, resultCapability); |
401 } | 402 } |
402 | 403 |
403 // ES#sec-promise.prototype.catch | 404 // ES#sec-promise.prototype.catch |
404 // Promise.prototype.catch ( onRejected ) | 405 // Promise.prototype.catch ( onRejected ) |
405 function PromiseCatch(onReject) { | 406 function PromiseCatch(onReject) { |
406 return this.then(UNDEFINED, onReject); | 407 return this.then(UNDEFINED, onReject); |
407 } | 408 } |
408 | 409 |
409 // Combinators. | 410 // Combinators. |
410 | 411 |
411 // ES#sec-promise.resolve | 412 // ES#sec-promise.resolve |
412 // Promise.resolve ( x ) | 413 // Promise.resolve ( x ) |
413 function PromiseResolve(x) { | 414 function PromiseResolve(x) { |
414 if (!IS_RECEIVER(this)) { | 415 if (!IS_RECEIVER(this)) { |
415 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 416 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
416 } | 417 } |
417 if (IsPromise(x) && x.constructor === this) return x; | 418 if (IsPromise(x) && x.constructor === this) return x; |
418 | 419 |
419 // Avoid creating resolving functions. | 420 // Avoid creating resolving functions. |
420 if (this === GlobalPromise) { | 421 if (this === GlobalPromise) { |
421 var promise = PromiseCreate(); | 422 var promise = PromiseCreate(); |
422 ResolvePromise(promise, x); | 423 ResolvePromise(promise, x); |
423 return promise; | 424 return promise; |
424 } | 425 } |
425 | 426 |
426 // debugEvent is not so meaningful here as it will be resolved | 427 // debugEvent is not so meaningful here as it will be resolved. |
427 var promiseCapability = NewPromiseCapability(this, true); | 428 // We have already addressed the case where we don't need callbacks created, |
429 // so we pass false to create the callbacks. | |
430 var promiseCapability = NewPromiseCapability(this, true, false); | |
428 %_Call(promiseCapability.resolve, UNDEFINED, x); | 431 %_Call(promiseCapability.resolve, UNDEFINED, x); |
429 return promiseCapability.promise; | 432 return promiseCapability.promise; |
430 } | 433 } |
431 | 434 |
432 // ES#sec-promise.all | 435 // ES#sec-promise.all |
433 // Promise.all ( iterable ) | 436 // Promise.all ( iterable ) |
434 function PromiseAll(iterable) { | 437 function PromiseAll(iterable) { |
435 if (!IS_RECEIVER(this)) { | 438 if (!IS_RECEIVER(this)) { |
436 throw %make_type_error(kCalledOnNonObject, "Promise.all"); | 439 throw %make_type_error(kCalledOnNonObject, "Promise.all"); |
437 } | 440 } |
438 | 441 |
439 // false debugEvent so that forwarding the rejection through all does not | 442 // false debugEvent so that forwarding the rejection through all does not |
440 // trigger redundant ExceptionEvents | 443 // trigger redundant ExceptionEvents |
441 var deferred = NewPromiseCapability(this, false); | 444 // We need to create the resolving callbacks for the promise. |
445 var deferred = NewPromiseCapability(this, false, false); | |
442 var resolutions = new InternalArray(); | 446 var resolutions = new InternalArray(); |
443 var count; | 447 var count; |
444 | 448 |
445 // For catch prediction, don't treat the .then calls as handling it; | 449 // For catch prediction, don't treat the .then calls as handling it; |
446 // instead, recurse outwards. | 450 // instead, recurse outwards. |
447 var instrumenting = DEBUG_IS_ACTIVE; | 451 var instrumenting = DEBUG_IS_ACTIVE; |
448 if (instrumenting) { | 452 if (instrumenting) { |
449 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 453 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
450 } | 454 } |
451 | 455 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
495 | 499 |
496 // ES#sec-promise.race | 500 // ES#sec-promise.race |
497 // Promise.race ( iterable ) | 501 // Promise.race ( iterable ) |
498 function PromiseRace(iterable) { | 502 function PromiseRace(iterable) { |
499 if (!IS_RECEIVER(this)) { | 503 if (!IS_RECEIVER(this)) { |
500 throw %make_type_error(kCalledOnNonObject, PromiseRace); | 504 throw %make_type_error(kCalledOnNonObject, PromiseRace); |
501 } | 505 } |
502 | 506 |
503 // false debugEvent so that forwarding the rejection through race does not | 507 // false debugEvent so that forwarding the rejection through race does not |
504 // trigger redundant ExceptionEvents | 508 // trigger redundant ExceptionEvents |
505 var deferred = NewPromiseCapability(this, false); | 509 // We need to create the resolving callbacks for the promise. |
510 var deferred = NewPromiseCapability(this, false, false); | |
506 | 511 |
507 // For catch prediction, don't treat the .then calls as handling it; | 512 // For catch prediction, don't treat the .then calls as handling it; |
508 // instead, recurse outwards. | 513 // instead, recurse outwards. |
509 var instrumenting = DEBUG_IS_ACTIVE; | 514 var instrumenting = DEBUG_IS_ACTIVE; |
510 if (instrumenting) { | 515 if (instrumenting) { |
511 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 516 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
512 } | 517 } |
513 | 518 |
514 try { | 519 try { |
515 for (var value of iterable) { | 520 for (var value of iterable) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 to.PromiseThen = PromiseThen; | 646 to.PromiseThen = PromiseThen; |
642 | 647 |
643 to.GlobalPromise = GlobalPromise; | 648 to.GlobalPromise = GlobalPromise; |
644 to.NewPromiseCapability = NewPromiseCapability; | 649 to.NewPromiseCapability = NewPromiseCapability; |
645 to.PerformPromiseThen = PerformPromiseThen; | 650 to.PerformPromiseThen = PerformPromiseThen; |
646 to.ResolvePromise = ResolvePromise; | 651 to.ResolvePromise = ResolvePromise; |
647 to.RejectPromise = RejectPromise; | 652 to.RejectPromise = RejectPromise; |
648 }); | 653 }); |
649 | 654 |
650 }) | 655 }) |
OLD | NEW |