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

Side by Side Diff: src/js/promise.js

Issue 1919143004: Renaming cleanup of Promises (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
« no previous file with comments | « src/js/prologue.js ('k') | src/js/promise-extra.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 promiseRejectReactionsSymbol =
21 var promiseOnResolveSymbol = 21 utils.ImportNow("promise_reject_reactions_symbol");
22 utils.ImportNow("promise_on_resolve_symbol"); 22 var promiseFulfillReactionsSymbol =
23 utils.ImportNow("promise_fulfill_reactions_symbol");
23 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); 24 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol");
24 var promiseStatusSymbol = utils.ImportNow("promise_status_symbol"); 25 var promiseStateSymbol = utils.ImportNow("promise_state_symbol");
25 var promiseValueSymbol = utils.ImportNow("promise_value_symbol"); 26 var promiseResultSymbol = utils.ImportNow("promise_result_symbol");
26 var SpeciesConstructor; 27 var SpeciesConstructor;
27 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); 28 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
28 29
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;
32 }); 33 });
33 34
34 // ------------------------------------------------------------------- 35 // -------------------------------------------------------------------
35 36
36 // Status values: 0 = pending, +1 = resolved, -1 = rejected 37 // [[PromiseState]] values:
38 const kPending = 0;
39 const kFulfilled = +1;
40 const kRejected = -1;
41
37 var lastMicrotaskId = 0; 42 var lastMicrotaskId = 0;
38 43
44 // ES#sec-createresolvingfunctions
45 // CreateResolvingFunctions ( promise )
39 function CreateResolvingFunctions(promise) { 46 function CreateResolvingFunctions(promise) {
40 var alreadyResolved = false; 47 var alreadyResolved = false;
41 48
49 // ES#sec-promise-resolve-functions
50 // Promise Resolve Functions
42 var resolve = value => { 51 var resolve = value => {
43 if (alreadyResolved === true) return; 52 if (alreadyResolved === true) return;
44 alreadyResolved = true; 53 alreadyResolved = true;
45 PromiseResolve(promise, value); 54 FulfillPromise(promise, value);
46 }; 55 };
47 56
57 // ES#sec-promise-reject-functions
58 // Promise Reject Functions
48 var reject = reason => { 59 var reject = reason => {
49 if (alreadyResolved === true) return; 60 if (alreadyResolved === true) return;
50 alreadyResolved = true; 61 alreadyResolved = true;
51 PromiseReject(promise, reason); 62 RejectPromise(promise, reason);
52 }; 63 };
53 64
54 return { 65 return {
55 __proto__: null, 66 __proto__: null,
56 resolve: resolve, 67 resolve: resolve,
57 reject: reject 68 reject: reject
58 }; 69 };
59 } 70 }
60 71
61 72
73 // ES#sec-promise-executor
74 // Promise ( executor )
62 var GlobalPromise = function Promise(resolver) { 75 var GlobalPromise = function Promise(resolver) {
63 if (resolver === promiseRawSymbol) { 76 if (resolver === promiseRawSymbol) {
64 return %_NewObject(GlobalPromise, new.target); 77 return %_NewObject(GlobalPromise, new.target);
65 } 78 }
66 if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this); 79 if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this);
67 if (!IS_CALLABLE(resolver)) 80 if (!IS_CALLABLE(resolver)) {
68 throw MakeTypeError(kResolverNotAFunction, resolver); 81 throw MakeTypeError(kResolverNotAFunction, resolver);
82 }
69 83
70 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target)); 84 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target));
71 var callbacks = CreateResolvingFunctions(promise); 85 var callbacks = CreateResolvingFunctions(promise);
72 86
73 try { 87 try {
74 %DebugPushPromise(promise, Promise); 88 %DebugPushPromise(promise, Promise);
75 resolver(callbacks.resolve, callbacks.reject); 89 resolver(callbacks.resolve, callbacks.reject);
76 } catch (e) { 90 } catch (e) {
77 %_Call(callbacks.reject, UNDEFINED, e); 91 %_Call(callbacks.reject, UNDEFINED, e);
78 } finally { 92 } finally {
79 %DebugPopPromise(); 93 %DebugPopPromise();
80 } 94 }
81 95
82 return promise; 96 return promise;
83 } 97 }
84 98
85 // Core functionality. 99 // Core functionality.
86 100
87 function PromiseSet(promise, status, value, onResolve, onReject) { 101 function PromiseSet(promise, status, value, onResolve, onReject) {
88 SET_PRIVATE(promise, promiseStatusSymbol, status); 102 SET_PRIVATE(promise, promiseStateSymbol, status);
89 SET_PRIVATE(promise, promiseValueSymbol, value); 103 SET_PRIVATE(promise, promiseResultSymbol, value);
90 SET_PRIVATE(promise, promiseOnResolveSymbol, onResolve); 104 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve);
91 SET_PRIVATE(promise, promiseOnRejectSymbol, onReject); 105 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject);
92 return promise; 106 return promise;
93 } 107 }
94 108
95 function PromiseCreateAndSet(status, value) { 109 function PromiseCreateAndSet(status, value) {
96 var promise = new GlobalPromise(promiseRawSymbol); 110 var promise = new GlobalPromise(promiseRawSymbol);
97 // If debug is active, notify about the newly created promise first. 111 // If debug is active, notify about the newly created promise first.
98 if (DEBUG_IS_ACTIVE) PromiseSet(promise, 0, UNDEFINED); 112 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED);
99 return PromiseSet(promise, status, value); 113 return PromiseSet(promise, status, value);
100 } 114 }
101 115
102 function PromiseInit(promise) { 116 function PromiseInit(promise) {
103 return PromiseSet( 117 return PromiseSet(
104 promise, 0, UNDEFINED, new InternalArray, new InternalArray) 118 promise, kPending, UNDEFINED, new InternalArray, new InternalArray)
105 } 119 }
106 120
107 function PromiseDone(promise, status, value, promiseQueue) { 121 function PromiseDone(promise, status, value, promiseQueue) {
108 if (GET_PRIVATE(promise, promiseStatusSymbol) === 0) { 122 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
109 var tasks = GET_PRIVATE(promise, promiseQueue); 123 var tasks = GET_PRIVATE(promise, promiseQueue);
110 if (tasks.length) PromiseEnqueue(value, tasks, status); 124 if (tasks.length) PromiseEnqueue(value, tasks, status);
111 PromiseSet(promise, status, value); 125 PromiseSet(promise, status, value);
112 } 126 }
113 } 127 }
114 128
115 function PromiseHandle(value, handler, deferred) { 129 function PromiseHandle(value, handler, deferred) {
116 try { 130 try {
117 %DebugPushPromise(deferred.promise, PromiseHandle); 131 %DebugPushPromise(deferred.promise, PromiseHandle);
118 var result = handler(value); 132 var result = handler(value);
(...skipping 13 matching lines...) Expand all
132 } 146 }
133 for (var i = 0; i < tasks.length; i += 2) { 147 for (var i = 0; i < tasks.length; i += 2) {
134 PromiseHandle(value, tasks[i], tasks[i + 1]) 148 PromiseHandle(value, tasks[i], tasks[i + 1])
135 } 149 }
136 if (instrumenting) { 150 if (instrumenting) {
137 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); 151 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
138 } 152 }
139 }); 153 });
140 if (instrumenting) { 154 if (instrumenting) {
141 id = ++lastMicrotaskId; 155 id = ++lastMicrotaskId;
142 name = status > 0 ? "Promise.resolve" : "Promise.reject"; 156 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";
143 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); 157 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
144 } 158 }
145 } 159 }
146 160
147 function PromiseIdResolveHandler(x) { return x } 161 function PromiseIdResolveHandler(x) { return x }
148 function PromiseIdRejectHandler(r) { throw r } 162 function PromiseIdRejectHandler(r) { throw r }
149 163
150 function PromiseNopResolver() {} 164 function PromiseNopResolver() {}
151 165
152 // ------------------------------------------------------------------- 166 // -------------------------------------------------------------------
153 // Define exported functions. 167 // Define exported functions.
154 168
155 // For bootstrapper. 169 // For bootstrapper.
156 170
171 // ES#sec-ispromise IsPromise ( x )
157 function IsPromise(x) { 172 function IsPromise(x) {
158 return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStatusSymbol); 173 return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStateSymbol);
159 } 174 }
160 175
161 function PromiseCreate() { 176 function PromiseCreate() {
162 return new GlobalPromise(PromiseNopResolver) 177 return new GlobalPromise(PromiseNopResolver)
163 } 178 }
164 179
165 function PromiseResolve(promise, x) { 180 // ES#sec-fulfillpromise
181 // FulfillPromise ( promise, value)
182 function FulfillPromise(promise, x) {
166 if (x === promise) { 183 if (x === promise) {
167 return PromiseReject(promise, MakeTypeError(kPromiseCyclic, x)); 184 return RejectPromise(promise, MakeTypeError(kPromiseCyclic, x));
168 } 185 }
169 if (IS_RECEIVER(x)) { 186 if (IS_RECEIVER(x)) {
170 // 25.4.1.3.2 steps 8-12 187 // 25.4.1.3.2 steps 8-12
171 try { 188 try {
172 var then = x.then; 189 var then = x.then;
173 } catch (e) { 190 } catch (e) {
174 return PromiseReject(promise, e); 191 return RejectPromise(promise, e);
175 } 192 }
176 if (IS_CALLABLE(then)) { 193 if (IS_CALLABLE(then)) {
177 // PromiseResolveThenableJob 194 // PromiseResolveThenableJob
178 var id, name, instrumenting = DEBUG_IS_ACTIVE; 195 var id, name, instrumenting = DEBUG_IS_ACTIVE;
179 %EnqueueMicrotask(function() { 196 %EnqueueMicrotask(function() {
180 if (instrumenting) { 197 if (instrumenting) {
181 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); 198 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
182 } 199 }
183 var callbacks = CreateResolvingFunctions(promise); 200 var callbacks = CreateResolvingFunctions(promise);
184 try { 201 try {
185 %_Call(then, x, callbacks.resolve, callbacks.reject); 202 %_Call(then, x, callbacks.resolve, callbacks.reject);
186 } catch (e) { 203 } catch (e) {
187 %_Call(callbacks.reject, UNDEFINED, e); 204 %_Call(callbacks.reject, UNDEFINED, e);
188 } 205 }
189 if (instrumenting) { 206 if (instrumenting) {
190 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); 207 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
191 } 208 }
192 }); 209 });
193 if (instrumenting) { 210 if (instrumenting) {
194 id = ++lastMicrotaskId; 211 id = ++lastMicrotaskId;
195 name = "PromseResolveThenableJob"; 212 name = "PromseResolveThenableJob";
196 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); 213 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
197 } 214 }
198 return; 215 return;
199 } 216 }
200 } 217 }
201 PromiseDone(promise, +1, x, promiseOnResolveSymbol); 218 PromiseDone(promise, kFulfilled, x, promiseFulfillReactionsSymbol);
202 } 219 }
203 220
204 function PromiseReject(promise, r) { 221 // ES#sec-rejectpromise
222 // RejectPromise ( promise, reason )
223 function RejectPromise(promise, r) {
205 // Check promise status to confirm that this reject has an effect. 224 // Check promise status to confirm that this reject has an effect.
206 // Call runtime for callbacks to the debugger or for unhandled reject. 225 // Call runtime for callbacks to the debugger or for unhandled reject.
207 if (GET_PRIVATE(promise, promiseStatusSymbol) == 0) { 226 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
208 var debug_is_active = DEBUG_IS_ACTIVE; 227 var debug_is_active = DEBUG_IS_ACTIVE;
209 if (debug_is_active || 228 if (debug_is_active ||
210 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) { 229 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) {
211 %PromiseRejectEvent(promise, r, debug_is_active); 230 %PromiseRejectEvent(promise, r, debug_is_active);
212 } 231 }
213 } 232 }
214 PromiseDone(promise, -1, r, promiseOnRejectSymbol) 233 PromiseDone(promise, kRejected, r, promiseRejectReactionsSymbol)
215 } 234 }
216 235
236 // ES#sec-newpromisecapability
237 // NewPromiseCapability ( C )
217 function NewPromiseCapability(C) { 238 function NewPromiseCapability(C) {
218 if (C === GlobalPromise) { 239 if (C === GlobalPromise) {
219 // Optimized case, avoid extra closure. 240 // Optimized case, avoid extra closure.
220 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol)); 241 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol));
221 var callbacks = CreateResolvingFunctions(promise); 242 var callbacks = CreateResolvingFunctions(promise);
222 return { 243 return {
223 promise: promise, 244 promise: promise,
224 resolve: callbacks.resolve, 245 resolve: callbacks.resolve,
225 reject: callbacks.reject 246 reject: callbacks.reject
226 }; 247 };
227 } 248 }
228 249
229 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; 250 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED };
230 result.promise = new C((resolve, reject) => { 251 result.promise = new C((resolve, reject) => {
231 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) 252 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject))
232 throw MakeTypeError(kPromiseExecutorAlreadyInvoked); 253 throw MakeTypeError(kPromiseExecutorAlreadyInvoked);
233 result.resolve = resolve; 254 result.resolve = resolve;
234 result.reject = reject; 255 result.reject = reject;
235 }); 256 });
236 257
237 if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject)) 258 if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject))
238 throw MakeTypeError(kPromiseNonCallable); 259 throw MakeTypeError(kPromiseNonCallable);
239 260
240 return result; 261 return result;
241 } 262 }
242 263
243 function PromiseDeferred() { 264 // Unspecified V8-specific legacy function
265 function PromiseDefer() {
244 %IncrementUseCounter(kPromiseDefer); 266 %IncrementUseCounter(kPromiseDefer);
245 return NewPromiseCapability(this); 267 return NewPromiseCapability(this);
246 } 268 }
247 269
248 function PromiseResolved(x) { 270 // Unspecified V8-specific legacy function
271 function PromiseAccept(x) {
249 %IncrementUseCounter(kPromiseAccept); 272 %IncrementUseCounter(kPromiseAccept);
250 return %_Call(PromiseCast, this, x); 273 return %_Call(PromiseResolve, this, x);
251 } 274 }
252 275
253 function PromiseRejected(r) { 276 // ES#sec-promise.reject
277 // Promise.reject ( x )
278 function PromiseReject(r) {
254 if (!IS_RECEIVER(this)) { 279 if (!IS_RECEIVER(this)) {
255 throw MakeTypeError(kCalledOnNonObject, PromiseRejected); 280 throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
256 } 281 }
257 if (this === GlobalPromise) { 282 if (this === GlobalPromise) {
258 // Optimized case, avoid extra closure. 283 // Optimized case, avoid extra closure.
259 var promise = PromiseCreateAndSet(-1, r); 284 var promise = PromiseCreateAndSet(kRejected, r);
260 // The debug event for this would always be an uncaught promise reject, 285 // The debug event for this would always be an uncaught promise reject,
261 // which is usually simply noise. Do not trigger that debug event. 286 // which is usually simply noise. Do not trigger that debug event.
262 %PromiseRejectEvent(promise, r, false); 287 %PromiseRejectEvent(promise, r, false);
263 return promise; 288 return promise;
264 } else { 289 } else {
265 var promiseCapability = NewPromiseCapability(this); 290 var promiseCapability = NewPromiseCapability(this);
266 %_Call(promiseCapability.reject, UNDEFINED, r); 291 %_Call(promiseCapability.reject, UNDEFINED, r);
267 return promiseCapability.promise; 292 return promiseCapability.promise;
268 } 293 }
269 } 294 }
270 295
296 // ES#sec-promise.prototype.then
297 // Promise.prototype.then ( onFulfilled, onRejected )
271 // Multi-unwrapped chaining with thenable coercion. 298 // Multi-unwrapped chaining with thenable coercion.
272
273 function PromiseThen(onResolve, onReject) { 299 function PromiseThen(onResolve, onReject) {
274 var status = GET_PRIVATE(this, promiseStatusSymbol); 300 var status = GET_PRIVATE(this, promiseStateSymbol);
275 if (IS_UNDEFINED(status)) { 301 if (IS_UNDEFINED(status)) {
276 throw MakeTypeError(kNotAPromise, this); 302 throw MakeTypeError(kNotAPromise, this);
277 } 303 }
278 304
279 var constructor = SpeciesConstructor(this, GlobalPromise); 305 var constructor = SpeciesConstructor(this, GlobalPromise);
280 onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler; 306 onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler;
281 onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler; 307 onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler;
282 var deferred = NewPromiseCapability(constructor); 308 var deferred = NewPromiseCapability(constructor);
283 switch (status) { 309 switch (status) {
284 case 0: // Pending 310 case kPending:
285 GET_PRIVATE(this, promiseOnResolveSymbol).push(onResolve, deferred); 311 GET_PRIVATE(this, promiseFulfillReactionsSymbol).push(onResolve,
286 GET_PRIVATE(this, promiseOnRejectSymbol).push(onReject, deferred); 312 deferred);
313 GET_PRIVATE(this, promiseRejectReactionsSymbol).push(onReject, deferred);
287 break; 314 break;
288 case +1: // Resolved 315 case kFulfilled:
289 PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol), 316 PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
290 [onResolve, deferred], 317 [onResolve, deferred],
291 +1); 318 kFulfilled);
292 break; 319 break;
293 case -1: // Rejected 320 case kRejected:
294 if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) { 321 if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) {
295 // Promise has already been rejected, but had no handler. 322 // Promise has already been rejected, but had no handler.
296 // Revoke previously triggered reject event. 323 // Revoke previously triggered reject event.
297 %PromiseRevokeReject(this); 324 %PromiseRevokeReject(this);
298 } 325 }
299 PromiseEnqueue(GET_PRIVATE(this, promiseValueSymbol), 326 PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
300 [onReject, deferred], 327 [onReject, deferred],
301 -1); 328 kRejected);
302 break; 329 break;
303 } 330 }
304 // Mark this promise as having handler. 331 // Mark this promise as having handler.
305 SET_PRIVATE(this, promiseHasHandlerSymbol, true); 332 SET_PRIVATE(this, promiseHasHandlerSymbol, true);
306 return deferred.promise; 333 return deferred.promise;
307 } 334 }
308 335
336 // Unspecified V8-specific legacy function
309 // Chain is left around for now as an alias for then 337 // Chain is left around for now as an alias for then
310 function PromiseChain(onResolve, onReject) { 338 function PromiseChain(onResolve, onReject) {
311 %IncrementUseCounter(kPromiseChain); 339 %IncrementUseCounter(kPromiseChain);
312 return %_Call(PromiseThen, this, onResolve, onReject); 340 return %_Call(PromiseThen, this, onResolve, onReject);
313 } 341 }
314 342
343 // ES#sec-promise.prototype.catch
344 // Promise.prototype.catch ( onRejected )
315 function PromiseCatch(onReject) { 345 function PromiseCatch(onReject) {
316 return this.then(UNDEFINED, onReject); 346 return this.then(UNDEFINED, onReject);
317 } 347 }
318 348
319 // Combinators. 349 // Combinators.
320 350
321 function PromiseCast(x) { 351 // ES#sec-promise.resolve
352 // Promise.resolve ( x )
353 function PromiseResolve(x) {
322 if (!IS_RECEIVER(this)) { 354 if (!IS_RECEIVER(this)) {
323 throw MakeTypeError(kCalledOnNonObject, PromiseCast); 355 throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
324 } 356 }
325 if (IsPromise(x) && x.constructor === this) return x; 357 if (IsPromise(x) && x.constructor === this) return x;
326 358
327 var promiseCapability = NewPromiseCapability(this); 359 var promiseCapability = NewPromiseCapability(this);
328 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x); 360 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x);
329 return promiseCapability.promise; 361 return promiseCapability.promise;
330 } 362 }
331 363
364 // ES#sec-promise.all
365 // Promise.all ( iterable )
332 function PromiseAll(iterable) { 366 function PromiseAll(iterable) {
333 if (!IS_RECEIVER(this)) { 367 if (!IS_RECEIVER(this)) {
334 throw MakeTypeError(kCalledOnNonObject, "Promise.all"); 368 throw MakeTypeError(kCalledOnNonObject, "Promise.all");
335 } 369 }
336 370
337 var deferred = NewPromiseCapability(this); 371 var deferred = NewPromiseCapability(this);
338 var resolutions = new InternalArray(); 372 var resolutions = new InternalArray();
339 var count; 373 var count;
340 374
341 function CreateResolveElementFunction(index, values, promiseCapability) { 375 function CreateResolveElementFunction(index, values, promiseCapability) {
(...skipping 29 matching lines...) Expand all
371 %MoveArrayContents(resolutions, valuesArray); 405 %MoveArrayContents(resolutions, valuesArray);
372 %_Call(deferred.resolve, UNDEFINED, valuesArray); 406 %_Call(deferred.resolve, UNDEFINED, valuesArray);
373 } 407 }
374 408
375 } catch (e) { 409 } catch (e) {
376 %_Call(deferred.reject, UNDEFINED, e); 410 %_Call(deferred.reject, UNDEFINED, e);
377 } 411 }
378 return deferred.promise; 412 return deferred.promise;
379 } 413 }
380 414
415 // ES#sec-promise.race
416 // Promise.race ( iterable )
381 function PromiseRace(iterable) { 417 function PromiseRace(iterable) {
382 if (!IS_RECEIVER(this)) { 418 if (!IS_RECEIVER(this)) {
383 throw MakeTypeError(kCalledOnNonObject, PromiseRace); 419 throw MakeTypeError(kCalledOnNonObject, PromiseRace);
384 } 420 }
385 421
386 var deferred = NewPromiseCapability(this); 422 var deferred = NewPromiseCapability(this);
387 try { 423 try {
388 for (var value of iterable) { 424 for (var value of iterable) {
389 this.resolve(value).then(deferred.resolve, deferred.reject); 425 this.resolve(value).then(deferred.resolve, deferred.reject);
390 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred); 426 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
391 } 427 }
392 } catch (e) { 428 } catch (e) {
393 deferred.reject(e) 429 deferred.reject(e)
394 } 430 }
395 return deferred.promise; 431 return deferred.promise;
396 } 432 }
397 433
398 434
399 // Utility for debugger 435 // Utility for debugger
400 436
401 function PromiseHasUserDefinedRejectHandlerRecursive(promise) { 437 function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
402 var queue = GET_PRIVATE(promise, promiseOnRejectSymbol); 438 var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol);
403 if (IS_UNDEFINED(queue)) return false; 439 if (IS_UNDEFINED(queue)) return false;
404 for (var i = 0; i < queue.length; i += 2) { 440 for (var i = 0; i < queue.length; i += 2) {
405 var handler = queue[i]; 441 var handler = queue[i];
406 if (handler !== PromiseIdRejectHandler) { 442 if (handler !== PromiseIdRejectHandler) {
407 var deferred = GET_PRIVATE(handler, promiseCombinedDeferredSymbol); 443 var deferred = GET_PRIVATE(handler, promiseCombinedDeferredSymbol);
408 if (IS_UNDEFINED(deferred)) return true; 444 if (IS_UNDEFINED(deferred)) return true;
409 if (PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise)) { 445 if (PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise)) {
410 return true; 446 return true;
411 } 447 }
412 } else if (PromiseHasUserDefinedRejectHandlerRecursive( 448 } else if (PromiseHasUserDefinedRejectHandlerRecursive(
(...skipping 12 matching lines...) Expand all
425 }; 461 };
426 462
427 // ------------------------------------------------------------------- 463 // -------------------------------------------------------------------
428 // Install exported functions. 464 // Install exported functions.
429 465
430 %AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM); 466 %AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM);
431 %AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise", 467 %AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise",
432 DONT_ENUM | READ_ONLY); 468 DONT_ENUM | READ_ONLY);
433 469
434 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [ 470 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
435 "reject", PromiseRejected, 471 "reject", PromiseReject,
436 "all", PromiseAll, 472 "all", PromiseAll,
437 "race", PromiseRace, 473 "race", PromiseRace,
438 "resolve", PromiseCast 474 "resolve", PromiseResolve
439 ]); 475 ]);
440 476
441 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [ 477 utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
442 "then", PromiseThen, 478 "then", PromiseThen,
443 "catch", PromiseCatch 479 "catch", PromiseCatch
444 ]); 480 ]);
445 481
446 %InstallToContext([ 482 %InstallToContext([
447 "promise_catch", PromiseCatch, 483 "promise_catch", PromiseCatch,
448 "promise_chain", PromiseChain, 484 "promise_chain", PromiseChain,
449 "promise_create", PromiseCreate, 485 "promise_create", PromiseCreate,
450 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, 486 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler,
451 "promise_reject", PromiseReject, 487 "promise_reject", RejectPromise,
452 "promise_resolve", PromiseResolve, 488 "promise_resolve", FulfillPromise,
453 "promise_then", PromiseThen, 489 "promise_then", PromiseThen,
454 ]); 490 ]);
455 491
456 // This allows extras to create promises quickly without building extra 492 // This allows extras to create promises quickly without building extra
457 // resolve/reject closures, and allows them to later resolve and reject any 493 // resolve/reject closures, and allows them to later resolve and reject any
458 // promise without having to hold on to those closures forever. 494 // promise without having to hold on to those closures forever.
459 utils.InstallFunctions(extrasUtils, 0, [ 495 utils.InstallFunctions(extrasUtils, 0, [
460 "createPromise", PromiseCreate, 496 "createPromise", PromiseCreate,
461 "resolvePromise", PromiseResolve, 497 "resolvePromise", FulfillPromise,
462 "rejectPromise", PromiseReject 498 "rejectPromise", RejectPromise
463 ]); 499 ]);
464 500
465 // TODO(v8:4567): Allow experimental natives to remove function prototype 501 // TODO(v8:4567): Allow experimental natives to remove function prototype
466 [PromiseChain, PromiseDeferred, PromiseResolved].forEach( 502 [PromiseChain, PromiseDefer, PromiseAccept].forEach(
467 fn => %FunctionRemovePrototype(fn)); 503 fn => %FunctionRemovePrototype(fn));
468 504
469 utils.Export(function(to) { 505 utils.Export(function(to) {
470 to.PromiseChain = PromiseChain; 506 to.PromiseChain = PromiseChain;
471 to.PromiseDeferred = PromiseDeferred; 507 to.PromiseDefer = PromiseDefer;
472 to.PromiseResolved = PromiseResolved; 508 to.PromiseAccept = PromiseAccept;
473 }); 509 });
474 510
475 }) 511 })
OLDNEW
« no previous file with comments | « src/js/prologue.js ('k') | src/js/promise-extra.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698