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 promiseCombinedDeferredSymbol = | |
16 utils.ImportNow("promise_combined_deferred_symbol"); | |
15 var promiseHasHandlerSymbol = | 17 var promiseHasHandlerSymbol = |
16 utils.ImportNow("promise_has_handler_symbol"); | 18 utils.ImportNow("promise_has_handler_symbol"); |
17 var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol"); | 19 var promiseOnRejectSymbol = utils.ImportNow("promise_on_reject_symbol"); |
18 var promiseOnResolveSymbol = | 20 var promiseOnResolveSymbol = |
19 utils.ImportNow("promise_on_resolve_symbol"); | 21 utils.ImportNow("promise_on_resolve_symbol"); |
20 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); | 22 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); |
21 var promiseStatusSymbol = utils.ImportNow("promise_status_symbol"); | 23 var promiseStatusSymbol = utils.ImportNow("promise_status_symbol"); |
22 var promiseValueSymbol = utils.ImportNow("promise_value_symbol"); | 24 var promiseValueSymbol = utils.ImportNow("promise_value_symbol"); |
23 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); | 25 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); |
24 | 26 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 } | 293 } |
292 } | 294 } |
293 | 295 |
294 function PromiseAll(iterable) { | 296 function PromiseAll(iterable) { |
295 var deferred = %_CallFunction(this, PromiseDeferred); | 297 var deferred = %_CallFunction(this, PromiseDeferred); |
296 var resolutions = []; | 298 var resolutions = []; |
297 try { | 299 try { |
298 var count = 0; | 300 var count = 0; |
299 var i = 0; | 301 var i = 0; |
300 for (var value of iterable) { | 302 for (var value of iterable) { |
301 this.resolve(value).then( | 303 var promise = this.resolve(value).then( |
302 // Nested scope to get closure over current i. | 304 // Nested scope to get closure over current i. |
303 // TODO(arv): Use an inner let binding once available. | 305 // TODO(arv): Use an inner let binding once available. |
304 (function(i) { | 306 (function(i) { |
305 return function(x) { | 307 return function(x) { |
306 resolutions[i] = x; | 308 resolutions[i] = x; |
307 if (--count === 0) deferred.resolve(resolutions); | 309 if (--count === 0) deferred.resolve(resolutions); |
308 } | 310 } |
309 })(i), | 311 })(i), |
310 function(r) { deferred.reject(r); }); | 312 function(r) { deferred.reject(r); }); |
313 SET_PRIVATE(promise, promiseCombinedDeferredSymbol, deferred); | |
311 ++i; | 314 ++i; |
312 ++count; | 315 ++count; |
313 } | 316 } |
314 | 317 |
315 if (count === 0) { | 318 if (count === 0) { |
316 deferred.resolve(resolutions); | 319 deferred.resolve(resolutions); |
317 } | 320 } |
318 | 321 |
319 } catch (e) { | 322 } catch (e) { |
320 deferred.reject(e) | 323 deferred.reject(e) |
321 } | 324 } |
322 return deferred.promise; | 325 return deferred.promise; |
323 } | 326 } |
324 | 327 |
325 function PromiseRace(iterable) { | 328 function PromiseRace(iterable) { |
326 var deferred = %_CallFunction(this, PromiseDeferred); | 329 var deferred = %_CallFunction(this, PromiseDeferred); |
327 try { | 330 try { |
328 for (var value of iterable) { | 331 for (var value of iterable) { |
329 this.resolve(value).then( | 332 var promise = this.resolve(value).then( |
330 function(x) { deferred.resolve(x) }, | 333 function(x) { deferred.resolve(x) }, |
331 function(r) { deferred.reject(r) }); | 334 function(r) { deferred.reject(r) }); |
335 SET_PRIVATE(promise, promiseCombinedDeferredSymbol, deferred); | |
332 } | 336 } |
333 } catch (e) { | 337 } catch (e) { |
334 deferred.reject(e) | 338 deferred.reject(e) |
335 } | 339 } |
336 return deferred.promise; | 340 return deferred.promise; |
337 } | 341 } |
338 | 342 |
339 | 343 |
340 // Utility for debugger | 344 // Utility for debugger |
341 | 345 |
342 function PromiseHasUserDefinedRejectHandlerRecursive(promise) { | 346 function PromiseHasUserDefinedRejectHandlerRecursive(promise) { |
343 var queue = GET_PRIVATE(promise, promiseOnRejectSymbol); | 347 var queue = GET_PRIVATE(promise, promiseOnRejectSymbol); |
344 if (IS_UNDEFINED(queue)) return false; | 348 if (IS_UNDEFINED(queue)) return false; |
345 for (var i = 0; i < queue.length; i += 2) { | 349 for (var i = 0; i < queue.length; i += 2) { |
346 if (queue[i] != PromiseIdRejectHandler) return true; | 350 var handler = queue[i]; |
347 if (PromiseHasUserDefinedRejectHandlerRecursive(queue[i + 1].promise)) { | 351 var promise = queue[i + 1].promise; |
352 if (handler !== PromiseIdRejectHandler) { | |
353 var deferred = GET_PRIVATE(promise, promiseCombinedDeferredSymbol); | |
354 if (IS_UNDEFINED(deferred)) return true; | |
355 if (PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise)) { | |
rossberg
2015/10/19 14:24:29
Why the extra conditional and not a tail call?
re
Yang
2015/10/19 16:24:09
A promise is considered to have a reject handler i
| |
356 return true; | |
357 } | |
358 } else if (PromiseHasUserDefinedRejectHandlerRecursive(promise)) { | |
348 return true; | 359 return true; |
349 } | 360 } |
350 } | 361 } |
351 return false; | 362 return false; |
352 } | 363 } |
353 | 364 |
354 // Return whether the promise will be handled by a user-defined reject | 365 // Return whether the promise will be handled by a user-defined reject |
355 // handler somewhere down the promise chain. For this, we do a depth-first | 366 // handler somewhere down the promise chain. For this, we do a depth-first |
356 // search for a reject handler that's not the default PromiseIdRejectHandler. | 367 // search for a reject handler that's not the default PromiseIdRejectHandler. |
357 function PromiseHasUserDefinedRejectHandler() { | 368 function PromiseHasUserDefinedRejectHandler() { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 // This allows extras to create promises quickly without building extra | 404 // This allows extras to create promises quickly without building extra |
394 // resolve/reject closures, and allows them to later resolve and reject any | 405 // resolve/reject closures, and allows them to later resolve and reject any |
395 // promise without having to hold on to those closures forever. | 406 // promise without having to hold on to those closures forever. |
396 utils.InstallFunctions(extrasUtils, 0, [ | 407 utils.InstallFunctions(extrasUtils, 0, [ |
397 "createPromise", PromiseCreate, | 408 "createPromise", PromiseCreate, |
398 "resolvePromise", PromiseResolve, | 409 "resolvePromise", PromiseResolve, |
399 "rejectPromise", PromiseReject | 410 "rejectPromise", PromiseReject |
400 ]); | 411 ]); |
401 | 412 |
402 }) | 413 }) |
OLD | NEW |