OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 (function(global, utils, extrasUtils) { | |
6 | |
7 "use strict"; | |
8 | |
9 %CheckIsBootstrapping(); | |
10 | |
11 // ------------------------------------------------------------------- | |
12 // Imports | |
13 | |
14 var AsyncFunctionNext; | |
15 var AsyncFunctionThrow; | |
16 | |
17 utils.Import(function(from) { | |
18 AsyncFunctionNext = from.AsyncFunctionNext; | |
19 AsyncFunctionThrow = from.AsyncFunctionThrow; | |
20 }); | |
21 | |
22 var promiseHandledBySymbol = | |
23 utils.ImportNow("promise_handled_by_symbol"); | |
24 var promiseForwardingHandlerSymbol = | |
25 utils.ImportNow("promise_forwarding_handler_symbol"); | |
26 | |
27 // ------------------------------------------------------------------- | |
28 | |
29 function PromiseCastResolved(value) { | |
30 // TODO(caitp): This is non spec compliant. See v8:5694. | |
31 if (%is_promise(value)) { | |
32 return value; | |
33 } else { | |
34 var promise = %promise_internal_constructor(UNDEFINED); | |
35 %promise_resolve(promise, value); | |
36 return promise; | |
37 } | |
38 } | |
39 | |
40 // ES#abstract-ops-async-function-await | |
41 // AsyncFunctionAwait ( value ) | |
42 // Shared logic for the core of await. The parser desugars | |
43 // await awaited | |
44 // into | |
45 // yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited, .promise) | |
46 // The 'awaited' parameter is the value; the generator stands in | |
47 // for the asyncContext, and .promise is the larger promise under | |
48 // construction by the enclosing async function. | |
49 function AsyncFunctionAwait(generator, awaited, outerPromise) { | |
50 // Promise.resolve(awaited).then( | |
51 // value => AsyncFunctionNext(value), | |
52 // error => AsyncFunctionThrow(error) | |
53 // ); | |
54 var promise = PromiseCastResolved(awaited); | |
55 | |
56 var onFulfilled = sentValue => { | |
57 %_Call(AsyncFunctionNext, generator, sentValue); | |
58 // The resulting Promise is a throwaway, so it doesn't matter what it | |
59 // resolves to. What is important is that we don't end up keeping the | |
60 // whole chain of intermediate Promises alive by returning the value | |
61 // of AsyncFunctionNext, as that would create a memory leak. | |
62 return; | |
63 }; | |
64 var onRejected = sentError => { | |
65 %_Call(AsyncFunctionThrow, generator, sentError); | |
66 // Similarly, returning the huge Promise here would cause a long | |
67 // resolution chain to find what the exception to throw is, and | |
68 // create a similar memory leak, and it does not matter what | |
69 // sort of rejection this intermediate Promise becomes. | |
70 return; | |
71 } | |
72 | |
73 var throwawayPromise = %promise_internal_constructor(promise); | |
74 | |
75 // The Promise will be thrown away and not handled, but it shouldn't trigger | |
76 // unhandled reject events as its work is done | |
77 %PromiseMarkAsHandled(throwawayPromise); | |
78 | |
79 if (DEBUG_IS_ACTIVE) { | |
80 if (%is_promise(awaited)) { | |
81 // Mark the reject handler callback to be a forwarding edge, rather | |
82 // than a meaningful catch handler | |
83 SET_PRIVATE(onRejected, promiseForwardingHandlerSymbol, true); | |
84 } | |
85 | |
86 // Mark the dependency to outerPromise in case the throwaway Promise is | |
87 // found on the Promise stack | |
88 SET_PRIVATE(throwawayPromise, promiseHandledBySymbol, outerPromise); | |
89 } | |
90 | |
91 %perform_promise_then(promise, onFulfilled, onRejected, throwawayPromise); | |
92 } | |
93 | |
94 // Called by the parser from the desugaring of 'await' when catch | |
95 // prediction indicates no locally surrounding catch block | |
96 function AsyncFunctionAwaitUncaught(generator, awaited, outerPromise) { | |
97 AsyncFunctionAwait(generator, awaited, outerPromise); | |
98 } | |
99 | |
100 // Called by the parser from the desugaring of 'await' when catch | |
101 // prediction indicates that there is a locally surrounding catch block | |
102 function AsyncFunctionAwaitCaught(generator, awaited, outerPromise) { | |
103 if (DEBUG_IS_ACTIVE && %is_promise(awaited)) { | |
104 %PromiseMarkHandledHint(awaited); | |
105 } | |
106 AsyncFunctionAwait(generator, awaited, outerPromise); | |
107 } | |
108 | |
109 %InstallToContext([ | |
110 "async_function_await_caught", AsyncFunctionAwaitCaught, | |
111 "async_function_await_uncaught", AsyncFunctionAwaitUncaught, | |
112 ]); | |
113 | |
114 }) | |
OLD | NEW |