| 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 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 // a new callback -- | 108 // a new callback -- |
| 109 // 1) UNDEFINED -- This is the zero state where there is no callback | 109 // 1) UNDEFINED -- This is the zero state where there is no callback |
| 110 // registered. When we see this state, we directly attach the callbacks to | 110 // registered. When we see this state, we directly attach the callbacks to |
| 111 // the symbol. | 111 // the symbol. |
| 112 // 2) !IS_ARRAY -- There is a single callback directly attached to the | 112 // 2) !IS_ARRAY -- There is a single callback directly attached to the |
| 113 // symbols. We need to create a new array to store additional callbacks. | 113 // symbols. We need to create a new array to store additional callbacks. |
| 114 // 3) IS_ARRAY -- There are multiple callbacks already registered, | 114 // 3) IS_ARRAY -- There are multiple callbacks already registered, |
| 115 // therefore we can just push the new callback to the existing array. | 115 // therefore we can just push the new callback to the existing array. |
| 116 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, UNDEFINED); | 116 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, UNDEFINED); |
| 117 SET_PRIVATE(promise, promiseRejectReactionsSymbol, UNDEFINED); | 117 SET_PRIVATE(promise, promiseRejectReactionsSymbol, UNDEFINED); |
| 118 |
| 119 // There are 2 possible states for this symbol -- |
| 120 // 1) UNDEFINED -- This is the zero state, no deferred object is |
| 121 // attached to this symbol. When we want to add a new deferred we |
| 122 // directly attach it to this symbol. |
| 123 // 2) symbol with attached deferred object -- New deferred objects |
| 124 // are not attached to this symbol, but instead they are directly |
| 125 // attached to the resolve, reject callback arrays. At this point, |
| 126 // the deferred symbol's state is stale, and the deferreds should be |
| 127 // read from the reject, resolve callbacks. |
| 118 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, UNDEFINED); | 128 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, UNDEFINED); |
| 129 |
| 119 return promise; | 130 return promise; |
| 120 } | 131 } |
| 121 | 132 |
| 122 function PromiseCreateAndSet(status, value) { | 133 function PromiseCreateAndSet(status, value) { |
| 123 var promise = new GlobalPromise(promiseRawSymbol); | 134 var promise = new GlobalPromise(promiseRawSymbol); |
| 124 // If debug is active, notify about the newly created promise first. | 135 // If debug is active, notify about the newly created promise first. |
| 125 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED); | 136 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED); |
| 126 return PromiseSet(promise, status, value); | 137 return PromiseSet(promise, status, value); |
| 127 } | 138 } |
| 128 | 139 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 156 } | 167 } |
| 157 } | 168 } |
| 158 | 169 |
| 159 function PromiseEnqueue(value, tasks, deferreds, status) { | 170 function PromiseEnqueue(value, tasks, deferreds, status) { |
| 160 var id, name, instrumenting = DEBUG_IS_ACTIVE; | 171 var id, name, instrumenting = DEBUG_IS_ACTIVE; |
| 161 %EnqueueMicrotask(function() { | 172 %EnqueueMicrotask(function() { |
| 162 if (instrumenting) { | 173 if (instrumenting) { |
| 163 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); | 174 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); |
| 164 } | 175 } |
| 165 if (IS_ARRAY(tasks)) { | 176 if (IS_ARRAY(tasks)) { |
| 166 for (var i = 0; i < tasks.length; i += 1) { | 177 for (var i = 0; i < tasks.length; i += 2) { |
| 167 PromiseHandle(value, tasks[i], deferreds[i]); | 178 PromiseHandle(value, tasks[i], tasks[i + 1]); |
| 168 } | 179 } |
| 169 } else { | 180 } else { |
| 170 PromiseHandle(value, tasks, deferreds); | 181 PromiseHandle(value, tasks, deferreds); |
| 171 } | 182 } |
| 172 if (instrumenting) { | 183 if (instrumenting) { |
| 173 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); | 184 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name }); |
| 174 } | 185 } |
| 175 }); | 186 }); |
| 176 if (instrumenting) { | 187 if (instrumenting) { |
| 177 id = ++lastMicrotaskId; | 188 id = ++lastMicrotaskId; |
| 178 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; | 189 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject"; |
| 179 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); | 190 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name }); |
| 180 } | 191 } |
| 181 } | 192 } |
| 182 | 193 |
| 183 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { | 194 function PromiseAttachCallbacks(promise, deferred, onResolve, onReject) { |
| 184 var maybeResolveCallbacks = | 195 var maybeResolveCallbacks = |
| 185 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); | 196 GET_PRIVATE(promise, promiseFulfillReactionsSymbol); |
| 186 if (IS_UNDEFINED(maybeResolveCallbacks)) { | 197 if (IS_UNDEFINED(maybeResolveCallbacks)) { |
| 187 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); | 198 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve); |
| 188 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); | 199 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject); |
| 189 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferred); | 200 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferred); |
| 190 } else if (!IS_ARRAY(maybeResolveCallbacks)) { | 201 } else if (!IS_ARRAY(maybeResolveCallbacks)) { |
| 191 var resolveCallbacks = new InternalArray(); | 202 var resolveCallbacks = new InternalArray(); |
| 192 var rejectCallbacks = new InternalArray(); | 203 var rejectCallbacks = new InternalArray(); |
| 193 var deferreds = new InternalArray(); | 204 var existingDeferred = GET_PRIVATE(promise, promiseDeferredReactionsSymbol); |
| 194 | 205 |
| 195 resolveCallbacks.push(maybeResolveCallbacks); | 206 resolveCallbacks.push( |
| 196 rejectCallbacks.push(GET_PRIVATE(promise, promiseRejectReactionsSymbol)); | 207 maybeResolveCallbacks, existingDeferred, onResolve, deferred); |
| 197 deferreds.push(GET_PRIVATE(promise, promiseDeferredReactionsSymbol)); | 208 rejectCallbacks.push(GET_PRIVATE(promise, promiseRejectReactionsSymbol), |
| 198 | 209 existingDeferred, |
| 199 resolveCallbacks.push(onResolve); | 210 onReject, |
| 200 rejectCallbacks.push(onReject); | 211 deferred); |
| 201 deferreds.push(deferred); | |
| 202 | 212 |
| 203 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, resolveCallbacks); | 213 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, resolveCallbacks); |
| 204 SET_PRIVATE(promise, promiseRejectReactionsSymbol, rejectCallbacks); | 214 SET_PRIVATE(promise, promiseRejectReactionsSymbol, rejectCallbacks); |
| 205 SET_PRIVATE(promise, promiseDeferredReactionsSymbol, deferreds); | |
| 206 } else { | 215 } else { |
| 207 maybeResolveCallbacks.push(onResolve); | 216 maybeResolveCallbacks.push(onResolve, deferred); |
| 208 GET_PRIVATE(promise, promiseRejectReactionsSymbol).push(onReject); | 217 GET_PRIVATE(promise, promiseRejectReactionsSymbol).push(onReject, deferred); |
| 209 GET_PRIVATE(promise, promiseDeferredReactionsSymbol).push(deferred); | |
| 210 } | 218 } |
| 211 } | 219 } |
| 212 | 220 |
| 213 function PromiseIdResolveHandler(x) { return x } | 221 function PromiseIdResolveHandler(x) { return x } |
| 214 function PromiseIdRejectHandler(r) { throw r } | 222 function PromiseIdRejectHandler(r) { throw r } |
| 215 | 223 |
| 216 function PromiseNopResolver() {} | 224 function PromiseNopResolver() {} |
| 217 | 225 |
| 218 // ------------------------------------------------------------------- | 226 // ------------------------------------------------------------------- |
| 219 // Define exported functions. | 227 // Define exported functions. |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 return false; | 513 return false; |
| 506 } | 514 } |
| 507 | 515 |
| 508 function PromiseHasUserDefinedRejectHandlerRecursive(promise) { | 516 function PromiseHasUserDefinedRejectHandlerRecursive(promise) { |
| 509 var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol); | 517 var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol); |
| 510 var deferreds = GET_PRIVATE(promise, promiseDeferredReactionsSymbol); | 518 var deferreds = GET_PRIVATE(promise, promiseDeferredReactionsSymbol); |
| 511 if (IS_UNDEFINED(queue)) return false; | 519 if (IS_UNDEFINED(queue)) return false; |
| 512 if (!IS_ARRAY(queue)) { | 520 if (!IS_ARRAY(queue)) { |
| 513 return PromiseHasUserDefinedRejectHandlerCheck(queue, deferreds); | 521 return PromiseHasUserDefinedRejectHandlerCheck(queue, deferreds); |
| 514 } else { | 522 } else { |
| 515 for (var i = 0; i < queue.length; i += 1) { | 523 for (var i = 0; i < queue.length; i += 2) { |
| 516 if (PromiseHasUserDefinedRejectHandlerCheck(queue[i], deferreds[i])) { | 524 if (PromiseHasUserDefinedRejectHandlerCheck(queue[i], queue[i + 1])) { |
| 517 return true; | 525 return true; |
| 518 } | 526 } |
| 519 } | 527 } |
| 520 } | 528 } |
| 521 return false; | 529 return false; |
| 522 } | 530 } |
| 523 | 531 |
| 524 // Return whether the promise will be handled by a user-defined reject | 532 // Return whether the promise will be handled by a user-defined reject |
| 525 // handler somewhere down the promise chain. For this, we do a depth-first | 533 // handler somewhere down the promise chain. For this, we do a depth-first |
| 526 // search for a reject handler that's not the default PromiseIdRejectHandler. | 534 // search for a reject handler that's not the default PromiseIdRejectHandler. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 to.PromiseChain = PromiseChain; | 584 to.PromiseChain = PromiseChain; |
| 577 to.PromiseDefer = PromiseDefer; | 585 to.PromiseDefer = PromiseDefer; |
| 578 to.PromiseAccept = PromiseAccept; | 586 to.PromiseAccept = PromiseAccept; |
| 579 | 587 |
| 580 to.PromiseCreateRejected = PromiseCreateRejected; | 588 to.PromiseCreateRejected = PromiseCreateRejected; |
| 581 to.PromiseCreateResolved = PromiseCreateResolved; | 589 to.PromiseCreateResolved = PromiseCreateResolved; |
| 582 to.PromiseThen = PromiseThen; | 590 to.PromiseThen = PromiseThen; |
| 583 }); | 591 }); |
| 584 | 592 |
| 585 }) | 593 }) |
| OLD | NEW |