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 | 37 |
38 // [[PromiseState]] values: | 38 // [[PromiseState]] values: |
39 const kPending = 0; | 39 const kPending = 0; |
40 const kFulfilled = +1; | 40 const kFulfilled = +1; |
41 const kRejected = -1; | 41 const kRejected = -1; |
42 | 42 |
43 var lastMicrotaskId = 0; | 43 var lastMicrotaskId = 0; |
44 | 44 |
45 // ES#sec-createresolvingfunctions | 45 // ES#sec-createresolvingfunctions |
46 // CreateResolvingFunctions ( promise ) | 46 // CreateResolvingFunctions ( promise ) |
47 function CreateResolvingFunctions(promise) { | 47 function CreateResolvingFunctions(promise, debugEvent) { |
48 var alreadyResolved = false; | 48 var alreadyResolved = false; |
49 | 49 |
50 // ES#sec-promise-resolve-functions | 50 // ES#sec-promise-resolve-functions |
51 // Promise Resolve Functions | 51 // Promise Resolve Functions |
52 var resolve = value => { | 52 var resolve = value => { |
53 if (alreadyResolved === true) return; | 53 if (alreadyResolved === true) return; |
54 alreadyResolved = true; | 54 alreadyResolved = true; |
55 ResolvePromise(promise, value); | 55 ResolvePromise(promise, value); |
56 }; | 56 }; |
57 | 57 |
58 // ES#sec-promise-reject-functions | 58 // ES#sec-promise-reject-functions |
59 // Promise Reject Functions | 59 // Promise Reject Functions |
60 var reject = reason => { | 60 var reject = reason => { |
61 if (alreadyResolved === true) return; | 61 if (alreadyResolved === true) return; |
62 alreadyResolved = true; | 62 alreadyResolved = true; |
63 RejectPromise(promise, reason); | 63 RejectPromise(promise, reason, debugEvent); |
64 }; | 64 }; |
65 | 65 |
66 return { | 66 return { |
67 __proto__: null, | 67 __proto__: null, |
68 resolve: resolve, | 68 resolve: resolve, |
69 reject: reject | 69 reject: reject |
70 }; | 70 }; |
71 } | 71 } |
72 | 72 |
73 | 73 |
74 // ES#sec-promise-executor | 74 // ES#sec-promise-executor |
75 // Promise ( executor ) | 75 // Promise ( executor ) |
76 var GlobalPromise = function Promise(executor) { | 76 var GlobalPromise = function Promise(executor) { |
77 if (executor === promiseRawSymbol) { | 77 if (executor === promiseRawSymbol) { |
78 return %_NewObject(GlobalPromise, new.target); | 78 return %_NewObject(GlobalPromise, new.target); |
79 } | 79 } |
80 if (IS_UNDEFINED(new.target)) throw %make_type_error(kNotAPromise, this); | 80 if (IS_UNDEFINED(new.target)) throw %make_type_error(kNotAPromise, this); |
81 if (!IS_CALLABLE(executor)) { | 81 if (!IS_CALLABLE(executor)) { |
82 throw %make_type_error(kResolverNotAFunction, executor); | 82 throw %make_type_error(kResolverNotAFunction, executor); |
83 } | 83 } |
84 | 84 |
85 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target)); | 85 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target)); |
86 var callbacks = CreateResolvingFunctions(promise); | 86 // Calling the reject function would be a new exception, so debugEvent = true |
| 87 var callbacks = CreateResolvingFunctions(promise, true); |
87 var debug_is_active = DEBUG_IS_ACTIVE; | 88 var debug_is_active = DEBUG_IS_ACTIVE; |
88 try { | 89 try { |
89 if (debug_is_active) %DebugPushPromise(promise); | 90 if (debug_is_active) %DebugPushPromise(promise); |
90 executor(callbacks.resolve, callbacks.reject); | 91 executor(callbacks.resolve, callbacks.reject); |
91 } %catch (e) { // Natives syntax to mark this catch block. | 92 } %catch (e) { // Natives syntax to mark this catch block. |
92 %_Call(callbacks.reject, UNDEFINED, e); | 93 %_Call(callbacks.reject, UNDEFINED, e); |
93 } finally { | 94 } finally { |
94 if (debug_is_active) %DebugPopPromise(); | 95 if (debug_is_active) %DebugPopPromise(); |
95 } | 96 } |
96 | 97 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 } | 232 } |
232 | 233 |
233 function PromiseCreate() { | 234 function PromiseCreate() { |
234 return new GlobalPromise(PromiseNopResolver) | 235 return new GlobalPromise(PromiseNopResolver) |
235 } | 236 } |
236 | 237 |
237 // ES#sec-promise-resolve-functions | 238 // ES#sec-promise-resolve-functions |
238 // Promise Resolve Functions, steps 6-13 | 239 // Promise Resolve Functions, steps 6-13 |
239 function ResolvePromise(promise, resolution) { | 240 function ResolvePromise(promise, resolution) { |
240 if (resolution === promise) { | 241 if (resolution === promise) { |
241 return RejectPromise(promise, %make_type_error(kPromiseCyclic, resolution)); | 242 return RejectPromise(promise, |
| 243 %make_type_error(kPromiseCyclic, resolution), |
| 244 true); |
242 } | 245 } |
243 if (IS_RECEIVER(resolution)) { | 246 if (IS_RECEIVER(resolution)) { |
244 // 25.4.1.3.2 steps 8-12 | 247 // 25.4.1.3.2 steps 8-12 |
245 try { | 248 try { |
246 var then = resolution.then; | 249 var then = resolution.then; |
247 } catch (e) { | 250 } catch (e) { |
248 return RejectPromise(promise, e); | 251 return RejectPromise(promise, e, true); |
249 } | 252 } |
250 | 253 |
251 // Resolution is a native promise and if it's already resolved or | 254 // Resolution is a native promise and if it's already resolved or |
252 // rejected, shortcircuit the resolution procedure by directly | 255 // rejected, shortcircuit the resolution procedure by directly |
253 // reusing the value from the promise. | 256 // reusing the value from the promise. |
254 if (IsPromise(resolution) && then === PromiseThen) { | 257 if (IsPromise(resolution) && then === PromiseThen) { |
255 var thenableState = GET_PRIVATE(resolution, promiseStateSymbol); | 258 var thenableState = GET_PRIVATE(resolution, promiseStateSymbol); |
256 if (thenableState === kFulfilled) { | 259 if (thenableState === kFulfilled) { |
257 // This goes inside the if-else to save one symbol lookup in | 260 // This goes inside the if-else to save one symbol lookup in |
258 // the slow path. | 261 // the slow path. |
259 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); | 262 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
260 FulfillPromise(promise, kFulfilled, thenableValue, | 263 FulfillPromise(promise, kFulfilled, thenableValue, |
261 promiseFulfillReactionsSymbol); | 264 promiseFulfillReactionsSymbol); |
262 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); | 265 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); |
263 return; | 266 return; |
264 } else if (thenableState === kRejected) { | 267 } else if (thenableState === kRejected) { |
265 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); | 268 var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol); |
266 if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) { | 269 if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) { |
267 // Promise has already been rejected, but had no handler. | 270 // Promise has already been rejected, but had no handler. |
268 // Revoke previously triggered reject event. | 271 // Revoke previously triggered reject event. |
269 %PromiseRevokeReject(resolution); | 272 %PromiseRevokeReject(resolution); |
270 } | 273 } |
271 RejectPromise(promise, thenableValue); | 274 // Don't cause a debug event as this case is forwarding a rejection |
| 275 RejectPromise(promise, thenableValue, false); |
272 SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); | 276 SET_PRIVATE(resolution, promiseHasHandlerSymbol, true); |
273 return; | 277 return; |
274 } | 278 } |
275 } | 279 } |
276 | 280 |
277 if (IS_CALLABLE(then)) { | 281 if (IS_CALLABLE(then)) { |
278 // PromiseResolveThenableJob | 282 // PromiseResolveThenableJob |
279 var id; | 283 var id; |
280 var name = "PromiseResolveThenableJob"; | 284 var name = "PromiseResolveThenableJob"; |
281 var instrumenting = DEBUG_IS_ACTIVE; | 285 var instrumenting = DEBUG_IS_ACTIVE; |
282 %EnqueueMicrotask(function() { | 286 %EnqueueMicrotask(function() { |
283 if (instrumenting) { | 287 if (instrumenting) { |
284 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); | 288 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); |
285 } | 289 } |
286 var callbacks = CreateResolvingFunctions(promise); | 290 // These resolving functions simply forward the exception, so |
| 291 // don't create a new debugEvent. |
| 292 var callbacks = CreateResolvingFunctions(promise, false); |
287 try { | 293 try { |
288 %_Call(then, resolution, callbacks.resolve, callbacks.reject); | 294 %_Call(then, resolution, callbacks.resolve, callbacks.reject); |
289 } catch (e) { | 295 } catch (e) { |
290 %_Call(callbacks.reject, UNDEFINED, e); | 296 %_Call(callbacks.reject, UNDEFINED, e); |
291 } | 297 } |
292 if (instrumenting) { | 298 if (instrumenting) { |
293 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); | 299 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); |
294 } | 300 } |
295 }); | 301 }); |
296 if (instrumenting) { | 302 if (instrumenting) { |
297 id = ++lastMicrotaskId; | 303 id = ++lastMicrotaskId; |
298 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); | 304 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); |
299 } | 305 } |
300 return; | 306 return; |
301 } | 307 } |
302 } | 308 } |
303 FulfillPromise(promise, kFulfilled, resolution, promiseFulfillReactionsSymbol)
; | 309 FulfillPromise(promise, kFulfilled, resolution, promiseFulfillReactionsSymbol)
; |
304 } | 310 } |
305 | 311 |
306 // ES#sec-rejectpromise | 312 // ES#sec-rejectpromise |
307 // RejectPromise ( promise, reason ) | 313 // RejectPromise ( promise, reason ) |
308 function RejectPromise(promise, reason) { | 314 function RejectPromise(promise, reason, debugEvent) { |
309 // Check promise status to confirm that this reject has an effect. | 315 // Check promise status to confirm that this reject has an effect. |
310 // Call runtime for callbacks to the debugger or for unhandled reject. | 316 // Call runtime for callbacks to the debugger or for unhandled reject. |
| 317 // The debugEvent parameter sets whether a debug ExceptionEvent should |
| 318 // be triggered. It should be set to false when forwarding a rejection |
| 319 // rather than creating a new one. |
311 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) { | 320 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) { |
312 var debug_is_active = DEBUG_IS_ACTIVE; | 321 // This check is redundant with checks in the runtime, but it may help |
313 if (debug_is_active || | 322 // avoid unnecessary runtime calls. |
| 323 if ((debugEvent && DEBUG_IS_ACTIVE) || |
314 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { | 324 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { |
315 %PromiseRejectEvent(promise, reason, debug_is_active); | 325 %PromiseRejectEvent(promise, reason, debugEvent); |
316 } | 326 } |
317 } | 327 } |
318 FulfillPromise(promise, kRejected, reason, promiseRejectReactionsSymbol) | 328 FulfillPromise(promise, kRejected, reason, promiseRejectReactionsSymbol) |
319 } | 329 } |
320 | 330 |
| 331 // Export to bindings |
| 332 function DoRejectPromise(promise, reason) { |
| 333 return RejectPromise(promise, reason, true); |
| 334 } |
| 335 |
321 // ES#sec-newpromisecapability | 336 // ES#sec-newpromisecapability |
322 // NewPromiseCapability ( C ) | 337 // NewPromiseCapability ( C ) |
323 function NewPromiseCapability(C) { | 338 function NewPromiseCapability(C, debugEvent) { |
324 if (C === GlobalPromise) { | 339 if (C === GlobalPromise) { |
325 // Optimized case, avoid extra closure. | 340 // Optimized case, avoid extra closure. |
326 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); | 341 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); |
327 var callbacks = CreateResolvingFunctions(promise); | 342 var callbacks = CreateResolvingFunctions(promise, debugEvent); |
328 return { | 343 return { |
329 promise: promise, | 344 promise: promise, |
330 resolve: callbacks.resolve, | 345 resolve: callbacks.resolve, |
331 reject: callbacks.reject | 346 reject: callbacks.reject |
332 }; | 347 }; |
333 } | 348 } |
334 | 349 |
335 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; | 350 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; |
336 result.promise = new C((resolve, reject) => { | 351 result.promise = new C((resolve, reject) => { |
337 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) | 352 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) |
(...skipping 10 matching lines...) Expand all Loading... |
348 | 363 |
349 // ES#sec-promise.reject | 364 // ES#sec-promise.reject |
350 // Promise.reject ( x ) | 365 // Promise.reject ( x ) |
351 function PromiseReject(r) { | 366 function PromiseReject(r) { |
352 if (!IS_RECEIVER(this)) { | 367 if (!IS_RECEIVER(this)) { |
353 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 368 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
354 } | 369 } |
355 if (this === GlobalPromise) { | 370 if (this === GlobalPromise) { |
356 // Optimized case, avoid extra closure. | 371 // Optimized case, avoid extra closure. |
357 var promise = PromiseCreateAndSet(kRejected, r); | 372 var promise = PromiseCreateAndSet(kRejected, r); |
358 // The debug event for this would always be an uncaught promise reject, | 373 // Trigger debug events if the debugger is on, as Promise.reject is |
359 // which is usually simply noise. Do not trigger that debug event. | 374 // equivalent to throwing an exception directly. |
360 %PromiseRejectEvent(promise, r, false); | 375 %PromiseRejectEventFromStack(promise, r); |
361 return promise; | 376 return promise; |
362 } else { | 377 } else { |
363 var promiseCapability = NewPromiseCapability(this); | 378 var promiseCapability = NewPromiseCapability(this, true); |
364 %_Call(promiseCapability.reject, UNDEFINED, r); | 379 %_Call(promiseCapability.reject, UNDEFINED, r); |
365 return promiseCapability.promise; | 380 return promiseCapability.promise; |
366 } | 381 } |
367 } | 382 } |
368 | 383 |
369 // Shortcut Promise.reject and Promise.resolve() implementations, used by | 384 // Shortcut Promise.reject and Promise.resolve() implementations, used by |
370 // Async Functions implementation. | 385 // Async Functions implementation. |
371 function PromiseCreateRejected(r) { | 386 function PromiseCreateRejected(r) { |
372 return %_Call(PromiseReject, GlobalPromise, r); | 387 var promise = PromiseCreateAndSet(kRejected, r); |
| 388 // This is called from the desugaring of async/await; no reason to |
| 389 // create a redundant reject event. |
| 390 %PromiseRejectEvent(promise, r, false); |
| 391 return promise; |
373 } | 392 } |
374 | 393 |
375 function PromiseCreateResolved(value) { | 394 function PromiseCreateResolved(value) { |
376 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); | 395 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); |
377 var resolveResult = ResolvePromise(promise, value); | 396 var resolveResult = ResolvePromise(promise, value); |
378 return promise; | 397 return promise; |
379 } | 398 } |
380 | 399 |
381 function PromiseCastResolved(value) { | 400 function PromiseCastResolved(value) { |
382 if (IsPromise(value)) { | 401 if (IsPromise(value)) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 // ES#sec-promise.prototype.then | 439 // ES#sec-promise.prototype.then |
421 // Promise.prototype.then ( onFulfilled, onRejected ) | 440 // Promise.prototype.then ( onFulfilled, onRejected ) |
422 // Multi-unwrapped chaining with thenable coercion. | 441 // Multi-unwrapped chaining with thenable coercion. |
423 function PromiseThen(onResolve, onReject) { | 442 function PromiseThen(onResolve, onReject) { |
424 var status = GET_PRIVATE(this, promiseStateSymbol); | 443 var status = GET_PRIVATE(this, promiseStateSymbol); |
425 if (IS_UNDEFINED(status)) { | 444 if (IS_UNDEFINED(status)) { |
426 throw %make_type_error(kNotAPromise, this); | 445 throw %make_type_error(kNotAPromise, this); |
427 } | 446 } |
428 | 447 |
429 var constructor = SpeciesConstructor(this, GlobalPromise); | 448 var constructor = SpeciesConstructor(this, GlobalPromise); |
430 var resultCapability = NewPromiseCapability(constructor); | 449 // Pass false for debugEvent so .then chaining does not trigger |
| 450 // redundant ExceptionEvents. |
| 451 var resultCapability = NewPromiseCapability(constructor, false); |
431 return PerformPromiseThen(this, onResolve, onReject, resultCapability); | 452 return PerformPromiseThen(this, onResolve, onReject, resultCapability); |
432 } | 453 } |
433 | 454 |
434 // ES#sec-promise.prototype.catch | 455 // ES#sec-promise.prototype.catch |
435 // Promise.prototype.catch ( onRejected ) | 456 // Promise.prototype.catch ( onRejected ) |
436 function PromiseCatch(onReject) { | 457 function PromiseCatch(onReject) { |
437 return this.then(UNDEFINED, onReject); | 458 return this.then(UNDEFINED, onReject); |
438 } | 459 } |
439 | 460 |
440 // Combinators. | 461 // Combinators. |
441 | 462 |
442 // ES#sec-promise.resolve | 463 // ES#sec-promise.resolve |
443 // Promise.resolve ( x ) | 464 // Promise.resolve ( x ) |
444 function PromiseResolve(x) { | 465 function PromiseResolve(x) { |
445 if (!IS_RECEIVER(this)) { | 466 if (!IS_RECEIVER(this)) { |
446 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 467 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
447 } | 468 } |
448 if (IsPromise(x) && x.constructor === this) return x; | 469 if (IsPromise(x) && x.constructor === this) return x; |
449 | 470 |
450 // Avoid creating resolving functions. | 471 // Avoid creating resolving functions. |
451 if (this === GlobalPromise) { | 472 if (this === GlobalPromise) { |
452 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); | 473 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); |
453 var resolveResult = ResolvePromise(promise, x); | 474 var resolveResult = ResolvePromise(promise, x); |
454 return promise; | 475 return promise; |
455 } | 476 } |
456 | 477 |
457 var promiseCapability = NewPromiseCapability(this); | 478 // debugEvent is not so meaningful here as it will be resolved |
| 479 var promiseCapability = NewPromiseCapability(this, true); |
458 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x); | 480 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x); |
459 return promiseCapability.promise; | 481 return promiseCapability.promise; |
460 } | 482 } |
461 | 483 |
462 // ES#sec-promise.all | 484 // ES#sec-promise.all |
463 // Promise.all ( iterable ) | 485 // Promise.all ( iterable ) |
464 function PromiseAll(iterable) { | 486 function PromiseAll(iterable) { |
465 if (!IS_RECEIVER(this)) { | 487 if (!IS_RECEIVER(this)) { |
466 throw %make_type_error(kCalledOnNonObject, "Promise.all"); | 488 throw %make_type_error(kCalledOnNonObject, "Promise.all"); |
467 } | 489 } |
468 | 490 |
469 var deferred = NewPromiseCapability(this); | 491 // false debugEvent so that forwarding the rejection through all does not |
| 492 // trigger redundant ExceptionEvents |
| 493 var deferred = NewPromiseCapability(this, false); |
470 var resolutions = new InternalArray(); | 494 var resolutions = new InternalArray(); |
471 var count; | 495 var count; |
472 | 496 |
473 function CreateResolveElementFunction(index, values, promiseCapability) { | 497 function CreateResolveElementFunction(index, values, promiseCapability) { |
474 var alreadyCalled = false; | 498 var alreadyCalled = false; |
475 return (x) => { | 499 return (x) => { |
476 if (alreadyCalled === true) return; | 500 if (alreadyCalled === true) return; |
477 alreadyCalled = true; | 501 alreadyCalled = true; |
478 values[index] = x; | 502 values[index] = x; |
479 if (--count === 0) { | 503 if (--count === 0) { |
(...skipping 30 matching lines...) Expand all Loading... |
510 return deferred.promise; | 534 return deferred.promise; |
511 } | 535 } |
512 | 536 |
513 // ES#sec-promise.race | 537 // ES#sec-promise.race |
514 // Promise.race ( iterable ) | 538 // Promise.race ( iterable ) |
515 function PromiseRace(iterable) { | 539 function PromiseRace(iterable) { |
516 if (!IS_RECEIVER(this)) { | 540 if (!IS_RECEIVER(this)) { |
517 throw %make_type_error(kCalledOnNonObject, PromiseRace); | 541 throw %make_type_error(kCalledOnNonObject, PromiseRace); |
518 } | 542 } |
519 | 543 |
520 var deferred = NewPromiseCapability(this); | 544 // false debugEvent so that forwarding the rejection through race does not |
| 545 // trigger redundant ExceptionEvents |
| 546 var deferred = NewPromiseCapability(this, false); |
521 try { | 547 try { |
522 for (var value of iterable) { | 548 for (var value of iterable) { |
523 this.resolve(value).then(deferred.resolve, deferred.reject); | 549 this.resolve(value).then(deferred.resolve, deferred.reject); |
524 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred); | 550 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred); |
525 } | 551 } |
526 } catch (e) { | 552 } catch (e) { |
527 deferred.reject(e) | 553 deferred.reject(e) |
528 } | 554 } |
529 return deferred.promise; | 555 return deferred.promise; |
530 } | 556 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 | 617 |
592 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [ | 618 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [ |
593 "then", PromiseThen, | 619 "then", PromiseThen, |
594 "catch", PromiseCatch | 620 "catch", PromiseCatch |
595 ]); | 621 ]); |
596 | 622 |
597 %InstallToContext([ | 623 %InstallToContext([ |
598 "promise_catch", PromiseCatch, | 624 "promise_catch", PromiseCatch, |
599 "promise_create", PromiseCreate, | 625 "promise_create", PromiseCreate, |
600 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, | 626 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, |
601 "promise_reject", RejectPromise, | 627 "promise_reject", DoRejectPromise, |
602 "promise_resolve", ResolvePromise, | 628 "promise_resolve", ResolvePromise, |
603 "promise_then", PromiseThen, | 629 "promise_then", PromiseThen, |
604 "promise_create_rejected", PromiseCreateRejected, | 630 "promise_create_rejected", PromiseCreateRejected, |
605 "promise_create_resolved", PromiseCreateResolved | 631 "promise_create_resolved", PromiseCreateResolved |
606 ]); | 632 ]); |
607 | 633 |
608 // This allows extras to create promises quickly without building extra | 634 // This allows extras to create promises quickly without building extra |
609 // resolve/reject closures, and allows them to later resolve and reject any | 635 // resolve/reject closures, and allows them to later resolve and reject any |
610 // promise without having to hold on to those closures forever. | 636 // promise without having to hold on to those closures forever. |
611 utils.InstallFunctions(extrasUtils, 0, [ | 637 utils.InstallFunctions(extrasUtils, 0, [ |
612 "createPromise", PromiseCreate, | 638 "createPromise", PromiseCreate, |
613 "resolvePromise", ResolvePromise, | 639 "resolvePromise", ResolvePromise, |
614 "rejectPromise", RejectPromise | 640 "rejectPromise", DoRejectPromise |
615 ]); | 641 ]); |
616 | 642 |
617 utils.Export(function(to) { | 643 utils.Export(function(to) { |
618 to.PromiseCastResolved = PromiseCastResolved; | 644 to.PromiseCastResolved = PromiseCastResolved; |
619 to.PromiseThen = PromiseThen; | 645 to.PromiseThen = PromiseThen; |
620 | 646 |
621 to.GlobalPromise = GlobalPromise; | 647 to.GlobalPromise = GlobalPromise; |
622 to.NewPromiseCapability = NewPromiseCapability; | 648 to.NewPromiseCapability = NewPromiseCapability; |
623 to.PerformPromiseThen = PerformPromiseThen; | 649 to.PerformPromiseThen = PerformPromiseThen; |
624 }); | 650 }); |
625 | 651 |
626 }) | 652 }) |
OLD | NEW |