| 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 // Only used by async-await.js | 82 // Only used by async-await.js |
| 83 function RejectPromise(promise, reason, debugEvent) { | 83 function RejectPromise(promise, reason, debugEvent) { |
| 84 %PromiseReject(promise, reason, debugEvent); | 84 %PromiseReject(promise, reason, debugEvent); |
| 85 } | 85 } |
| 86 | 86 |
| 87 // Export to bindings | 87 // Export to bindings |
| 88 function DoRejectPromise(promise, reason) { | 88 function DoRejectPromise(promise, reason) { |
| 89 %PromiseReject(promise, reason, true); | 89 %PromiseReject(promise, reason, true); |
| 90 } | 90 } |
| 91 | 91 |
| 92 // The resultCapability.promise is only ever fulfilled internally, | |
| 93 // so we don't need the closures to protect against accidentally | |
| 94 // calling them multiple times. | |
| 95 function CreateInternalPromiseCapability(parent) { | |
| 96 return { | |
| 97 promise: %promise_internal_constructor(parent), | |
| 98 resolve: UNDEFINED, | |
| 99 reject: UNDEFINED | |
| 100 }; | |
| 101 } | |
| 102 | |
| 103 // ES#sec-newpromisecapability | |
| 104 // NewPromiseCapability ( C ) | |
| 105 function NewPromiseCapability(C, debugEvent) { | |
| 106 if (C === GlobalPromise) { | |
| 107 // Optimized case, avoid extra closure. | |
| 108 var promise = %promise_internal_constructor(UNDEFINED); | |
| 109 // TODO(gsathya): Remove container for callbacks when this is | |
| 110 // moved to CPP/TF. | |
| 111 var callbacks = %create_resolving_functions(promise, debugEvent); | |
| 112 return { | |
| 113 promise: promise, | |
| 114 resolve: callbacks[kResolveCallback], | |
| 115 reject: callbacks[kRejectCallback] | |
| 116 }; | |
| 117 } | |
| 118 | |
| 119 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; | |
| 120 result.promise = new C((resolve, reject) => { | |
| 121 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) | |
| 122 throw %make_type_error(kPromiseExecutorAlreadyInvoked); | |
| 123 result.resolve = resolve; | |
| 124 result.reject = reject; | |
| 125 }); | |
| 126 | |
| 127 if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject)) | |
| 128 throw %make_type_error(kPromiseNonCallable); | |
| 129 | |
| 130 return result; | |
| 131 } | |
| 132 | |
| 133 // ES#sec-promise.reject | 92 // ES#sec-promise.reject |
| 134 // Promise.reject ( x ) | 93 // Promise.reject ( x ) |
| 135 function PromiseReject(r) { | 94 function PromiseReject(r) { |
| 136 if (!IS_RECEIVER(this)) { | 95 if (!IS_RECEIVER(this)) { |
| 137 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 96 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
| 138 } | 97 } |
| 139 if (this === GlobalPromise) { | 98 if (this === GlobalPromise) { |
| 140 // Optimized case, avoid extra closure. | 99 // Optimized case, avoid extra closure. |
| 141 var promise = %promise_create_and_set(kRejected, r); | 100 var promise = %promise_create_and_set(kRejected, r); |
| 142 // Trigger debug events if the debugger is on, as Promise.reject is | 101 // Trigger debug events if the debugger is on, as Promise.reject is |
| 143 // equivalent to throwing an exception directly. | 102 // equivalent to throwing an exception directly. |
| 144 %PromiseRejectEventFromStack(promise, r); | 103 %PromiseRejectEventFromStack(promise, r); |
| 145 return promise; | 104 return promise; |
| 146 } else { | 105 } else { |
| 147 var promiseCapability = NewPromiseCapability(this, true); | 106 var promiseCapability = %new_promise_capability(this, true); |
| 148 %_Call(promiseCapability.reject, UNDEFINED, r); | 107 %_Call(promiseCapability.reject, UNDEFINED, r); |
| 149 return promiseCapability.promise; | 108 return promiseCapability.promise; |
| 150 } | 109 } |
| 151 } | 110 } |
| 152 | 111 |
| 153 // ES#sec-promise.prototype.catch | 112 // ES#sec-promise.prototype.catch |
| 154 // Promise.prototype.catch ( onRejected ) | 113 // Promise.prototype.catch ( onRejected ) |
| 155 function PromiseCatch(onReject) { | 114 function PromiseCatch(onReject) { |
| 156 return this.then(UNDEFINED, onReject); | 115 return this.then(UNDEFINED, onReject); |
| 157 } | 116 } |
| 158 | 117 |
| 159 // Combinators. | 118 // Combinators. |
| 160 | 119 |
| 161 // ES#sec-promise.resolve | 120 // ES#sec-promise.resolve |
| 162 // Promise.resolve ( x ) | 121 // Promise.resolve ( x ) |
| 163 function PromiseResolve(x) { | 122 function PromiseResolve(x) { |
| 164 if (!IS_RECEIVER(this)) { | 123 if (!IS_RECEIVER(this)) { |
| 165 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 124 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
| 166 } | 125 } |
| 167 if (%is_promise(x) && x.constructor === this) return x; | 126 if (%is_promise(x) && x.constructor === this) return x; |
| 168 | 127 |
| 169 // Avoid creating resolving functions. | 128 // Avoid creating resolving functions. |
| 170 if (this === GlobalPromise) { | 129 if (this === GlobalPromise) { |
| 171 var promise = %promise_internal_constructor(UNDEFINED); | 130 var promise = %promise_internal_constructor(UNDEFINED); |
| 172 %promise_resolve(promise, x); | 131 %promise_resolve(promise, x); |
| 173 return promise; | 132 return promise; |
| 174 } | 133 } |
| 175 | 134 |
| 176 // debugEvent is not so meaningful here as it will be resolved | 135 // debugEvent is not so meaningful here as it will be resolved |
| 177 var promiseCapability = NewPromiseCapability(this, true); | 136 var promiseCapability = %new_promise_capability(this, true); |
| 178 %_Call(promiseCapability.resolve, UNDEFINED, x); | 137 %_Call(promiseCapability.resolve, UNDEFINED, x); |
| 179 return promiseCapability.promise; | 138 return promiseCapability.promise; |
| 180 } | 139 } |
| 181 | 140 |
| 182 // ES#sec-promise.all | 141 // ES#sec-promise.all |
| 183 // Promise.all ( iterable ) | 142 // Promise.all ( iterable ) |
| 184 function PromiseAll(iterable) { | 143 function PromiseAll(iterable) { |
| 185 if (!IS_RECEIVER(this)) { | 144 if (!IS_RECEIVER(this)) { |
| 186 throw %make_type_error(kCalledOnNonObject, "Promise.all"); | 145 throw %make_type_error(kCalledOnNonObject, "Promise.all"); |
| 187 } | 146 } |
| 188 | 147 |
| 189 // false debugEvent so that forwarding the rejection through all does not | 148 // false debugEvent so that forwarding the rejection through all does not |
| 190 // trigger redundant ExceptionEvents | 149 // trigger redundant ExceptionEvents |
| 191 var deferred = NewPromiseCapability(this, false); | 150 var deferred = %new_promise_capability(this, false); |
| 192 var resolutions = new InternalArray(); | 151 var resolutions = new InternalArray(); |
| 193 var count; | 152 var count; |
| 194 | 153 |
| 195 // For catch prediction, don't treat the .then calls as handling it; | 154 // For catch prediction, don't treat the .then calls as handling it; |
| 196 // instead, recurse outwards. | 155 // instead, recurse outwards. |
| 197 var instrumenting = DEBUG_IS_ACTIVE; | 156 var instrumenting = DEBUG_IS_ACTIVE; |
| 198 if (instrumenting) { | 157 if (instrumenting) { |
| 199 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 158 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
| 200 } | 159 } |
| 201 | 160 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 204 |
| 246 // ES#sec-promise.race | 205 // ES#sec-promise.race |
| 247 // Promise.race ( iterable ) | 206 // Promise.race ( iterable ) |
| 248 function PromiseRace(iterable) { | 207 function PromiseRace(iterable) { |
| 249 if (!IS_RECEIVER(this)) { | 208 if (!IS_RECEIVER(this)) { |
| 250 throw %make_type_error(kCalledOnNonObject, PromiseRace); | 209 throw %make_type_error(kCalledOnNonObject, PromiseRace); |
| 251 } | 210 } |
| 252 | 211 |
| 253 // false debugEvent so that forwarding the rejection through race does not | 212 // false debugEvent so that forwarding the rejection through race does not |
| 254 // trigger redundant ExceptionEvents | 213 // trigger redundant ExceptionEvents |
| 255 var deferred = NewPromiseCapability(this, false); | 214 var deferred = %new_promise_capability(this, false); |
| 256 | 215 |
| 257 // For catch prediction, don't treat the .then calls as handling it; | 216 // For catch prediction, don't treat the .then calls as handling it; |
| 258 // instead, recurse outwards. | 217 // instead, recurse outwards. |
| 259 var instrumenting = DEBUG_IS_ACTIVE; | 218 var instrumenting = DEBUG_IS_ACTIVE; |
| 260 if (instrumenting) { | 219 if (instrumenting) { |
| 261 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 220 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
| 262 } | 221 } |
| 263 | 222 |
| 264 try { | 223 try { |
| 265 for (var value of iterable) { | 224 for (var value of iterable) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 %SetCode(GlobalPromise.prototype.catch, PromiseCatch); | 322 %SetCode(GlobalPromise.prototype.catch, PromiseCatch); |
| 364 | 323 |
| 365 %InstallToContext([ | 324 %InstallToContext([ |
| 366 "promise_catch", GlobalPromise.prototype.catch, | 325 "promise_catch", GlobalPromise.prototype.catch, |
| 367 "promise_create", PromiseCreate, | 326 "promise_create", PromiseCreate, |
| 368 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, | 327 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, |
| 369 "promise_reject", DoRejectPromise, | 328 "promise_reject", DoRejectPromise, |
| 370 // TODO(gsathya): Remove this once we update the promise builtin. | 329 // TODO(gsathya): Remove this once we update the promise builtin. |
| 371 "promise_internal_reject", RejectPromise, | 330 "promise_internal_reject", RejectPromise, |
| 372 "promise_debug_get_info", PromiseDebugGetInfo, | 331 "promise_debug_get_info", PromiseDebugGetInfo, |
| 373 "new_promise_capability", NewPromiseCapability, | |
| 374 "internal_promise_capability", CreateInternalPromiseCapability, | |
| 375 "promise_id_resolve_handler", PromiseIdResolveHandler, | 332 "promise_id_resolve_handler", PromiseIdResolveHandler, |
| 376 "promise_id_reject_handler", PromiseIdRejectHandler | 333 "promise_id_reject_handler", PromiseIdRejectHandler |
| 377 ]); | 334 ]); |
| 378 | 335 |
| 379 // This allows extras to create promises quickly without building extra | 336 // This allows extras to create promises quickly without building extra |
| 380 // resolve/reject closures, and allows them to later resolve and reject any | 337 // resolve/reject closures, and allows them to later resolve and reject any |
| 381 // promise without having to hold on to those closures forever. | 338 // promise without having to hold on to those closures forever. |
| 382 utils.InstallFunctions(extrasUtils, 0, [ | 339 utils.InstallFunctions(extrasUtils, 0, [ |
| 383 "createPromise", PromiseCreate, | 340 "createPromise", PromiseCreate, |
| 384 "rejectPromise", DoRejectPromise, | 341 "rejectPromise", DoRejectPromise, |
| 385 "markPromiseAsHandled", MarkPromiseAsHandled | 342 "markPromiseAsHandled", MarkPromiseAsHandled |
| 386 ]); | 343 ]); |
| 387 | 344 |
| 388 utils.Export(function(to) { | 345 utils.Export(function(to) { |
| 389 to.PromiseCreate = PromiseCreate; | 346 to.PromiseCreate = PromiseCreate; |
| 390 to.PromiseThen = PromiseThen; | 347 to.PromiseThen = PromiseThen; |
| 391 | |
| 392 to.CreateInternalPromiseCapability = CreateInternalPromiseCapability; | |
| 393 to.RejectPromise = RejectPromise; | 348 to.RejectPromise = RejectPromise; |
| 394 }); | 349 }); |
| 395 | 350 |
| 396 }) | 351 }) |
| OLD | NEW |