Chromium Code Reviews| 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 |