• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3// found in the LICENSE file.
4
5(function(global, utils, extrasUtils) {
6
7"use strict";
8
9%CheckIsBootstrapping();
10
11// -------------------------------------------------------------------
12// Imports
13
14var InternalArray = utils.InternalArray;
15var promiseHandledBySymbol =
16    utils.ImportNow("promise_handled_by_symbol");
17var promiseForwardingHandlerSymbol =
18    utils.ImportNow("promise_forwarding_handler_symbol");
19var GlobalPromise = global.Promise;
20
21// -------------------------------------------------------------------
22// Define exported functions.
23
24// Combinators.
25
26// ES#sec-promise.all
27// Promise.all ( iterable )
28function PromiseAll(iterable) {
29  if (!IS_RECEIVER(this)) {
30    throw %make_type_error(kCalledOnNonObject, "Promise.all");
31  }
32
33  // false debugEvent so that forwarding the rejection through all does not
34  // trigger redundant ExceptionEvents
35  var deferred = %new_promise_capability(this, false);
36  var resolutions = new InternalArray();
37  var count;
38
39  // For catch prediction, don't treat the .then calls as handling it;
40  // instead, recurse outwards.
41  var instrumenting = DEBUG_IS_ACTIVE;
42  if (instrumenting) {
43    SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true);
44  }
45
46  function CreateResolveElementFunction(index, values, promiseCapability) {
47    var alreadyCalled = false;
48    return (x) => {
49      if (alreadyCalled === true) return;
50      alreadyCalled = true;
51      values[index] = x;
52      if (--count === 0) {
53        var valuesArray = [];
54        %MoveArrayContents(values, valuesArray);
55        %_Call(promiseCapability.resolve, UNDEFINED, valuesArray);
56      }
57    };
58  }
59
60  try {
61    var i = 0;
62    count = 1;
63    for (var value of iterable) {
64      var nextPromise = this.resolve(value);
65      ++count;
66      var throwawayPromise = nextPromise.then(
67          CreateResolveElementFunction(i, resolutions, deferred),
68          deferred.reject);
69      // For catch prediction, mark that rejections here are semantically
70      // handled by the combined Promise.
71      if (instrumenting && %is_promise(throwawayPromise)) {
72        SET_PRIVATE(throwawayPromise, promiseHandledBySymbol, deferred.promise);
73      }
74      ++i;
75    }
76
77    // 6.d
78    if (--count === 0) {
79      var valuesArray = [];
80      %MoveArrayContents(resolutions, valuesArray);
81      %_Call(deferred.resolve, UNDEFINED, valuesArray);
82    }
83
84  } catch (e) {
85    %_Call(deferred.reject, UNDEFINED, e);
86  }
87  return deferred.promise;
88}
89
90// ES#sec-promise.race
91// Promise.race ( iterable )
92function PromiseRace(iterable) {
93  if (!IS_RECEIVER(this)) {
94    throw %make_type_error(kCalledOnNonObject, PromiseRace);
95  }
96
97  // false debugEvent so that forwarding the rejection through race does not
98  // trigger redundant ExceptionEvents
99  var deferred = %new_promise_capability(this, false);
100
101  // For catch prediction, don't treat the .then calls as handling it;
102  // instead, recurse outwards.
103  var instrumenting = DEBUG_IS_ACTIVE;
104  if (instrumenting) {
105    SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true);
106  }
107
108  try {
109    for (var value of iterable) {
110      var throwawayPromise = this.resolve(value).then(deferred.resolve,
111                                                      deferred.reject);
112      // For catch prediction, mark that rejections here are semantically
113      // handled by the combined Promise.
114      if (instrumenting && %is_promise(throwawayPromise)) {
115        SET_PRIVATE(throwawayPromise, promiseHandledBySymbol, deferred.promise);
116      }
117    }
118  } catch (e) {
119    %_Call(deferred.reject, UNDEFINED, e);
120  }
121  return deferred.promise;
122}
123
124// -------------------------------------------------------------------
125// Install exported functions.
126
127utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
128  "all", PromiseAll,
129  "race", PromiseRace,
130]);
131
132})
133