summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2021-11-14 00:33:16 +0000
committerLinus Groh <mail@linusgroh.de>2021-11-14 15:27:46 +0000
commit01c2570678edad6896e22d1a951002bb5718113e (patch)
tree2de9ac01f24d562c66c95de3afb4cbb27bf40d6f /Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
parentdf06552b4882554fd2cc1979f5dcc2575d3f6a64 (diff)
downloadserenity-01c2570678edad6896e22d1a951002bb5718113e.zip
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 :^)
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp')
-rw-r--r--Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp45
1 files changed, 41 insertions, 4 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp b/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
index d1d77fc517..0860b1802f 100644
--- a/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
+++ b/Userland/Libraries/LibJS/Runtime/PromiseResolvingElementFunctions.cpp
@@ -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));
}