| 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 var promise = new GlobalPromise(promiseRawSymbol); | 135 var promise = new GlobalPromise(promiseRawSymbol); |
| 136 // If debug is active, notify about the newly created promise first. | 136 // If debug is active, notify about the newly created promise first. |
| 137 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED); | 137 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED); |
| 138 return PromiseSet(promise, status, value); | 138 return PromiseSet(promise, status, value); |
| 139 } | 139 } |
| 140 | 140 |
| 141 function PromiseInit(promise) { | 141 function PromiseInit(promise) { |
| 142 return PromiseSet(promise, kPending, UNDEFINED); | 142 return PromiseSet(promise, kPending, UNDEFINED); |
| 143 } | 143 } |
| 144 | 144 |
| 145 function FulfillPromise(promise, status, value, promiseQueue) { | |
| 146 %PromiseFulfill(promise, status, value, promiseQueue); | |
| 147 PromiseSet(promise, status, value); | |
| 148 } | |
| 149 | |
| 150 function PromiseHandle(value, handler, deferred) { | 145 function PromiseHandle(value, handler, deferred) { |
| 151 var debug_is_active = DEBUG_IS_ACTIVE; | 146 var debug_is_active = DEBUG_IS_ACTIVE; |
| 152 try { | 147 try { |
| 153 if (debug_is_active) %DebugPushPromise(deferred.promise); | 148 if (debug_is_active) %DebugPushPromise(deferred.promise); |
| 154 var result = handler(value); | 149 var result = handler(value); |
| 155 if (IS_UNDEFINED(deferred.resolve)) { | 150 if (IS_UNDEFINED(deferred.resolve)) { |
| 156 ResolvePromise(deferred.promise, result); | 151 ResolvePromise(deferred.promise, result); |
| 157 } else { | 152 } else { |
| 158 %_Call(deferred.resolve, UNDEFINED, result); | 153 %_Call(deferred.resolve, UNDEFINED, result); |
| 159 } | 154 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 | 257 |
| 263 // Resolution is a native promise and if it's already resolved or | 258 // Resolution is a native promise and if it's already resolved or |
| 264 // rejected, shortcircuit the resolution procedure by directly | 259 // rejected, shortcircuit the resolution procedure by directly |
| 265 // reusing the value from the promise. | 260 // reusing the value from the promise. |
| 266 if (IsPromise(resolution) && then === PromiseThen) { | 261 if (IsPromise(resolution) && then === PromiseThen) { |
| 267 var thenableState = GET_PRIVATE(resolution, promiseStateSymbol); | 262 var thenableState = GET_PRIVATE(resolution, promiseStateSymbol); |
| 268 if (thenableState === kFulfilled) { | 263 if (thenableState === kFulfilled) { |
| 269 // This goes inside the if-else to save one symbol lookup in | 264 // This goes inside the if-else to save one symbol lookup in |
| 270 // the slow path. | 265 // the slow path. |
| 271 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); | 266 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
| 272 FulfillPromise(promise, kFulfilled, thenableValue, | 267 %PromiseFulfill(promise, kFulfilled, thenableValue, |
| 273 promiseFulfillReactionsSymbol); | 268 promiseFulfillReactionsSymbol); |
| 269 PromiseSet(promise, kFulfilled, thenableValue); |
| 274 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); | 270 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); |
| 275 return; | 271 return; |
| 276 } else if (thenableState === kRejected) { | 272 } else if (thenableState === kRejected) { |
| 277 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); | 273 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
| 278 if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) { | 274 if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) { |
| 279 // Promise has already been rejected, but had no handler. | 275 // Promise has already been rejected, but had no handler. |
| 280 // Revoke previously triggered reject event. | 276 // Revoke previously triggered reject event. |
| 281 %PromiseRevokeReject(resolution); | 277 %PromiseRevokeReject(resolution); |
| 282 } | 278 } |
| 283 // Don't cause a debug event as this case is forwarding a rejection | 279 // Don't cause a debug event as this case is forwarding a rejection |
| 284 RejectPromise(promise, thenableValue, false); | 280 RejectPromise(promise, thenableValue, false); |
| 285 SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); | 281 SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); |
| 286 return; | 282 return; |
| 287 } | 283 } |
| 288 } | 284 } |
| 289 | 285 |
| 290 if (IS_CALLABLE(then)) { | 286 if (IS_CALLABLE(then)) { |
| 291 var callbacks = CreateResolvingFunctions(promise, false); | 287 var callbacks = CreateResolvingFunctions(promise, false); |
| 292 if (DEBUG_IS_ACTIVE && IsPromise(resolution)) { | 288 if (DEBUG_IS_ACTIVE && IsPromise(resolution)) { |
| 293 // Mark the dependency of the new promise on the resolution | 289 // Mark the dependency of the new promise on the resolution |
| 294 SET_PRIVATE(resolution, promiseHandledBySymbol, promise); | 290 SET_PRIVATE(resolution, promiseHandledBySymbol, promise); |
| 295 } | 291 } |
| 296 %EnqueuePromiseResolveThenableJob( | 292 %EnqueuePromiseResolveThenableJob( |
| 297 resolution, then, callbacks.resolve, callbacks.reject); | 293 resolution, then, callbacks.resolve, callbacks.reject); |
| 298 return; | 294 return; |
| 299 } | 295 } |
| 300 } | 296 } |
| 301 FulfillPromise(promise, kFulfilled, resolution, | 297 %PromiseFulfill(promise, kFulfilled, resolution, |
| 302 promiseFulfillReactionsSymbol); | 298 promiseFulfillReactionsSymbol); |
| 299 PromiseSet(promise, kFulfilled, resolution); |
| 303 } | 300 } |
| 304 | 301 |
| 305 // ES#sec-rejectpromise | 302 // ES#sec-rejectpromise |
| 306 // RejectPromise ( promise, reason ) | 303 // RejectPromise ( promise, reason ) |
| 307 function RejectPromise(promise, reason, debugEvent) { | 304 function RejectPromise(promise, reason, debugEvent) { |
| 308 // Check promise status to confirm that this reject has an effect. | 305 // Check promise status to confirm that this reject has an effect. |
| 309 // Call runtime for callbacks to the debugger or for unhandled reject. | 306 // Call runtime for callbacks to the debugger or for unhandled reject. |
| 310 // The debugEvent parameter sets whether a debug ExceptionEvent should | 307 // The debugEvent parameter sets whether a debug ExceptionEvent should |
| 311 // be triggered. It should be set to false when forwarding a rejection | 308 // be triggered. It should be set to false when forwarding a rejection |
| 312 // rather than creating a new one. | 309 // rather than creating a new one. |
| 313 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) { | 310 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) { |
| 314 // This check is redundant with checks in the runtime, but it may help | 311 // This check is redundant with checks in the runtime, but it may help |
| 315 // avoid unnecessary runtime calls. | 312 // avoid unnecessary runtime calls. |
| 316 if ((debugEvent && DEBUG_IS_ACTIVE) || | 313 if ((debugEvent && DEBUG_IS_ACTIVE) || |
| 317 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { | 314 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { |
| 318 %PromiseRejectEvent(promise, reason, debugEvent); | 315 %PromiseRejectEvent(promise, reason, debugEvent); |
| 319 } | 316 } |
| 320 } | 317 } |
| 321 FulfillPromise(promise, kRejected, reason, promiseRejectReactionsSymbol) | 318 %PromiseFulfill(promise, kRejected, reason, promiseRejectReactionsSymbol) |
| 319 PromiseSet(promise, kRejected, reason); |
| 322 } | 320 } |
| 323 | 321 |
| 324 // Export to bindings | 322 // Export to bindings |
| 325 function DoRejectPromise(promise, reason) { | 323 function DoRejectPromise(promise, reason) { |
| 326 return RejectPromise(promise, reason, true); | 324 return RejectPromise(promise, reason, true); |
| 327 } | 325 } |
| 328 | 326 |
| 329 // ES#sec-newpromisecapability | 327 // ES#sec-newpromisecapability |
| 330 // NewPromiseCapability ( C ) | 328 // NewPromiseCapability ( C ) |
| 331 function NewPromiseCapability(C, debugEvent) { | 329 function NewPromiseCapability(C, debugEvent) { |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 to.PromiseThen = PromiseThen; | 670 to.PromiseThen = PromiseThen; |
| 673 | 671 |
| 674 to.GlobalPromise = GlobalPromise; | 672 to.GlobalPromise = GlobalPromise; |
| 675 to.NewPromiseCapability = NewPromiseCapability; | 673 to.NewPromiseCapability = NewPromiseCapability; |
| 676 to.PerformPromiseThen = PerformPromiseThen; | 674 to.PerformPromiseThen = PerformPromiseThen; |
| 677 to.ResolvePromise = ResolvePromise; | 675 to.ResolvePromise = ResolvePromise; |
| 678 to.RejectPromise = RejectPromise; | 676 to.RejectPromise = RejectPromise; |
| 679 }); | 677 }); |
| 680 | 678 |
| 681 }) | 679 }) |
| OLD | NEW |