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 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 if (resolution === promise) { | 243 if (resolution === promise) { |
244 return RejectPromise(promise, MakeTypeError(kPromiseCyclic, resolution)); | 244 return RejectPromise(promise, MakeTypeError(kPromiseCyclic, resolution)); |
245 } | 245 } |
246 if (IS_RECEIVER(resolution)) { | 246 if (IS_RECEIVER(resolution)) { |
247 // 25.4.1.3.2 steps 8-12 | 247 // 25.4.1.3.2 steps 8-12 |
248 try { | 248 try { |
249 var then = resolution.then; | 249 var then = resolution.then; |
250 } catch (e) { | 250 } catch (e) { |
251 return RejectPromise(promise, e); | 251 return RejectPromise(promise, e); |
252 } | 252 } |
| 253 |
| 254 // Resolution is a native promise and if it's already resolved or |
| 255 // rejected, shortcircuit the resolution procedure by directly |
| 256 // reusing the value from the promise. |
| 257 if (IsPromise(resolution) && then === PromiseThen) { |
| 258 var thenableState = GET_PRIVATE(resolution, promiseStateSymbol); |
| 259 if (thenableState === kFulfilled) { |
| 260 // This goes inside the if-else to save one symbol lookup in |
| 261 // the slow path. |
| 262 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
| 263 FulfillPromise(promise, kFulfilled, thenableValue, |
| 264 promiseFulfillReactionsSymbol); |
| 265 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); |
| 266 return; |
| 267 } else if (thenableState === kRejected) { |
| 268 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
| 269 if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) { |
| 270 // Promise has already been rejected, but had no handler. |
| 271 // Revoke previously triggered reject event. |
| 272 %PromiseRevokeReject(resolution); |
| 273 } |
| 274 RejectPromise(promise, thenableValue); |
| 275 SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); |
| 276 return; |
| 277 } |
| 278 } |
| 279 |
253 if (IS_CALLABLE(then)) { | 280 if (IS_CALLABLE(then)) { |
254 // PromiseResolveThenableJob | 281 // PromiseResolveThenableJob |
255 var id, name, instrumenting = DEBUG_IS_ACTIVE; | 282 var id, name, instrumenting = DEBUG_IS_ACTIVE; |
256 %EnqueueMicrotask(function() { | 283 %EnqueueMicrotask(function() { |
257 if (instrumenting) { | 284 if (instrumenting) { |
258 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); | 285 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); |
259 } | 286 } |
260 var callbacks = CreateResolvingFunctions(promise); | 287 var callbacks = CreateResolvingFunctions(promise); |
261 try { | 288 try { |
262 %_Call(then, resolution, callbacks.resolve, callbacks.reject); | 289 %_Call(then, resolution, callbacks.resolve, callbacks.reject); |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 to.PromiseChain = PromiseChain; | 611 to.PromiseChain = PromiseChain; |
585 to.PromiseDefer = PromiseDefer; | 612 to.PromiseDefer = PromiseDefer; |
586 to.PromiseAccept = PromiseAccept; | 613 to.PromiseAccept = PromiseAccept; |
587 | 614 |
588 to.PromiseCreateRejected = PromiseCreateRejected; | 615 to.PromiseCreateRejected = PromiseCreateRejected; |
589 to.PromiseCreateResolved = PromiseCreateResolved; | 616 to.PromiseCreateResolved = PromiseCreateResolved; |
590 to.PromiseThen = PromiseThen; | 617 to.PromiseThen = PromiseThen; |
591 }); | 618 }); |
592 | 619 |
593 }) | 620 }) |
OLD | NEW |