|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org> |
| 2 | + * Copyright (c) 2021-2024, Linus Groh <linusg@serenityos.org> |
3 | 3 | *
|
4 | 4 | * SPDX-License-Identifier: BSD-2-Clause
|
5 | 5 | */
|
@@ -238,6 +238,7 @@ void PromiseConstructor::initialize(Realm& realm)
|
238 | 238 | define_native_function(realm, vm.names.race, race, 1, attr);
|
239 | 239 | define_native_function(realm, vm.names.reject, reject, 1, attr);
|
240 | 240 | define_native_function(realm, vm.names.resolve, resolve, 1, attr);
|
| 241 | + define_native_function(realm, vm.names.try_, try_, 1, attr); |
241 | 242 | define_native_function(realm, vm.names.withResolvers, with_resolvers, 0, attr);
|
242 | 243 |
|
243 | 244 | define_native_accessor(realm, vm.well_known_symbol_species(), symbol_species_getter, {}, Attribute::Configurable);
|
@@ -458,6 +459,43 @@ JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::resolve)
|
458 | 459 | return TRY(promise_resolve(vm, constructor.as_object(), value));
|
459 | 460 | }
|
460 | 461 |
|
| 462 | +// 1 Promise.try ( callbackfn, ...args ), https://tc39.es/proposal-promise-try/#sec-promise.try |
| 463 | +JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::try_) |
| 464 | +{ |
| 465 | + auto callbackfn = vm.argument(0); |
| 466 | + Span<Value> args; |
| 467 | + if (vm.argument_count() > 1) { |
| 468 | + args = vm.running_execution_context().arguments.span().slice(1, vm.argument_count() - 1); |
| 469 | + } |
| 470 | + |
| 471 | + // 1. Let C be the this value. |
| 472 | + auto constructor = vm.this_value(); |
| 473 | + |
| 474 | + // 2. If C is not an Object, throw a TypeError exception. |
| 475 | + if (!constructor.is_object()) |
| 476 | + return vm.throw_completion<TypeError>(ErrorType::NotAnObject, constructor.to_string_without_side_effects()); |
| 477 | + |
| 478 | + // 3. Let promiseCapability be ? NewPromiseCapability(C). |
| 479 | + auto promise_capability = TRY(new_promise_capability(vm, constructor)); |
| 480 | + |
| 481 | + // 4. Let status be Completion(Call(callbackfn, undefined, args)). |
| 482 | + auto status = JS::call(vm, callbackfn, js_undefined(), args); |
| 483 | + |
| 484 | + // 5. If status is an abrupt completion, then |
| 485 | + if (status.is_throw_completion()) { |
| 486 | + // a. Perform ? Call(promiseCapability.[[Reject]], undefined, « status.[[Value]] »). |
| 487 | + TRY(JS::call(vm, *promise_capability->reject(), js_undefined(), *status.throw_completion().value())); |
| 488 | + } |
| 489 | + // 6. Else, |
| 490 | + else { |
| 491 | + // a. Perform ? Call(promiseCapability.[[Resolve]], undefined, « status.[[Value]] »). |
| 492 | + TRY(JS::call(vm, *promise_capability->resolve(), js_undefined(), status.value())); |
| 493 | + } |
| 494 | + |
| 495 | + // 7. Return promiseCapability.[[Promise]]. |
| 496 | + return promise_capability->promise(); |
| 497 | +} |
| 498 | + |
461 | 499 | // 27.2.4.8 Promise.withResolvers ( ), https://tc39.es/ecma262/#sec-promise.withResolvers
|
462 | 500 | JS_DEFINE_NATIVE_FUNCTION(PromiseConstructor::with_resolvers)
|
463 | 501 | {
|
|
0 commit comments