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 |
11 // ------------------------------------------------------------------- | 11 // ------------------------------------------------------------------- |
12 // Imports | 12 // Imports |
13 | 13 |
14 var InternalArray = utils.InternalArray; | 14 var InternalArray = utils.InternalArray; |
15 var MakeTypeError; | |
16 var promiseCombinedDeferredSymbol = | 15 var promiseCombinedDeferredSymbol = |
17 utils.ImportNow("promise_combined_deferred_symbol"); | 16 utils.ImportNow("promise_combined_deferred_symbol"); |
18 var promiseHasHandlerSymbol = | 17 var promiseHasHandlerSymbol = |
19 utils.ImportNow("promise_has_handler_symbol"); | 18 utils.ImportNow("promise_has_handler_symbol"); |
20 var promiseRejectReactionsSymbol = | 19 var promiseRejectReactionsSymbol = |
21 utils.ImportNow("promise_reject_reactions_symbol"); | 20 utils.ImportNow("promise_reject_reactions_symbol"); |
22 var promiseFulfillReactionsSymbol = | 21 var promiseFulfillReactionsSymbol = |
23 utils.ImportNow("promise_fulfill_reactions_symbol"); | 22 utils.ImportNow("promise_fulfill_reactions_symbol"); |
24 var promiseDeferredReactionsSymbol = | 23 var promiseDeferredReactionsSymbol = |
25 utils.ImportNow("promise_deferred_reactions_symbol"); | 24 utils.ImportNow("promise_deferred_reactions_symbol"); |
26 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); | 25 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); |
27 var promiseStateSymbol = utils.ImportNow("promise_state_symbol"); | 26 var promiseStateSymbol = utils.ImportNow("promise_state_symbol"); |
28 var promiseResultSymbol = utils.ImportNow("promise_result_symbol"); | 27 var promiseResultSymbol = utils.ImportNow("promise_result_symbol"); |
29 var SpeciesConstructor; | 28 var SpeciesConstructor; |
30 var speciesSymbol = utils.ImportNow("species_symbol"); | 29 var speciesSymbol = utils.ImportNow("species_symbol"); |
31 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); | 30 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); |
32 | 31 |
33 utils.Import(function(from) { | 32 utils.Import(function(from) { |
34 MakeTypeError = from.MakeTypeError; | |
35 SpeciesConstructor = from.SpeciesConstructor; | 33 SpeciesConstructor = from.SpeciesConstructor; |
36 }); | 34 }); |
37 | 35 |
38 // ------------------------------------------------------------------- | 36 // ------------------------------------------------------------------- |
39 | 37 |
40 // [[PromiseState]] values: | 38 // [[PromiseState]] values: |
41 const kPending = 0; | 39 const kPending = 0; |
42 const kFulfilled = +1; | 40 const kFulfilled = +1; |
43 const kRejected = -1; | 41 const kRejected = -1; |
44 | 42 |
(...skipping 27 matching lines...) Expand all Loading... |
72 }; | 70 }; |
73 } | 71 } |
74 | 72 |
75 | 73 |
76 // ES#sec-promise-executor | 74 // ES#sec-promise-executor |
77 // Promise ( executor ) | 75 // Promise ( executor ) |
78 var GlobalPromise = function Promise(executor) { | 76 var GlobalPromise = function Promise(executor) { |
79 if (executor === promiseRawSymbol) { | 77 if (executor === promiseRawSymbol) { |
80 return %_NewObject(GlobalPromise, new.target); | 78 return %_NewObject(GlobalPromise, new.target); |
81 } | 79 } |
82 if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this); | 80 if (IS_UNDEFINED(new.target)) throw %make_type_error(kNotAPromise, this); |
83 if (!IS_CALLABLE(executor)) { | 81 if (!IS_CALLABLE(executor)) { |
84 throw MakeTypeError(kResolverNotAFunction, executor); | 82 throw %make_type_error(kResolverNotAFunction, executor); |
85 } | 83 } |
86 | 84 |
87 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target)); | 85 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target)); |
88 var callbacks = CreateResolvingFunctions(promise); | 86 var callbacks = CreateResolvingFunctions(promise); |
89 var debug_is_active = DEBUG_IS_ACTIVE; | 87 var debug_is_active = DEBUG_IS_ACTIVE; |
90 try { | 88 try { |
91 if (debug_is_active) %DebugPushPromise(promise); | 89 if (debug_is_active) %DebugPushPromise(promise); |
92 executor(callbacks.resolve, callbacks.reject); | 90 executor(callbacks.resolve, callbacks.reject); |
93 } %catch (e) { // Natives syntax to mark this catch block. | 91 } %catch (e) { // Natives syntax to mark this catch block. |
94 %_Call(callbacks.reject, UNDEFINED, e); | 92 %_Call(callbacks.reject, UNDEFINED, e); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 } | 231 } |
234 | 232 |
235 function PromiseCreate() { | 233 function PromiseCreate() { |
236 return new GlobalPromise(PromiseNopResolver) | 234 return new GlobalPromise(PromiseNopResolver) |
237 } | 235 } |
238 | 236 |
239 // ES#sec-promise-resolve-functions | 237 // ES#sec-promise-resolve-functions |
240 // Promise Resolve Functions, steps 6-13 | 238 // Promise Resolve Functions, steps 6-13 |
241 function ResolvePromise(promise, resolution) { | 239 function ResolvePromise(promise, resolution) { |
242 if (resolution === promise) { | 240 if (resolution === promise) { |
243 return RejectPromise(promise, MakeTypeError(kPromiseCyclic, resolution)); | 241 return RejectPromise(promise, %make_type_error(kPromiseCyclic, resolution)); |
244 } | 242 } |
245 if (IS_RECEIVER(resolution)) { | 243 if (IS_RECEIVER(resolution)) { |
246 // 25.4.1.3.2 steps 8-12 | 244 // 25.4.1.3.2 steps 8-12 |
247 try { | 245 try { |
248 var then = resolution.then; | 246 var then = resolution.then; |
249 } catch (e) { | 247 } catch (e) { |
250 return RejectPromise(promise, e); | 248 return RejectPromise(promise, e); |
251 } | 249 } |
252 | 250 |
253 // Resolution is a native promise and if it's already resolved or | 251 // Resolution is a native promise and if it's already resolved or |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 return { | 328 return { |
331 promise: promise, | 329 promise: promise, |
332 resolve: callbacks.resolve, | 330 resolve: callbacks.resolve, |
333 reject: callbacks.reject | 331 reject: callbacks.reject |
334 }; | 332 }; |
335 } | 333 } |
336 | 334 |
337 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; | 335 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; |
338 result.promise = new C((resolve, reject) => { | 336 result.promise = new C((resolve, reject) => { |
339 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) | 337 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) |
340 throw MakeTypeError(kPromiseExecutorAlreadyInvoked); | 338 throw %make_type_error(kPromiseExecutorAlreadyInvoked); |
341 result.resolve = resolve; | 339 result.resolve = resolve; |
342 result.reject = reject; | 340 result.reject = reject; |
343 }); | 341 }); |
344 | 342 |
345 if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject)) | 343 if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject)) |
346 throw MakeTypeError(kPromiseNonCallable); | 344 throw %make_type_error(kPromiseNonCallable); |
347 | 345 |
348 return result; | 346 return result; |
349 } | 347 } |
350 | 348 |
351 // Unspecified V8-specific legacy function | 349 // Unspecified V8-specific legacy function |
352 function PromiseDefer() { | 350 function PromiseDefer() { |
353 %IncrementUseCounter(kPromiseDefer); | 351 %IncrementUseCounter(kPromiseDefer); |
354 return NewPromiseCapability(this); | 352 return NewPromiseCapability(this); |
355 } | 353 } |
356 | 354 |
357 // Unspecified V8-specific legacy function | 355 // Unspecified V8-specific legacy function |
358 function PromiseAccept(x) { | 356 function PromiseAccept(x) { |
359 %IncrementUseCounter(kPromiseAccept); | 357 %IncrementUseCounter(kPromiseAccept); |
360 return %_Call(PromiseResolve, this, x); | 358 return %_Call(PromiseResolve, this, x); |
361 } | 359 } |
362 | 360 |
363 // ES#sec-promise.reject | 361 // ES#sec-promise.reject |
364 // Promise.reject ( x ) | 362 // Promise.reject ( x ) |
365 function PromiseReject(r) { | 363 function PromiseReject(r) { |
366 if (!IS_RECEIVER(this)) { | 364 if (!IS_RECEIVER(this)) { |
367 throw MakeTypeError(kCalledOnNonObject, PromiseResolve); | 365 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
368 } | 366 } |
369 if (this === GlobalPromise) { | 367 if (this === GlobalPromise) { |
370 // Optimized case, avoid extra closure. | 368 // Optimized case, avoid extra closure. |
371 var promise = PromiseCreateAndSet(kRejected, r); | 369 var promise = PromiseCreateAndSet(kRejected, r); |
372 // The debug event for this would always be an uncaught promise reject, | 370 // The debug event for this would always be an uncaught promise reject, |
373 // which is usually simply noise. Do not trigger that debug event. | 371 // which is usually simply noise. Do not trigger that debug event. |
374 %PromiseRejectEvent(promise, r, false); | 372 %PromiseRejectEvent(promise, r, false); |
375 return promise; | 373 return promise; |
376 } else { | 374 } else { |
377 var promiseCapability = NewPromiseCapability(this); | 375 var promiseCapability = NewPromiseCapability(this); |
(...skipping 11 matching lines...) Expand all Loading... |
389 function PromiseCreateResolved(x) { | 387 function PromiseCreateResolved(x) { |
390 return %_Call(PromiseResolve, GlobalPromise, x); | 388 return %_Call(PromiseResolve, GlobalPromise, x); |
391 } | 389 } |
392 | 390 |
393 // ES#sec-promise.prototype.then | 391 // ES#sec-promise.prototype.then |
394 // Promise.prototype.then ( onFulfilled, onRejected ) | 392 // Promise.prototype.then ( onFulfilled, onRejected ) |
395 // Multi-unwrapped chaining with thenable coercion. | 393 // Multi-unwrapped chaining with thenable coercion. |
396 function PromiseThen(onResolve, onReject) { | 394 function PromiseThen(onResolve, onReject) { |
397 var status = GET_PRIVATE(this, promiseStateSymbol); | 395 var status = GET_PRIVATE(this, promiseStateSymbol); |
398 if (IS_UNDEFINED(status)) { | 396 if (IS_UNDEFINED(status)) { |
399 throw MakeTypeError(kNotAPromise, this); | 397 throw %make_type_error(kNotAPromise, this); |
400 } | 398 } |
401 | 399 |
402 var constructor = SpeciesConstructor(this, GlobalPromise); | 400 var constructor = SpeciesConstructor(this, GlobalPromise); |
403 onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler; | 401 onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler; |
404 onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler; | 402 onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler; |
405 var deferred = NewPromiseCapability(constructor); | 403 var deferred = NewPromiseCapability(constructor); |
406 switch (status) { | 404 switch (status) { |
407 case kPending: | 405 case kPending: |
408 PromiseAttachCallbacks(this, deferred, onResolve, onReject); | 406 PromiseAttachCallbacks(this, deferred, onResolve, onReject); |
409 break; | 407 break; |
(...skipping 28 matching lines...) Expand all Loading... |
438 function PromiseCatch(onReject) { | 436 function PromiseCatch(onReject) { |
439 return this.then(UNDEFINED, onReject); | 437 return this.then(UNDEFINED, onReject); |
440 } | 438 } |
441 | 439 |
442 // Combinators. | 440 // Combinators. |
443 | 441 |
444 // ES#sec-promise.resolve | 442 // ES#sec-promise.resolve |
445 // Promise.resolve ( x ) | 443 // Promise.resolve ( x ) |
446 function PromiseResolve(x) { | 444 function PromiseResolve(x) { |
447 if (!IS_RECEIVER(this)) { | 445 if (!IS_RECEIVER(this)) { |
448 throw MakeTypeError(kCalledOnNonObject, PromiseResolve); | 446 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
449 } | 447 } |
450 if (IsPromise(x) && x.constructor === this) return x; | 448 if (IsPromise(x) && x.constructor === this) return x; |
451 | 449 |
452 // Avoid creating resolving functions. | 450 // Avoid creating resolving functions. |
453 if (this === GlobalPromise) { | 451 if (this === GlobalPromise) { |
454 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); | 452 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); |
455 var resolveResult = ResolvePromise(promise, x); | 453 var resolveResult = ResolvePromise(promise, x); |
456 return promise; | 454 return promise; |
457 } | 455 } |
458 | 456 |
459 var promiseCapability = NewPromiseCapability(this); | 457 var promiseCapability = NewPromiseCapability(this); |
460 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x); | 458 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x); |
461 return promiseCapability.promise; | 459 return promiseCapability.promise; |
462 } | 460 } |
463 | 461 |
464 // ES#sec-promise.all | 462 // ES#sec-promise.all |
465 // Promise.all ( iterable ) | 463 // Promise.all ( iterable ) |
466 function PromiseAll(iterable) { | 464 function PromiseAll(iterable) { |
467 if (!IS_RECEIVER(this)) { | 465 if (!IS_RECEIVER(this)) { |
468 throw MakeTypeError(kCalledOnNonObject, "Promise.all"); | 466 throw %make_type_error(kCalledOnNonObject, "Promise.all"); |
469 } | 467 } |
470 | 468 |
471 var deferred = NewPromiseCapability(this); | 469 var deferred = NewPromiseCapability(this); |
472 var resolutions = new InternalArray(); | 470 var resolutions = new InternalArray(); |
473 var count; | 471 var count; |
474 | 472 |
475 function CreateResolveElementFunction(index, values, promiseCapability) { | 473 function CreateResolveElementFunction(index, values, promiseCapability) { |
476 var alreadyCalled = false; | 474 var alreadyCalled = false; |
477 return (x) => { | 475 return (x) => { |
478 if (alreadyCalled === true) return; | 476 if (alreadyCalled === true) return; |
(...skipping 30 matching lines...) Expand all Loading... |
509 } catch (e) { | 507 } catch (e) { |
510 %_Call(deferred.reject, UNDEFINED, e); | 508 %_Call(deferred.reject, UNDEFINED, e); |
511 } | 509 } |
512 return deferred.promise; | 510 return deferred.promise; |
513 } | 511 } |
514 | 512 |
515 // ES#sec-promise.race | 513 // ES#sec-promise.race |
516 // Promise.race ( iterable ) | 514 // Promise.race ( iterable ) |
517 function PromiseRace(iterable) { | 515 function PromiseRace(iterable) { |
518 if (!IS_RECEIVER(this)) { | 516 if (!IS_RECEIVER(this)) { |
519 throw MakeTypeError(kCalledOnNonObject, PromiseRace); | 517 throw %make_type_error(kCalledOnNonObject, PromiseRace); |
520 } | 518 } |
521 | 519 |
522 var deferred = NewPromiseCapability(this); | 520 var deferred = NewPromiseCapability(this); |
523 try { | 521 try { |
524 for (var value of iterable) { | 522 for (var value of iterable) { |
525 this.resolve(value).then(deferred.resolve, deferred.reject); | 523 this.resolve(value).then(deferred.resolve, deferred.reject); |
526 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred); | 524 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred); |
527 } | 525 } |
528 } catch (e) { | 526 } catch (e) { |
529 deferred.reject(e) | 527 deferred.reject(e) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 to.PromiseChain = PromiseChain; | 623 to.PromiseChain = PromiseChain; |
626 to.PromiseDefer = PromiseDefer; | 624 to.PromiseDefer = PromiseDefer; |
627 to.PromiseAccept = PromiseAccept; | 625 to.PromiseAccept = PromiseAccept; |
628 | 626 |
629 to.PromiseCreateRejected = PromiseCreateRejected; | 627 to.PromiseCreateRejected = PromiseCreateRejected; |
630 to.PromiseCreateResolved = PromiseCreateResolved; | 628 to.PromiseCreateResolved = PromiseCreateResolved; |
631 to.PromiseThen = PromiseThen; | 629 to.PromiseThen = PromiseThen; |
632 }); | 630 }); |
633 | 631 |
634 }) | 632 }) |
OLD | NEW |