Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(878)

Side by Side Diff: src/js/harmony-async-await.js

Issue 2365123002: Move async/await JS support code out of experimental natives (Closed)
Patch Set: Alphabetize Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 var GlobalPromise;
17 var IsPromise;
18 var NewPromiseCapability;
19 var PerformPromiseThen;
20 var PromiseCreate;
21 var PromiseNextMicrotaskID;
22 var RejectPromise;
23 var ResolvePromise;
24
25 utils.Import(function(from) {
26 AsyncFunctionNext = from.AsyncFunctionNext;
27 AsyncFunctionThrow = from.AsyncFunctionThrow;
28 GlobalPromise = from.GlobalPromise;
29 IsPromise = from.IsPromise;
30 NewPromiseCapability = from.NewPromiseCapability;
31 PerformPromiseThen = from.PerformPromiseThen;
32 PromiseCreate = from.PromiseCreate;
33 PromiseNextMicrotaskID = from.PromiseNextMicrotaskID;
34 RejectPromise = from.RejectPromise;
35 ResolvePromise = from.ResolvePromise;
36 });
37
38 var promiseAsyncStackIDSymbol =
39 utils.ImportNow("promise_async_stack_id_symbol");
40 var promiseHandledBySymbol =
41 utils.ImportNow("promise_handled_by_symbol");
42 var promiseForwardingHandlerSymbol =
43 utils.ImportNow("promise_forwarding_handler_symbol");
44 var promiseHandledHintSymbol =
45 utils.ImportNow("promise_handled_hint_symbol");
46 var promiseHasHandlerSymbol =
47 utils.ImportNow("promise_has_handler_symbol");
48
49 // -------------------------------------------------------------------
50
51 function PromiseCastResolved(value) {
52 if (IsPromise(value)) {
53 return value;
54 } else {
55 var promise = PromiseCreate();
56 ResolvePromise(promise, value);
57 return promise;
58 }
59 }
60
61 // ES#abstract-ops-async-function-await
62 // AsyncFunctionAwait ( value )
63 // Shared logic for the core of await. The parser desugars
64 // await awaited
65 // into
66 // yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited, .promise)
67 // The 'awaited' parameter is the value; the generator stands in
68 // for the asyncContext, and .promise is the larger promise under
69 // construction by the enclosing async function.
70 function AsyncFunctionAwait(generator, awaited, outerPromise) {
71 // Promise.resolve(awaited).then(
72 // value => AsyncFunctionNext(value),
73 // error => AsyncFunctionThrow(error)
74 // );
75 var promise = PromiseCastResolved(awaited);
76
77 var onFulfilled = sentValue => {
78 %_Call(AsyncFunctionNext, generator, sentValue);
79 // The resulting Promise is a throwaway, so it doesn't matter what it
80 // resolves to. What is important is that we don't end up keeping the
81 // whole chain of intermediate Promises alive by returning the value
82 // of AsyncFunctionNext, as that would create a memory leak.
83 return;
84 };
85 var onRejected = sentError => {
86 %_Call(AsyncFunctionThrow, generator, sentError);
87 // Similarly, returning the huge Promise here would cause a long
88 // resolution chain to find what the exception to throw is, and
89 // create a similar memory leak, and it does not matter what
90 // sort of rejection this intermediate Promise becomes.
91 return;
92 }
93
94 // Just forwarding the exception, so no debugEvent for throwawayCapability
95 var throwawayCapability = NewPromiseCapability(GlobalPromise, false);
96
97 // The Promise will be thrown away and not handled, but it shouldn't trigger
98 // unhandled reject events as its work is done
99 SET_PRIVATE(throwawayCapability.promise, promiseHasHandlerSymbol, true);
100
101 if (DEBUG_IS_ACTIVE) {
102 if (IsPromise(awaited)) {
103 // Mark the reject handler callback to be a forwarding edge, rather
104 // than a meaningful catch handler
105 SET_PRIVATE(onRejected, promiseForwardingHandlerSymbol, true);
106 }
107
108 // Mark the dependency to outerPromise in case the throwaway Promise is
109 // found on the Promise stack
110 SET_PRIVATE(throwawayCapability.promise, promiseHandledBySymbol,
111 outerPromise);
112 }
113
114 PerformPromiseThen(promise, onFulfilled, onRejected, throwawayCapability);
115 }
116
117 // Called by the parser from the desugaring of 'await' when catch
118 // prediction indicates no locally surrounding catch block
119 function AsyncFunctionAwaitUncaught(generator, awaited, outerPromise) {
120 AsyncFunctionAwait(generator, awaited, outerPromise);
121 }
122
123 // Called by the parser from the desugaring of 'await' when catch
124 // prediction indicates that there is a locally surrounding catch block
125 function AsyncFunctionAwaitCaught(generator, awaited, outerPromise) {
126 if (DEBUG_IS_ACTIVE && IsPromise(awaited)) {
127 SET_PRIVATE(awaited, promiseHandledHintSymbol, true);
128 }
129 AsyncFunctionAwait(generator, awaited, outerPromise);
130 }
131
132 // How the parser rejects promises from async/await desugaring
133 function RejectPromiseNoDebugEvent(promise, reason) {
134 return RejectPromise(promise, reason, false);
135 }
136
137 function AsyncFunctionPromiseCreate() {
138 var promise = PromiseCreate();
139 if (DEBUG_IS_ACTIVE) {
140 // Push the Promise under construction in an async function on
141 // the catch prediction stack to handle exceptions thrown before
142 // the first await.
143 %DebugPushPromise(promise);
144 // Assign ID and create a recurring task to save stack for future
145 // resumptions from await.
146 var id = PromiseNextMicrotaskID();
147 SET_PRIVATE(promise, promiseAsyncStackIDSymbol, id);
148 %DebugAsyncTaskEvent({
149 type: "enqueueRecurring",
150 id: id,
151 name: "async function",
152 });
153 }
154 return promise;
155 }
156
157 function AsyncFunctionPromiseRelease(promise) {
158 if (DEBUG_IS_ACTIVE) {
159 // Cancel
160 var id = GET_PRIVATE(promise, promiseAsyncStackIDSymbol);
161 %DebugAsyncTaskEvent({
162 type: "cancel",
163 id: id,
164 name: "async function",
165 });
166 // Pop the Promise under construction in an async function on
167 // from catch prediction stack.
168 %DebugPopPromise();
169 }
170 }
171
172 %InstallToContext([
173 "async_function_await_caught", AsyncFunctionAwaitCaught,
174 "async_function_await_uncaught", AsyncFunctionAwaitUncaught,
175 "reject_promise_no_debug_event", RejectPromiseNoDebugEvent,
176 "async_function_promise_create", AsyncFunctionPromiseCreate,
177 "async_function_promise_release", AsyncFunctionPromiseRelease,
178 ]);
179
180 })
OLDNEW
« no previous file with comments | « src/js/async-await.js ('k') | src/js/prologue.js » ('j') | src/js/prologue.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698