|
7 | 7 |
|
8 | 8 | namespace runtime { |
9 | 9 | extern transitioning runtime |
10 | | - RejectPromise(implicit context: Context)(JSPromise, JSAny, Boolean): Object; |
| 10 | + RejectPromise(implicit context: Context)(JSPromise, JSAny, Boolean): JSAny; |
| 11 | + |
| 12 | + extern transitioning runtime |
| 13 | + PromiseRejectAfterResolved(implicit context: Context)(JSPromise, JSAny): |
| 14 | + JSAny; |
| 15 | + |
| 16 | + extern transitioning runtime |
| 17 | + PromiseResolveAfterResolved(implicit context: Context)(JSPromise, JSAny): |
| 18 | + JSAny; |
11 | 19 | } |
12 | 20 |
|
13 | 21 | // https://tc39.es/ecma262/#sec-promise-abstract-operations |
@@ -36,6 +44,8 @@ namespace promise { |
36 | 44 | extern macro PromiseReactionMapConstant(): Map; |
37 | 45 | extern macro PromiseFulfillReactionJobTaskMapConstant(): Map; |
38 | 46 | extern macro PromiseRejectReactionJobTaskMapConstant(): Map; |
| 47 | + extern transitioning builtin |
| 48 | + ResolvePromise(Context, JSPromise, JSAny): JSAny; |
39 | 49 |
|
40 | 50 | extern transitioning builtin |
41 | 51 | EnqueueMicrotask(Context, PromiseReactionJobTask): Undefined; |
@@ -196,7 +206,7 @@ namespace promise { |
196 | 206 | // https://tc39.es/ecma262/#sec-rejectpromise |
197 | 207 | transitioning builtin |
198 | 208 | RejectPromise(implicit context: Context)( |
199 | | - promise: JSPromise, reason: JSAny, debugEvent: Boolean): Object { |
| 209 | + promise: JSPromise, reason: JSAny, debugEvent: Boolean): JSAny { |
200 | 210 | // If promise hook is enabled or the debugger is active, let |
201 | 211 | // the runtime handle this operation, which greatly reduces |
202 | 212 | // the complexity here and also avoids a couple of back and |
@@ -233,6 +243,12 @@ namespace promise { |
233 | 243 | generates 'PromiseBuiltins::kCapabilitiesContextLength'; |
234 | 244 | const kPromiseBuiltinsCapabilitySlot: constexpr ContextSlot |
235 | 245 | generates 'PromiseBuiltins::kCapabilitySlot'; |
| 246 | + const kPromiseBuiltinsPromiseSlot: constexpr ContextSlot |
| 247 | + generates 'PromiseBuiltins::kPromiseSlot'; |
| 248 | + const kPromiseBuiltinsAlreadyResolvedSlot: constexpr ContextSlot |
| 249 | + generates 'PromiseBuiltins::kAlreadyResolvedSlot'; |
| 250 | + const kPromiseBuiltinsDebugEventSlot: constexpr ContextSlot |
| 251 | + generates 'PromiseBuiltins::kDebugEventSlot'; |
236 | 252 |
|
237 | 253 | extern macro |
238 | 254 | PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Context): JSPromise; |
@@ -340,4 +356,53 @@ namespace promise { |
340 | 356 | } |
341 | 357 | } |
342 | 358 | } |
| 359 | + |
| 360 | + // https://tc39.es/ecma262/#sec-promise-reject-functions |
| 361 | + transitioning javascript builtin |
| 362 | + PromiseCapabilityDefaultReject(js-implicit context: Context, receiver: JSAny)( |
| 363 | + reason: JSAny): JSAny { |
| 364 | + // 2. Let promise be F.[[Promise]]. |
| 365 | + const promise = UnsafeCast<JSPromise>(context[kPromiseBuiltinsPromiseSlot]); |
| 366 | + |
| 367 | + // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
| 368 | + const alreadyResolved = |
| 369 | + UnsafeCast<Boolean>(context[kPromiseBuiltinsAlreadyResolvedSlot]); |
| 370 | + |
| 371 | + // 4. If alreadyResolved.[[Value]] is true, return undefined. |
| 372 | + if (alreadyResolved == True) { |
| 373 | + return runtime::PromiseRejectAfterResolved(promise, reason); |
| 374 | + } |
| 375 | + |
| 376 | + // 5. Set alreadyResolved.[[Value]] to true. |
| 377 | + context[kPromiseBuiltinsAlreadyResolvedSlot] = True; |
| 378 | + |
| 379 | + // 6. Return RejectPromise(promise, reason). |
| 380 | + const debugEvent = |
| 381 | + UnsafeCast<Boolean>(context[kPromiseBuiltinsDebugEventSlot]); |
| 382 | + return RejectPromise(promise, reason, debugEvent); |
| 383 | + } |
| 384 | + |
| 385 | + // https://tc39.es/ecma262/#sec-promise-resolve-functions |
| 386 | + transitioning javascript builtin |
| 387 | + PromiseCapabilityDefaultResolve( |
| 388 | + js-implicit context: Context, receiver: JSAny)(resolution: JSAny): JSAny { |
| 389 | + // 2. Let promise be F.[[Promise]]. |
| 390 | + const promise = UnsafeCast<JSPromise>(context[kPromiseBuiltinsPromiseSlot]); |
| 391 | + |
| 392 | + // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
| 393 | + const alreadyResolved = |
| 394 | + UnsafeCast<Boolean>(context[kPromiseBuiltinsAlreadyResolvedSlot]); |
| 395 | + |
| 396 | + // 4. If alreadyResolved.[[Value]] is true, return undefined. |
| 397 | + if (alreadyResolved == True) { |
| 398 | + return runtime::PromiseResolveAfterResolved(promise, resolution); |
| 399 | + } |
| 400 | + |
| 401 | + // 5. Set alreadyResolved.[[Value]] to true. |
| 402 | + context[kPromiseBuiltinsAlreadyResolvedSlot] = True; |
| 403 | + |
| 404 | + // The rest of the logic (and the catch prediction) is |
| 405 | + // encapsulated in the dedicated ResolvePromise builtin. |
| 406 | + return ResolvePromise(context, promise, resolution); |
| 407 | + } |
343 | 408 | } |
0 commit comments