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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 } | 162 } |
| 163 PromiseSet(promise, status, value); | 163 PromiseSet(promise, status, value); |
| 164 } | 164 } |
| 165 } | 165 } |
| 166 | 166 |
| 167 function PromiseHandle(value, handler, deferred) { | 167 function PromiseHandle(value, handler, deferred) { |
| 168 var debug_is_active = DEBUG_IS_ACTIVE; | 168 var debug_is_active = DEBUG_IS_ACTIVE; |
| 169 try { | 169 try { |
| 170 if (debug_is_active) %DebugPushPromise(deferred.promise); | 170 if (debug_is_active) %DebugPushPromise(deferred.promise); |
| 171 var result = handler(value); | 171 var result = handler(value); |
| 172 deferred.resolve(result); | 172 if (deferred.resolve) { deferred.resolve(result); } |
| 173 else { ResolvePromise(deferred.promise, result); } | |
| 173 } %catch (exception) { // Natives syntax to mark this catch block. | 174 } %catch (exception) { // Natives syntax to mark this catch block. |
| 174 try { deferred.reject(exception); } catch (e) { } | 175 try { |
| 176 if (deferred.reject) { deferred.reject(exception); } | |
| 177 else { RejectPromise(deferred.promise, exception, false); } | |
| 178 } catch (e) { } | |
| 175 } finally { | 179 } finally { |
| 176 if (debug_is_active) %DebugPopPromise(); | 180 if (debug_is_active) %DebugPopPromise(); |
| 177 } | 181 } |
| 178 } | 182 } |
| 179 | 183 |
| 180 function PromiseEnqueue(value, tasks, deferreds, status) { | 184 function PromiseEnqueue(value, tasks, deferreds, status) { |
| 181 var id, name, instrumenting = DEBUG_IS_ACTIVE; | 185 var id, name, instrumenting = DEBUG_IS_ACTIVE; |
| 182 %EnqueueMicrotask(function() { | 186 %EnqueueMicrotask(function() { |
| 183 if (instrumenting) { | 187 if (instrumenting) { |
| 184 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); | 188 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 | 366 |
| 363 // Export to bindings | 367 // Export to bindings |
| 364 function DoRejectPromise(promise, reason) { | 368 function DoRejectPromise(promise, reason) { |
| 365 return RejectPromise(promise, reason, true); | 369 return RejectPromise(promise, reason, true); |
| 366 } | 370 } |
| 367 | 371 |
| 368 // ES#sec-newpromisecapability | 372 // ES#sec-newpromisecapability |
| 369 // NewPromiseCapability ( C ) | 373 // NewPromiseCapability ( C ) |
| 370 function NewPromiseCapability(C, debugEvent) { | 374 function NewPromiseCapability(C, debugEvent) { |
| 371 if (C === GlobalPromise) { | 375 if (C === GlobalPromise) { |
| 372 // Optimized case, avoid extra closure. | |
| 373 var promise = PromiseCreate(); | |
| 374 var callbacks = CreateResolvingFunctions(promise, debugEvent); | |
| 375 return { | 376 return { |
| 376 promise: promise, | 377 promise: PromiseCreate(), |
| 377 resolve: callbacks.resolve, | 378 resolve: false, |
| 378 reject: callbacks.reject | 379 reject: false, |
| 379 }; | 380 }; |
| 380 } | 381 } |
| 381 | 382 |
| 382 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; | 383 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; |
| 383 result.promise = new C((resolve, reject) => { | 384 result.promise = new C((resolve, reject) => { |
| 384 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) | 385 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) |
| 385 throw %make_type_error(kPromiseExecutorAlreadyInvoked); | 386 throw %make_type_error(kPromiseExecutorAlreadyInvoked); |
| 386 result.resolve = resolve; | 387 result.resolve = resolve; |
| 387 result.reject = reject; | 388 result.reject = reject; |
| 388 }); | 389 }); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 // Combinators. | 468 // Combinators. |
| 468 | 469 |
| 469 // ES#sec-promise.resolve | 470 // ES#sec-promise.resolve |
| 470 // Promise.resolve ( x ) | 471 // Promise.resolve ( x ) |
| 471 function PromiseResolve(x) { | 472 function PromiseResolve(x) { |
| 472 if (!IS_RECEIVER(this)) { | 473 if (!IS_RECEIVER(this)) { |
| 473 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 474 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
| 474 } | 475 } |
| 475 if (IsPromise(x) && x.constructor === this) return x; | 476 if (IsPromise(x) && x.constructor === this) return x; |
| 476 | 477 |
| 477 // Avoid creating resolving functions. | 478 // debugEvent is not so meaningful here as it will be resolved |
| 479 var promiseCapability = NewPromiseCapability(this, true); | |
| 480 | |
| 478 if (this === GlobalPromise) { | 481 if (this === GlobalPromise) { |
| 479 var promise = PromiseCreate(); | 482 ResolvePromise(promiseCapability.promise, x); |
| 480 var resolveResult = ResolvePromise(promise, x); | 483 } else { |
| 481 return promise; | 484 %_Call(promiseCapability.resolve, UNDEFINED, x); |
| 482 } | 485 } |
| 483 | 486 |
| 484 // debugEvent is not so meaningful here as it will be resolved | |
| 485 var promiseCapability = NewPromiseCapability(this, true); | |
| 486 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x); | |
| 487 return promiseCapability.promise; | 487 return promiseCapability.promise; |
| 488 } | 488 } |
| 489 | 489 |
| 490 // ES#sec-promise.all | 490 // ES#sec-promise.all |
| 491 // Promise.all ( iterable ) | 491 // Promise.all ( iterable ) |
| 492 function PromiseAll(iterable) { | 492 function PromiseAll(iterable) { |
| 493 if (!IS_RECEIVER(this)) { | 493 if (!IS_RECEIVER(this)) { |
| 494 throw %make_type_error(kCalledOnNonObject, "Promise.all"); | 494 throw %make_type_error(kCalledOnNonObject, "Promise.all"); |
| 495 } | 495 } |
| 496 | 496 |
| 497 // false debugEvent so that forwarding the rejection through all does not | 497 // false debugEvent so that forwarding the rejection through all does not |
| 498 // trigger redundant ExceptionEvents | 498 // trigger redundant ExceptionEvents |
| 499 var deferred = NewPromiseCapability(this, false); | 499 var deferred = NewPromiseCapability(this, false); |
| 500 if (this === GlobalPromise) { | |
| 501 var callbacks = CreateResolvingFunctions(deferred.promise, false); | |
| 502 deferred.resolve = callbacks.resolve; | |
| 503 deferred.reject = callbacks.reject; | |
| 504 } | |
| 500 var resolutions = new InternalArray(); | 505 var resolutions = new InternalArray(); |
| 501 var count; | 506 var count; |
| 502 | 507 |
| 503 // For catch prediction, don't treat the .then calls as handling it; | 508 // For catch prediction, don't treat the .then calls as handling it; |
| 504 // instead, recurse outwards. | 509 // instead, recurse outwards. |
| 505 var instrumenting = DEBUG_IS_ACTIVE; | 510 var instrumenting = DEBUG_IS_ACTIVE; |
| 506 if (instrumenting) { | 511 if (instrumenting) { |
| 507 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 512 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
| 508 } | 513 } |
| 509 | 514 |
| 510 function CreateResolveElementFunction(index, values, promiseCapability) { | 515 function CreateResolveElementFunction(index, values, promiseCapability) { |
| 511 var alreadyCalled = false; | 516 var alreadyCalled = false; |
| 512 return (x) => { | 517 return function(x) { |
| 513 if (alreadyCalled === true) return; | 518 if (alreadyCalled === true) return; |
| 514 alreadyCalled = true; | 519 alreadyCalled = true; |
| 515 values[index] = x; | 520 values[index] = x; |
| 516 if (--count === 0) { | 521 if (--count === 0) { |
| 517 var valuesArray = []; | 522 var valuesArray = []; |
| 518 %MoveArrayContents(values, valuesArray); | 523 %MoveArrayContents(values, valuesArray); |
| 519 %_Call(promiseCapability.resolve, UNDEFINED, valuesArray); | 524 %_Call(promiseCapability.resolve, UNDEFINED, valuesArray); |
| 520 } | 525 } |
| 521 }; | 526 }; |
| 522 } | 527 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 // ES#sec-promise.race | 559 // ES#sec-promise.race |
| 555 // Promise.race ( iterable ) | 560 // Promise.race ( iterable ) |
| 556 function PromiseRace(iterable) { | 561 function PromiseRace(iterable) { |
| 557 if (!IS_RECEIVER(this)) { | 562 if (!IS_RECEIVER(this)) { |
| 558 throw %make_type_error(kCalledOnNonObject, PromiseRace); | 563 throw %make_type_error(kCalledOnNonObject, PromiseRace); |
| 559 } | 564 } |
| 560 | 565 |
| 561 // false debugEvent so that forwarding the rejection through race does not | 566 // false debugEvent so that forwarding the rejection through race does not |
| 562 // trigger redundant ExceptionEvents | 567 // trigger redundant ExceptionEvents |
| 563 var deferred = NewPromiseCapability(this, false); | 568 var deferred = NewPromiseCapability(this, false); |
| 569 if (this === GlobalPromise) { | |
| 570 var callbacks = CreateResolvingFunctions(deferred.promise, false); | |
|
adamk
2016/10/05 20:18:09
Ah, I didn't realize some callers need the callbac
| |
| 571 deferred.resolve = callbacks.resolve; | |
| 572 deferred.reject = callbacks.reject; | |
| 573 } | |
| 564 | 574 |
| 565 // For catch prediction, don't treat the .then calls as handling it; | 575 // For catch prediction, don't treat the .then calls as handling it; |
| 566 // instead, recurse outwards. | 576 // instead, recurse outwards. |
| 567 var instrumenting = DEBUG_IS_ACTIVE; | 577 var instrumenting = DEBUG_IS_ACTIVE; |
| 568 if (instrumenting) { | 578 if (instrumenting) { |
| 569 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 579 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
| 570 } | 580 } |
| 571 | 581 |
| 572 try { | 582 try { |
| 573 for (var value of iterable) { | 583 for (var value of iterable) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 to.PromiseNextMicrotaskID = PromiseNextMicrotaskID; | 706 to.PromiseNextMicrotaskID = PromiseNextMicrotaskID; |
| 697 | 707 |
| 698 to.GlobalPromise = GlobalPromise; | 708 to.GlobalPromise = GlobalPromise; |
| 699 to.NewPromiseCapability = NewPromiseCapability; | 709 to.NewPromiseCapability = NewPromiseCapability; |
| 700 to.PerformPromiseThen = PerformPromiseThen; | 710 to.PerformPromiseThen = PerformPromiseThen; |
| 701 to.ResolvePromise = ResolvePromise; | 711 to.ResolvePromise = ResolvePromise; |
| 702 to.RejectPromise = RejectPromise; | 712 to.RejectPromise = RejectPromise; |
| 703 }); | 713 }); |
| 704 | 714 |
| 705 }) | 715 }) |
| OLD | NEW |