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; | 15 var MakeTypeError; |
16 var promiseCombinedDeferredSymbol = | 16 var promiseCombinedDeferredSymbol = |
17 utils.ImportNow("promise_combined_deferred_symbol"); | 17 utils.ImportNow("promise_combined_deferred_symbol"); |
18 var promiseHasHandlerSymbol = | 18 var promiseHasHandlerSymbol = |
19 utils.ImportNow("promise_has_handler_symbol"); | 19 utils.ImportNow("promise_has_handler_symbol"); |
20 var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol"); | 20 var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol"); |
21 var promiseOnResolveSymbol = | 21 var promiseOnResolveSymbol = |
22 utils.ImportNow("promise_on_resolve_symbol"); | 22 utils.ImportNow("promise_on_resolve_symbol"); |
23 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); | 23 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); |
24 var promiseStatusSymbol = utils.ImportNow("promise_status_symbol"); | 24 var promiseStatusSymbol = utils.ImportNow("promise_status_symbol"); |
25 var promiseValueSymbol = utils.ImportNow("promise_value_symbol"); | 25 var promiseValueSymbol = utils.ImportNow("promise_value_symbol"); |
26 var SpeciesConstructor; | 26 var SpeciesConstructor; |
27 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); | 27 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); |
28 | 28 var AsyncFunctionNext; |
29 var AsyncFunctionThrow; | |
29 utils.Import(function(from) { | 30 utils.Import(function(from) { |
30 MakeTypeError = from.MakeTypeError; | 31 MakeTypeError = from.MakeTypeError; |
31 SpeciesConstructor = from.SpeciesConstructor; | 32 SpeciesConstructor = from.SpeciesConstructor; |
33 AsyncFunctionNext = from.AsyncFunctionNext; | |
34 AsyncFunctionThrow = from.AsyncFunctionThrow; | |
32 }); | 35 }); |
33 | 36 |
34 // ------------------------------------------------------------------- | 37 // ------------------------------------------------------------------- |
35 | 38 |
36 // Status values: 0 = pending, +1 = resolved, -1 = rejected | 39 // Status values: 0 = pending, +1 = resolved, -1 = rejected |
37 var lastMicrotaskId = 0; | 40 var lastMicrotaskId = 0; |
38 | 41 |
39 function CreateResolvingFunctions(promise) { | 42 function CreateResolvingFunctions(promise) { |
40 var alreadyResolved = false; | 43 var alreadyResolved = false; |
41 | 44 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
261 // which is usually simply noise. Do not trigger that debug event. | 264 // which is usually simply noise. Do not trigger that debug event. |
262 %PromiseRejectEvent(promise, r, false); | 265 %PromiseRejectEvent(promise, r, false); |
263 return promise; | 266 return promise; |
264 } else { | 267 } else { |
265 var promiseCapability = NewPromiseCapability(this); | 268 var promiseCapability = NewPromiseCapability(this); |
266 %_Call(promiseCapability.reject, UNDEFINED, r); | 269 %_Call(promiseCapability.reject, UNDEFINED, r); |
267 return promiseCapability.promise; | 270 return promiseCapability.promise; |
268 } | 271 } |
269 } | 272 } |
270 | 273 |
274 // Shortcut Promise.reject and Promise.resolve() implementations, used by | |
275 // Async Functions implementation. | |
276 function PromiseCreateRejected(r) { | |
277 var promise = PromiseCreateAndSet(-1, r); | |
278 %PromiseRejectEvent(promise, r, false); | |
279 return promise; | |
280 } | |
281 | |
282 function PromiseCreateResolved(x) { | |
283 if (IsPromise(x) && x.constructor === GlobalPromise) return x; | |
284 return PromiseCreateAndSet(+1, x); | |
285 } | |
286 | |
271 // Multi-unwrapped chaining with thenable coercion. | 287 // Multi-unwrapped chaining with thenable coercion. |
272 | 288 |
273 function PromiseThen(onResolve, onReject) { | 289 function PromiseThen(onResolve, onReject) { |
274 var status = GET_PRIVATE(this, promiseStatusSymbol); | 290 var status = GET_PRIVATE(this, promiseStatusSymbol); |
275 if (IS_UNDEFINED(status)) { | 291 if (IS_UNDEFINED(status)) { |
276 throw MakeTypeError(kNotAPromise, this); | 292 throw MakeTypeError(kNotAPromise, this); |
277 } | 293 } |
278 | 294 |
279 var constructor = SpeciesConstructor(this, GlobalPromise); | 295 var constructor = SpeciesConstructor(this, GlobalPromise); |
280 onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler; | 296 onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 return false; | 433 return false; |
418 } | 434 } |
419 | 435 |
420 // Return whether the promise will be handled by a user-defined reject | 436 // Return whether the promise will be handled by a user-defined reject |
421 // handler somewhere down the promise chain. For this, we do a depth-first | 437 // handler somewhere down the promise chain. For this, we do a depth-first |
422 // search for a reject handler that's not the default PromiseIdRejectHandler. | 438 // search for a reject handler that's not the default PromiseIdRejectHandler. |
423 function PromiseHasUserDefinedRejectHandler() { | 439 function PromiseHasUserDefinedRejectHandler() { |
424 return PromiseHasUserDefinedRejectHandlerRecursive(this); | 440 return PromiseHasUserDefinedRejectHandlerRecursive(this); |
425 }; | 441 }; |
426 | 442 |
443 // TODO(caitp): move me to a new file =) | |
444 function AsyncFunctionResume(generator, sentValue, resumeFunc) { | |
445 try { | |
446 var result = resumeFunc(generator, sentValue); | |
447 if (result.done) return PromiseCreateResolved(result.value); | |
448 } catch (error) { | |
449 return PromiseCreateRejected(error); | |
450 } | |
451 | |
452 %GlobalPrint("await...\n"); | |
453 return %_Call(PromiseThen, PromiseCreateResolved(result.value), | |
454 function(value) { %GlobalPrint("resume normal...\n"); return AsyncFunction Resume(generator, value, AsyncFunctionNext); }, | |
caitp (gmail)
2016/04/16 18:33:03
phantom edits from some debugging =)
| |
455 function(error) { %GlobalPrint("resume throw...\n"); return AsyncFunctionR esume(generator, error, AsyncFunctionThrow); }); | |
456 } | |
457 | |
458 function AsyncFunctionStart(generator) { | |
459 return AsyncFunctionResume(generator, UNDEFINED, AsyncFunctionNext); | |
460 } | |
461 | |
427 // ------------------------------------------------------------------- | 462 // ------------------------------------------------------------------- |
428 // Install exported functions. | 463 // Install exported functions. |
429 | 464 |
430 %AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM); | 465 %AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM); |
431 %AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise", | 466 %AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise", |
432 DONT_ENUM | READ_ONLY); | 467 DONT_ENUM | READ_ONLY); |
433 | 468 |
434 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [ | 469 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [ |
435 "reject", PromiseRejected, | 470 "reject", PromiseRejected, |
436 "all", PromiseAll, | 471 "all", PromiseAll, |
437 "race", PromiseRace, | 472 "race", PromiseRace, |
438 "resolve", PromiseCast | 473 "resolve", PromiseCast |
439 ]); | 474 ]); |
440 | 475 |
441 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [ | 476 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [ |
442 "then", PromiseThen, | 477 "then", PromiseThen, |
443 "catch", PromiseCatch | 478 "catch", PromiseCatch |
444 ]); | 479 ]); |
445 | 480 |
446 %InstallToContext([ | 481 %InstallToContext([ |
447 "promise_catch", PromiseCatch, | 482 "promise_catch", PromiseCatch, |
448 "promise_chain", PromiseChain, | 483 "promise_chain", PromiseChain, |
449 "promise_create", PromiseCreate, | 484 "promise_create", PromiseCreate, |
450 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, | 485 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, |
451 "promise_reject", PromiseReject, | 486 "promise_reject", PromiseReject, |
452 "promise_resolve", PromiseResolve, | 487 "promise_resolve", PromiseResolve, |
453 "promise_then", PromiseThen, | 488 "promise_then", PromiseThen, |
489 "promise_create_rejected", PromiseCreateRejected, | |
490 "promise_create_resolved", PromiseCreateResolved, | |
491 "async_function_start", AsyncFunctionStart | |
454 ]); | 492 ]); |
455 | 493 |
456 // This allows extras to create promises quickly without building extra | 494 // This allows extras to create promises quickly without building extra |
457 // resolve/reject closures, and allows them to later resolve and reject any | 495 // resolve/reject closures, and allows them to later resolve and reject any |
458 // promise without having to hold on to those closures forever. | 496 // promise without having to hold on to those closures forever. |
459 utils.InstallFunctions(extrasUtils, 0, [ | 497 utils.InstallFunctions(extrasUtils, 0, [ |
460 "createPromise", PromiseCreate, | 498 "createPromise", PromiseCreate, |
461 "resolvePromise", PromiseResolve, | 499 "resolvePromise", PromiseResolve, |
462 "rejectPromise", PromiseReject | 500 "rejectPromise", PromiseReject |
463 ]); | 501 ]); |
464 | 502 |
465 // TODO(v8:4567): Allow experimental natives to remove function prototype | 503 // TODO(v8:4567): Allow experimental natives to remove function prototype |
466 [PromiseChain, PromiseDeferred, PromiseResolved].forEach( | 504 [PromiseChain, PromiseDeferred, PromiseResolved].forEach( |
467 fn => %FunctionRemovePrototype(fn)); | 505 fn => %FunctionRemovePrototype(fn)); |
468 | 506 |
469 utils.Export(function(to) { | 507 utils.Export(function(to) { |
470 to.PromiseChain = PromiseChain; | 508 to.PromiseChain = PromiseChain; |
471 to.PromiseDeferred = PromiseDeferred; | 509 to.PromiseDeferred = PromiseDeferred; |
472 to.PromiseResolved = PromiseResolved; | 510 to.PromiseResolved = PromiseResolved; |
473 }); | 511 }); |
474 | 512 |
475 }) | 513 }) |
OLD | NEW |