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 26 matching lines...) Expand all Loading... | |
| 37 var ObjectHasOwnProperty; | 37 var ObjectHasOwnProperty; |
| 38 | 38 |
| 39 utils.Import(function(from) { | 39 utils.Import(function(from) { |
| 40 ObjectHasOwnProperty = from.ObjectHasOwnProperty; | 40 ObjectHasOwnProperty = from.ObjectHasOwnProperty; |
| 41 SpeciesConstructor = from.SpeciesConstructor; | 41 SpeciesConstructor = from.SpeciesConstructor; |
| 42 }); | 42 }); |
| 43 | 43 |
| 44 // ------------------------------------------------------------------- | 44 // ------------------------------------------------------------------- |
| 45 | 45 |
| 46 // [[PromiseState]] values: | 46 // [[PromiseState]] values: |
| 47 // These values should be kept in sync with PromiseStatus in globals.h | |
| 47 const kPending = 0; | 48 const kPending = 0; |
| 48 const kFulfilled = +1; | 49 const kFulfilled = +1; |
| 49 const kRejected = -1; | 50 const kRejected = +2; |
| 50 | 51 |
| 51 // ES#sec-createresolvingfunctions | 52 // ES#sec-createresolvingfunctions |
| 52 // CreateResolvingFunctions ( promise ) | 53 // CreateResolvingFunctions ( promise ) |
| 53 function CreateResolvingFunctions(promise, debugEvent) { | 54 function CreateResolvingFunctions(promise, debugEvent) { |
| 54 var alreadyResolved = false; | 55 var alreadyResolved = false; |
| 55 | 56 |
| 56 // ES#sec-promise-resolve-functions | 57 // ES#sec-promise-resolve-functions |
| 57 // Promise Resolve Functions | 58 // Promise Resolve Functions |
| 58 var resolve = value => { | 59 var resolve = value => { |
| 59 if (alreadyResolved === true) return; | 60 if (alreadyResolved === true) return; |
| 60 alreadyResolved = true; | 61 alreadyResolved = true; |
| 61 ResolvePromise(promise, value); | 62 ResolvePromise(promise, value); |
| 62 }; | 63 }; |
| 63 | 64 |
| 64 // ES#sec-promise-reject-functions | 65 // ES#sec-promise-reject-functions |
| 65 // Promise Reject Functions | 66 // Promise Reject Functions |
| 66 var reject = reason => { | 67 var reject = reason => { |
| 67 if (alreadyResolved === true) return; | 68 if (alreadyResolved === true) return; |
| 68 alreadyResolved = true; | 69 alreadyResolved = true; |
| 69 RejectPromise(promise, reason, debugEvent); | 70 %PromiseReject(promise, reason, debugEvent); |
| 71 PromiseSet(promise, kRejected, reason); | |
| 70 }; | 72 }; |
| 71 | 73 |
| 72 return { | 74 return { |
| 73 __proto__: null, | 75 __proto__: null, |
| 74 resolve: resolve, | 76 resolve: resolve, |
| 75 reject: reject | 77 reject: reject |
| 76 }; | 78 }; |
| 77 } | 79 } |
| 78 | 80 |
| 79 | 81 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 if (IS_UNDEFINED(deferred.resolve)) { | 152 if (IS_UNDEFINED(deferred.resolve)) { |
| 151 ResolvePromise(deferred.promise, result); | 153 ResolvePromise(deferred.promise, result); |
| 152 } else { | 154 } else { |
| 153 %_Call(deferred.resolve, UNDEFINED, result); | 155 %_Call(deferred.resolve, UNDEFINED, result); |
| 154 } | 156 } |
| 155 } %catch (exception) { // Natives syntax to mark this catch block. | 157 } %catch (exception) { // Natives syntax to mark this catch block. |
| 156 try { | 158 try { |
| 157 if (IS_UNDEFINED(deferred.reject)) { | 159 if (IS_UNDEFINED(deferred.reject)) { |
| 158 // Pass false for debugEvent so .then chaining does not trigger | 160 // Pass false for debugEvent so .then chaining does not trigger |
| 159 // redundant ExceptionEvents. | 161 // redundant ExceptionEvents. |
| 160 RejectPromise(deferred.promise, exception, false); | 162 %PromiseReject(deferred.promise, exception, false); |
| 163 PromiseSet(deferred.promise, kRejected, exception); | |
| 161 } else { | 164 } else { |
| 162 %_Call(deferred.reject, UNDEFINED, exception); | 165 %_Call(deferred.reject, UNDEFINED, exception); |
| 163 } | 166 } |
| 164 } catch (e) { } | 167 } catch (e) { } |
| 165 } finally { | 168 } finally { |
| 166 if (debug_is_active) %DebugPopPromise(); | 169 if (debug_is_active) %DebugPopPromise(); |
| 167 } | 170 } |
| 168 } | 171 } |
| 169 | 172 |
| 170 function PromiseDebugGetInfo(deferreds, status) { | 173 function PromiseDebugGetInfo(deferreds, status) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 } | 239 } |
| 237 | 240 |
| 238 function PromiseCreate() { | 241 function PromiseCreate() { |
| 239 return PromiseInit(new GlobalPromise(promiseRawSymbol)); | 242 return PromiseInit(new GlobalPromise(promiseRawSymbol)); |
| 240 } | 243 } |
| 241 | 244 |
| 242 // ES#sec-promise-resolve-functions | 245 // ES#sec-promise-resolve-functions |
| 243 // Promise Resolve Functions, steps 6-13 | 246 // Promise Resolve Functions, steps 6-13 |
| 244 function ResolvePromise(promise, resolution) { | 247 function ResolvePromise(promise, resolution) { |
| 245 if (resolution === promise) { | 248 if (resolution === promise) { |
| 246 return RejectPromise(promise, | 249 var exception = %make_type_error(kPromiseCyclic, resolution); |
| 247 %make_type_error(kPromiseCyclic, resolution), | 250 %PromiseReject(promise, exception, true); |
| 248 true); | 251 PromiseSet(promise, kRejected, exception); |
| 252 return; | |
| 249 } | 253 } |
| 250 if (IS_RECEIVER(resolution)) { | 254 if (IS_RECEIVER(resolution)) { |
| 251 // 25.4.1.3.2 steps 8-12 | 255 // 25.4.1.3.2 steps 8-12 |
| 252 try { | 256 try { |
| 253 var then = resolution.then; | 257 var then = resolution.then; |
| 254 } catch (e) { | 258 } catch (e) { |
| 255 return RejectPromise(promise, e, true); | 259 %PromiseReject(promise, e, true); |
| 260 PromiseSet(promise, kRejected, e); | |
| 261 return; | |
| 256 } | 262 } |
| 257 | 263 |
| 258 // Resolution is a native promise and if it's already resolved or | 264 // Resolution is a native promise and if it's already resolved or |
| 259 // rejected, shortcircuit the resolution procedure by directly | 265 // rejected, shortcircuit the resolution procedure by directly |
| 260 // reusing the value from the promise. | 266 // reusing the value from the promise. |
| 261 if (IsPromise(resolution) && then === PromiseThen) { | 267 if (IsPromise(resolution) && then === PromiseThen) { |
| 262 var thenableState = GET_PRIVATE(resolution, promiseStateSymbol); | 268 var thenableState = GET_PRIVATE(resolution, promiseStateSymbol); |
| 263 if (thenableState === kFulfilled) { | 269 if (thenableState === kFulfilled) { |
| 264 // This goes inside the if-else to save one symbol lookup in | 270 // This goes inside the if-else to save one symbol lookup in |
| 265 // the slow path. | 271 // the slow path. |
| 266 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); | 272 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
| 267 %PromiseFulfill(promise, kFulfilled, thenableValue, | 273 %PromiseFulfill(promise, kFulfilled, thenableValue, |
| 268 promiseFulfillReactionsSymbol); | 274 promiseFulfillReactionsSymbol); |
| 269 PromiseSet(promise, kFulfilled, thenableValue); | 275 PromiseSet(promise, kFulfilled, thenableValue); |
| 270 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); | 276 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); |
| 271 return; | 277 return; |
| 272 } else if (thenableState === kRejected) { | 278 } else if (thenableState === kRejected) { |
| 273 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); | 279 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
| 274 if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) { | 280 if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) { |
| 275 // Promise has already been rejected, but had no handler. | 281 // Promise has already been rejected, but had no handler. |
| 276 // Revoke previously triggered reject event. | 282 // Revoke previously triggered reject event. |
| 277 %PromiseRevokeReject(resolution); | 283 %PromiseRevokeReject(resolution); |
| 278 } | 284 } |
| 279 // Don't cause a debug event as this case is forwarding a rejection | 285 // Don't cause a debug event as this case is forwarding a rejection |
| 280 RejectPromise(promise, thenableValue, false); | 286 %PromiseReject(promise, thenableValue, false); |
| 287 PromiseSet(promise, kRejected, thenableValue); | |
| 281 SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); | 288 SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); |
| 282 return; | 289 return; |
| 283 } | 290 } |
| 284 } | 291 } |
| 285 | 292 |
| 286 if (IS_CALLABLE(then)) { | 293 if (IS_CALLABLE(then)) { |
| 287 var callbacks = CreateResolvingFunctions(promise, false); | 294 var callbacks = CreateResolvingFunctions(promise, false); |
| 288 if (DEBUG_IS_ACTIVE && IsPromise(resolution)) { | 295 if (DEBUG_IS_ACTIVE && IsPromise(resolution)) { |
| 289 // Mark the dependency of the new promise on the resolution | 296 // Mark the dependency of the new promise on the resolution |
| 290 SET_PRIVATE(resolution, promiseHandledBySymbol, promise); | 297 SET_PRIVATE(resolution, promiseHandledBySymbol, promise); |
| 291 } | 298 } |
| 292 %EnqueuePromiseResolveThenableJob( | 299 %EnqueuePromiseResolveThenableJob( |
| 293 resolution, then, callbacks.resolve, callbacks.reject); | 300 resolution, then, callbacks.resolve, callbacks.reject); |
| 294 return; | 301 return; |
| 295 } | 302 } |
| 296 } | 303 } |
| 297 %PromiseFulfill(promise, kFulfilled, resolution, | 304 %PromiseFulfill(promise, kFulfilled, resolution, |
| 298 promiseFulfillReactionsSymbol); | 305 promiseFulfillReactionsSymbol); |
| 299 PromiseSet(promise, kFulfilled, resolution); | 306 PromiseSet(promise, kFulfilled, resolution); |
| 300 } | 307 } |
| 301 | 308 |
| 302 // ES#sec-rejectpromise | 309 // Only used by async-await.js |
| 303 // RejectPromise ( promise, reason ) | 310 function RejectPromise(promise, reason) { |
| 304 function RejectPromise(promise, reason, debugEvent) { | 311 %PromiseReject(promise, reason, false); |
| 305 // Call runtime for callbacks to the debugger or for unhandled reject. | |
| 306 // The debugEvent parameter sets whether a debug ExceptionEvent should | |
| 307 // be triggered. It should be set to false when forwarding a rejection | |
| 308 // rather than creating a new one. | |
| 309 // This check is redundant with checks in the runtime, but it may help | |
| 310 // avoid unnecessary runtime calls. | |
| 311 if ((debugEvent && DEBUG_IS_ACTIVE) || | |
| 312 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { | |
| 313 %PromiseRejectEvent(promise, reason, debugEvent); | |
| 314 } | |
| 315 %PromiseFulfill(promise, kRejected, reason, promiseRejectReactionsSymbol) | |
| 316 PromiseSet(promise, kRejected, reason); | 312 PromiseSet(promise, kRejected, reason); |
| 317 } | 313 } |
| 318 | 314 |
| 319 // Export to bindings | 315 // Export to bindings |
| 320 function DoRejectPromise(promise, reason) { | 316 function DoRejectPromise(promise, reason) { |
| 321 return RejectPromise(promise, reason, true); | 317 %PromiseReject(promise, reason, true); |
| 318 PromiseSet(promise, kRejected, reason); | |
| 319 return; | |
|
adamk
2016/10/27 08:02:34
No need for this empty return
gsathya
2016/10/27 11:27:48
Done.
| |
| 322 } | 320 } |
| 323 | 321 |
| 324 // ES#sec-newpromisecapability | 322 // ES#sec-newpromisecapability |
| 325 // NewPromiseCapability ( C ) | 323 // NewPromiseCapability ( C ) |
| 326 function NewPromiseCapability(C, debugEvent) { | 324 function NewPromiseCapability(C, debugEvent) { |
| 327 if (C === GlobalPromise) { | 325 if (C === GlobalPromise) { |
| 328 // Optimized case, avoid extra closure. | 326 // Optimized case, avoid extra closure. |
| 329 var promise = PromiseCreate(); | 327 var promise = PromiseCreate(); |
| 330 var callbacks = CreateResolvingFunctions(promise, debugEvent); | 328 var callbacks = CreateResolvingFunctions(promise, debugEvent); |
| 331 return { | 329 return { |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 to.PromiseThen = PromiseThen; | 665 to.PromiseThen = PromiseThen; |
| 668 | 666 |
| 669 to.GlobalPromise = GlobalPromise; | 667 to.GlobalPromise = GlobalPromise; |
| 670 to.NewPromiseCapability = NewPromiseCapability; | 668 to.NewPromiseCapability = NewPromiseCapability; |
| 671 to.PerformPromiseThen = PerformPromiseThen; | 669 to.PerformPromiseThen = PerformPromiseThen; |
| 672 to.ResolvePromise = ResolvePromise; | 670 to.ResolvePromise = ResolvePromise; |
| 673 to.RejectPromise = RejectPromise; | 671 to.RejectPromise = RejectPromise; |
| 674 }); | 672 }); |
| 675 | 673 |
| 676 }) | 674 }) |
| OLD | NEW |