| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 // Only used by async-await.js | 74 // Only used by async-await.js |
| 75 function RejectPromise(promise, reason, debugEvent) { | 75 function RejectPromise(promise, reason, debugEvent) { |
| 76 %PromiseReject(promise, reason, debugEvent); | 76 %PromiseReject(promise, reason, debugEvent); |
| 77 } | 77 } |
| 78 | 78 |
| 79 // Export to bindings | 79 // Export to bindings |
| 80 function DoRejectPromise(promise, reason) { | 80 function DoRejectPromise(promise, reason) { |
| 81 %PromiseReject(promise, reason, true); | 81 %PromiseReject(promise, reason, true); |
| 82 } | 82 } |
| 83 | 83 |
| 84 // The resultCapability.promise is only ever fulfilled internally, | |
| 85 // so we don't need the closures to protect against accidentally | |
| 86 // calling them multiple times. | |
| 87 function CreateInternalPromiseCapability(parent) { | |
| 88 return { | |
| 89 promise: %promise_internal_constructor(parent), | |
| 90 resolve: UNDEFINED, | |
| 91 reject: UNDEFINED | |
| 92 }; | |
| 93 } | |
| 94 | |
| 95 // ES#sec-newpromisecapability | |
| 96 // NewPromiseCapability ( C ) | |
| 97 function NewPromiseCapability(C, debugEvent) { | |
| 98 if (C === GlobalPromise) { | |
| 99 // Optimized case, avoid extra closure. | |
| 100 var promise = %promise_internal_constructor(UNDEFINED); | |
| 101 // TODO(gsathya): Remove container for callbacks when this is | |
| 102 // moved to CPP/TF. | |
| 103 var callbacks = %create_resolving_functions(promise, debugEvent); | |
| 104 return { | |
| 105 promise: promise, | |
| 106 resolve: callbacks[kResolveCallback], | |
| 107 reject: callbacks[kRejectCallback] | |
| 108 }; | |
| 109 } | |
| 110 | |
| 111 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; | |
| 112 result.promise = new C((resolve, reject) => { | |
| 113 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) | |
| 114 throw %make_type_error(kPromiseExecutorAlreadyInvoked); | |
| 115 result.resolve = resolve; | |
| 116 result.reject = reject; | |
| 117 }); | |
| 118 | |
| 119 if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject)) | |
| 120 throw %make_type_error(kPromiseNonCallable); | |
| 121 | |
| 122 return result; | |
| 123 } | |
| 124 | |
| 125 // ES#sec-promise.reject | 84 // ES#sec-promise.reject |
| 126 // Promise.reject ( x ) | 85 // Promise.reject ( x ) |
| 127 function PromiseReject(r) { | 86 function PromiseReject(r) { |
| 128 if (!IS_RECEIVER(this)) { | 87 if (!IS_RECEIVER(this)) { |
| 129 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 88 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
| 130 } | 89 } |
| 131 if (this === GlobalPromise) { | 90 if (this === GlobalPromise) { |
| 132 // Optimized case, avoid extra closure. | 91 // Optimized case, avoid extra closure. |
| 133 var promise = %promise_create_and_set(kRejected, r); | 92 var promise = %promise_create_and_set(kRejected, r); |
| 134 // Trigger debug events if the debugger is on, as Promise.reject is | 93 // Trigger debug events if the debugger is on, as Promise.reject is |
| 135 // equivalent to throwing an exception directly. | 94 // equivalent to throwing an exception directly. |
| 136 %PromiseRejectEventFromStack(promise, r); | 95 %PromiseRejectEventFromStack(promise, r); |
| 137 return promise; | 96 return promise; |
| 138 } else { | 97 } else { |
| 139 var promiseCapability = NewPromiseCapability(this, true); | 98 var promiseCapability = %new_promise_capability(this, true); |
| 140 %_Call(promiseCapability.reject, UNDEFINED, r); | 99 %_Call(promiseCapability.reject, UNDEFINED, r); |
| 141 return promiseCapability.promise; | 100 return promiseCapability.promise; |
| 142 } | 101 } |
| 143 } | 102 } |
| 144 | 103 |
| 145 // Combinators. | 104 // Combinators. |
| 146 | 105 |
| 147 // ES#sec-promise.resolve | 106 // ES#sec-promise.resolve |
| 148 // Promise.resolve ( x ) | 107 // Promise.resolve ( x ) |
| 149 function PromiseResolve(x) { | 108 function PromiseResolve(x) { |
| 150 if (!IS_RECEIVER(this)) { | 109 if (!IS_RECEIVER(this)) { |
| 151 throw %make_type_error(kCalledOnNonObject, PromiseResolve); | 110 throw %make_type_error(kCalledOnNonObject, PromiseResolve); |
| 152 } | 111 } |
| 153 if (%is_promise(x) && x.constructor === this) return x; | 112 if (%is_promise(x) && x.constructor === this) return x; |
| 154 | 113 |
| 155 // Avoid creating resolving functions. | 114 // Avoid creating resolving functions. |
| 156 if (this === GlobalPromise) { | 115 if (this === GlobalPromise) { |
| 157 var promise = %promise_internal_constructor(UNDEFINED); | 116 var promise = %promise_internal_constructor(UNDEFINED); |
| 158 %promise_resolve(promise, x); | 117 %promise_resolve(promise, x); |
| 159 return promise; | 118 return promise; |
| 160 } | 119 } |
| 161 | 120 |
| 162 // debugEvent is not so meaningful here as it will be resolved | 121 // debugEvent is not so meaningful here as it will be resolved |
| 163 var promiseCapability = NewPromiseCapability(this, true); | 122 var promiseCapability = %new_promise_capability(this, true); |
| 164 %_Call(promiseCapability.resolve, UNDEFINED, x); | 123 %_Call(promiseCapability.resolve, UNDEFINED, x); |
| 165 return promiseCapability.promise; | 124 return promiseCapability.promise; |
| 166 } | 125 } |
| 167 | 126 |
| 168 // ES#sec-promise.all | 127 // ES#sec-promise.all |
| 169 // Promise.all ( iterable ) | 128 // Promise.all ( iterable ) |
| 170 function PromiseAll(iterable) { | 129 function PromiseAll(iterable) { |
| 171 if (!IS_RECEIVER(this)) { | 130 if (!IS_RECEIVER(this)) { |
| 172 throw %make_type_error(kCalledOnNonObject, "Promise.all"); | 131 throw %make_type_error(kCalledOnNonObject, "Promise.all"); |
| 173 } | 132 } |
| 174 | 133 |
| 175 // false debugEvent so that forwarding the rejection through all does not | 134 // false debugEvent so that forwarding the rejection through all does not |
| 176 // trigger redundant ExceptionEvents | 135 // trigger redundant ExceptionEvents |
| 177 var deferred = NewPromiseCapability(this, false); | 136 var deferred = %new_promise_capability(this, false); |
| 178 var resolutions = new InternalArray(); | 137 var resolutions = new InternalArray(); |
| 179 var count; | 138 var count; |
| 180 | 139 |
| 181 // For catch prediction, don't treat the .then calls as handling it; | 140 // For catch prediction, don't treat the .then calls as handling it; |
| 182 // instead, recurse outwards. | 141 // instead, recurse outwards. |
| 183 var instrumenting = DEBUG_IS_ACTIVE; | 142 var instrumenting = DEBUG_IS_ACTIVE; |
| 184 if (instrumenting) { | 143 if (instrumenting) { |
| 185 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 144 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
| 186 } | 145 } |
| 187 | 146 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 | 190 |
| 232 // ES#sec-promise.race | 191 // ES#sec-promise.race |
| 233 // Promise.race ( iterable ) | 192 // Promise.race ( iterable ) |
| 234 function PromiseRace(iterable) { | 193 function PromiseRace(iterable) { |
| 235 if (!IS_RECEIVER(this)) { | 194 if (!IS_RECEIVER(this)) { |
| 236 throw %make_type_error(kCalledOnNonObject, PromiseRace); | 195 throw %make_type_error(kCalledOnNonObject, PromiseRace); |
| 237 } | 196 } |
| 238 | 197 |
| 239 // false debugEvent so that forwarding the rejection through race does not | 198 // false debugEvent so that forwarding the rejection through race does not |
| 240 // trigger redundant ExceptionEvents | 199 // trigger redundant ExceptionEvents |
| 241 var deferred = NewPromiseCapability(this, false); | 200 var deferred = %new_promise_capability(this, false); |
| 242 | 201 |
| 243 // For catch prediction, don't treat the .then calls as handling it; | 202 // For catch prediction, don't treat the .then calls as handling it; |
| 244 // instead, recurse outwards. | 203 // instead, recurse outwards. |
| 245 var instrumenting = DEBUG_IS_ACTIVE; | 204 var instrumenting = DEBUG_IS_ACTIVE; |
| 246 if (instrumenting) { | 205 if (instrumenting) { |
| 247 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); | 206 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); |
| 248 } | 207 } |
| 249 | 208 |
| 250 try { | 209 try { |
| 251 for (var value of iterable) { | 210 for (var value of iterable) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 "resolve", PromiseResolve | 298 "resolve", PromiseResolve |
| 340 ]); | 299 ]); |
| 341 | 300 |
| 342 %InstallToContext([ | 301 %InstallToContext([ |
| 343 "promise_create", PromiseCreate, | 302 "promise_create", PromiseCreate, |
| 344 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, | 303 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler, |
| 345 "promise_reject", DoRejectPromise, | 304 "promise_reject", DoRejectPromise, |
| 346 // TODO(gsathya): Remove this once we update the promise builtin. | 305 // TODO(gsathya): Remove this once we update the promise builtin. |
| 347 "promise_internal_reject", RejectPromise, | 306 "promise_internal_reject", RejectPromise, |
| 348 "promise_debug_get_info", PromiseDebugGetInfo, | 307 "promise_debug_get_info", PromiseDebugGetInfo, |
| 349 "new_promise_capability", NewPromiseCapability, | |
| 350 "internal_promise_capability", CreateInternalPromiseCapability, | |
| 351 "promise_id_resolve_handler", PromiseIdResolveHandler, | 308 "promise_id_resolve_handler", PromiseIdResolveHandler, |
| 352 "promise_id_reject_handler", PromiseIdRejectHandler | 309 "promise_id_reject_handler", PromiseIdRejectHandler |
| 353 ]); | 310 ]); |
| 354 | 311 |
| 355 // This allows extras to create promises quickly without building extra | 312 // This allows extras to create promises quickly without building extra |
| 356 // resolve/reject closures, and allows them to later resolve and reject any | 313 // resolve/reject closures, and allows them to later resolve and reject any |
| 357 // promise without having to hold on to those closures forever. | 314 // promise without having to hold on to those closures forever. |
| 358 utils.InstallFunctions(extrasUtils, 0, [ | 315 utils.InstallFunctions(extrasUtils, 0, [ |
| 359 "createPromise", PromiseCreate, | 316 "createPromise", PromiseCreate, |
| 360 "rejectPromise", DoRejectPromise, | 317 "rejectPromise", DoRejectPromise, |
| 361 "markPromiseAsHandled", MarkPromiseAsHandled | 318 "markPromiseAsHandled", MarkPromiseAsHandled |
| 362 ]); | 319 ]); |
| 363 | 320 |
| 364 utils.Export(function(to) { | 321 utils.Export(function(to) { |
| 365 to.PromiseCreate = PromiseCreate; | 322 to.PromiseCreate = PromiseCreate; |
| 366 | |
| 367 to.CreateInternalPromiseCapability = CreateInternalPromiseCapability; | |
| 368 to.RejectPromise = RejectPromise; | 323 to.RejectPromise = RejectPromise; |
| 369 }); | 324 }); |
| 370 | 325 |
| 371 }) | 326 }) |
| OLD | NEW |