mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 10:18:15 +09:00
LibJS: Annotate Promise implementation with spec comments
I wanted to do this for a long time. The guts of Promise are pretty complex, and it's easier to understand with the spec right next to it. Also found a couple of issues along the way :^)
This commit is contained in:
parent
df06552b48
commit
01c2570678
Notes:
sideshowbarker
2024-07-18 01:10:03 +09:00
Author: https://github.com/linusg
Commit: 01c2570678
Pull-request: https://github.com/SerenityOS/serenity/pull/10913
Reviewed-by: https://github.com/IdanHo ✅
7 changed files with 523 additions and 41 deletions
|
@ -63,13 +63,20 @@ Value PromiseAllResolveElementFunction::resolve_element()
|
|||
auto& vm = this->vm();
|
||||
auto& global_object = this->global_object();
|
||||
|
||||
// 8. Set values[index] to x.
|
||||
m_values.values()[m_index] = vm.argument(0);
|
||||
|
||||
// 9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
|
||||
// 10. If remainingElementsCount.[[Value]] is 0, then
|
||||
if (--m_remaining_elements.value == 0) {
|
||||
auto values_array = Array::create_from(global_object, m_values.values());
|
||||
// a. Let valuesArray be ! CreateArrayFromList(values).
|
||||
auto* values_array = Array::create_from(global_object, m_values.values());
|
||||
|
||||
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
||||
return TRY_OR_DISCARD(vm.call(*m_capability.resolve, js_undefined(), values_array));
|
||||
}
|
||||
|
||||
// 11. Return undefined.
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
|
@ -88,17 +95,29 @@ Value PromiseAllSettledResolveElementFunction::resolve_element()
|
|||
auto& vm = this->vm();
|
||||
auto& global_object = this->global_object();
|
||||
|
||||
// 9. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
||||
|
||||
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled").
|
||||
MUST(object->create_data_property_or_throw(vm.names.status, js_string(vm, "fulfilled"sv)));
|
||||
|
||||
// 11. Perform ! CreateDataPropertyOrThrow(obj, "value", x).
|
||||
MUST(object->create_data_property_or_throw(vm.names.value, vm.argument(0)));
|
||||
|
||||
// 12. Set values[index] to obj.
|
||||
m_values.values()[m_index] = object;
|
||||
|
||||
// 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
|
||||
// 14. If remainingElementsCount.[[Value]] is 0, then
|
||||
if (--m_remaining_elements.value == 0) {
|
||||
auto values_array = Array::create_from(global_object, m_values.values());
|
||||
// a. Let valuesArray be ! CreateArrayFromList(values).
|
||||
auto* values_array = Array::create_from(global_object, m_values.values());
|
||||
|
||||
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
||||
return TRY_OR_DISCARD(vm.call(*m_capability.resolve, js_undefined(), values_array));
|
||||
}
|
||||
|
||||
// 15. Return undefined.
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
|
@ -117,17 +136,29 @@ Value PromiseAllSettledRejectElementFunction::resolve_element()
|
|||
auto& vm = this->vm();
|
||||
auto& global_object = this->global_object();
|
||||
|
||||
// 9. Let obj be ! OrdinaryObjectCreate(%Object.prototype%).
|
||||
auto* object = Object::create(global_object, global_object.object_prototype());
|
||||
|
||||
// 10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected").
|
||||
MUST(object->create_data_property_or_throw(vm.names.status, js_string(vm, "rejected"sv)));
|
||||
|
||||
// 11. Perform ! CreateDataPropertyOrThrow(obj, "reason", x).
|
||||
MUST(object->create_data_property_or_throw(vm.names.reason, vm.argument(0)));
|
||||
|
||||
// 12. Set values[index] to obj.
|
||||
m_values.values()[m_index] = object;
|
||||
|
||||
// 13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
|
||||
// 14. If remainingElementsCount.[[Value]] is 0, then
|
||||
if (--m_remaining_elements.value == 0) {
|
||||
// a. Let valuesArray be ! CreateArrayFromList(values).
|
||||
auto values_array = Array::create_from(global_object, m_values.values());
|
||||
|
||||
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
||||
return TRY_OR_DISCARD(vm.call(*m_capability.resolve, js_undefined(), values_array));
|
||||
}
|
||||
|
||||
// 15. Return undefined.
|
||||
return js_undefined();
|
||||
}
|
||||
|
||||
|
@ -146,14 +177,20 @@ Value PromiseAnyRejectElementFunction::resolve_element()
|
|||
auto& vm = this->vm();
|
||||
auto& global_object = this->global_object();
|
||||
|
||||
// 8. Set errors[index] to x.
|
||||
m_values.values()[m_index] = vm.argument(0);
|
||||
|
||||
// 9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
|
||||
// 10. If remainingElementsCount.[[Value]] is 0, then
|
||||
if (--m_remaining_elements.value == 0) {
|
||||
auto errors_array = Array::create_from(global_object, m_values.values());
|
||||
|
||||
// a. Let error be a newly created AggregateError object.
|
||||
auto* error = AggregateError::create(global_object);
|
||||
|
||||
// b. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: ! CreateArrayFromList(errors) }).
|
||||
auto errors_array = Array::create_from(global_object, m_values.values());
|
||||
MUST(error->define_property_or_throw(vm.names.errors, { .value = errors_array, .writable = true, .enumerable = false, .configurable = true }));
|
||||
|
||||
// c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
|
||||
return TRY_OR_DISCARD(vm.call(*m_capability.reject, js_undefined(), error));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue