OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 ResolvePromise(promise, value); | 47 ResolvePromise(promise, value); |
48 return promise; | 48 return promise; |
49 } | 49 } |
50 } | 50 } |
51 | 51 |
52 // ES#abstract-ops-async-function-await | 52 // ES#abstract-ops-async-function-await |
53 // AsyncFunctionAwait ( value ) | 53 // AsyncFunctionAwait ( value ) |
54 // Shared logic for the core of await. The parser desugars | 54 // Shared logic for the core of await. The parser desugars |
55 // await awaited | 55 // await awaited |
56 // into | 56 // into |
57 // yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited) | 57 // yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited, .promise) |
58 // The 'awaited' parameter is the value; the generator stands in | 58 // The 'awaited' parameter is the value; the generator stands in |
59 // for the asyncContext, and mark is metadata for debugging | 59 // for the asyncContext, and .promise is the larger promise under |
60 function AsyncFunctionAwait(generator, awaited, mark) { | 60 // construction by the enclosing async function. |
61 function AsyncFunctionAwait(generator, awaited, outerPromise) { | |
61 // Promise.resolve(awaited).then( | 62 // Promise.resolve(awaited).then( |
62 // value => AsyncFunctionNext(value), | 63 // value => AsyncFunctionNext(value), |
63 // error => AsyncFunctionThrow(error) | 64 // error => AsyncFunctionThrow(error) |
64 // ); | 65 // ); |
65 var promise = PromiseCastResolved(awaited); | 66 var promise = PromiseCastResolved(awaited); |
66 | 67 |
67 var onFulfilled = | 68 var onFulfilled = |
68 (sentValue) => %_Call(AsyncFunctionNext, generator, sentValue); | 69 (sentValue) => %_Call(AsyncFunctionNext, generator, sentValue); |
69 var onRejected = | 70 var onRejected = |
70 (sentError) => %_Call(AsyncFunctionThrow, generator, sentError); | 71 (sentError) => %_Call(AsyncFunctionThrow, generator, sentError); |
71 | 72 |
72 if (mark && DEBUG_IS_ACTIVE && IsPromise(awaited)) { | 73 var debug_is_active = DEBUG_IS_ACTIVE; |
73 // Mark the reject handler callback such that it does not influence | 74 |
74 // catch prediction. | 75 if (!IS_UNDEFINED(outerPromise) && debug_is_active && IsPromise(awaited)) { |
75 SET_PRIVATE(onRejected, promiseAwaitHandlerSymbol, true); | 76 // Mark the reject handler callback to continue recursing to outerPromise |
77 SET_PRIVATE(onRejected, promiseAwaitHandlerSymbol, outerPromise); | |
76 } | 78 } |
77 | 79 |
78 // Just forwarding the exception, so no debugEvent for throwawayCapability | 80 // Just forwarding the exception, so no debugEvent for throwawayCapability |
79 var throwawayCapability = NewPromiseCapability(GlobalPromise, false); | 81 var throwawayCapability = NewPromiseCapability(GlobalPromise, false); |
80 return PerformPromiseThen(promise, onFulfilled, onRejected, | 82 PerformPromiseThen(promise, onFulfilled, onRejected, |
81 throwawayCapability); | 83 throwawayCapability); |
jgruber
2016/09/12 13:22:00
Nit: needs formatting.
Dan Ehrenberg
2016/09/12 22:49:25
Moved to one line
| |
84 | |
85 if (debug_is_active) { | |
jgruber
2016/09/12 13:22:00
Should this also check for !IS_UNDEFINED(outerProm
Dan Ehrenberg
2016/09/12 22:51:23
Added the IS_UNDEFINED check and merged the blocks
| |
86 // Mark the dependency to outerPromise in case the throwaway Promise is | |
87 // found on the Promise stack | |
88 SET_PRIVATE(throwawayCapability.promise, promiseAwaitHandlerSymbol, | |
89 outerPromise); | |
90 } | |
82 } | 91 } |
83 | 92 |
84 // Called by the parser from the desugaring of 'await' when catch | 93 // Called by the parser from the desugaring of 'await' when catch |
85 // prediction indicates no locally surrounding catch block | 94 // prediction indicates no locally surrounding catch block |
86 function AsyncFunctionAwaitUncaught(generator, awaited) { | 95 function AsyncFunctionAwaitUncaught(generator, awaited, outerPromise) { |
87 // TODO(littledan): Install a dependency edge from awaited to outerPromise | 96 AsyncFunctionAwait(generator, awaited, outerPromise); |
88 return AsyncFunctionAwait(generator, awaited, true); | 97 return outerPromise; |
89 } | 98 } |
90 | 99 |
91 // Called by the parser from the desugaring of 'await' when catch | 100 // Called by the parser from the desugaring of 'await' when catch |
92 // prediction indicates that there is a locally surrounding catch block | 101 // prediction indicates that there is a locally surrounding catch block |
93 function AsyncFunctionAwaitCaught(generator, awaited) { | 102 function AsyncFunctionAwaitCaught(generator, awaited, outerPromise) { |
94 if (DEBUG_IS_ACTIVE && IsPromise(awaited)) { | 103 if (DEBUG_IS_ACTIVE && IsPromise(awaited)) { |
95 SET_PRIVATE(awaited, promiseHandledHintSymbol, true); | 104 SET_PRIVATE(awaited, promiseHandledHintSymbol, true); |
96 } | 105 } |
97 return AsyncFunctionAwait(generator, awaited, false); | 106 // Pass undefined for the outer Promise to not waste time setting up |
107 // or following the dependency chain when this Promise is already marked | |
108 // as handled | |
109 AsyncFunctionAwait(generator, awaited, UNDEFINED); | |
110 return outerPromise; | |
98 } | 111 } |
99 | 112 |
100 // How the parser rejects promises from async/await desugaring | 113 // How the parser rejects promises from async/await desugaring |
101 function RejectPromiseNoDebugEvent(promise, reason) { | 114 function RejectPromiseNoDebugEvent(promise, reason) { |
102 return RejectPromise(promise, reason, false); | 115 return RejectPromise(promise, reason, false); |
103 } | 116 } |
104 | 117 |
105 %InstallToContext([ | 118 %InstallToContext([ |
106 "async_function_await_caught", AsyncFunctionAwaitCaught, | 119 "async_function_await_caught", AsyncFunctionAwaitCaught, |
107 "async_function_await_uncaught", AsyncFunctionAwaitUncaught, | 120 "async_function_await_uncaught", AsyncFunctionAwaitUncaught, |
108 "reject_promise_no_debug_event", RejectPromiseNoDebugEvent, | 121 "reject_promise_no_debug_event", RejectPromiseNoDebugEvent, |
109 ]); | 122 ]); |
110 | 123 |
111 }) | 124 }) |
OLD | NEW |