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 |