LibJS: Implement the CompareArrayElements AO

This commit is contained in:
Linus Groh 2022-06-13 07:53:58 +01:00
parent aa5d5bf1c8
commit 5ddf0b0c99
Notes: sideshowbarker 2024-07-17 10:17:15 +09:00
2 changed files with 60 additions and 0 deletions

View file

@ -6,6 +6,7 @@
*/
#include <AK/Function.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/Error.h>
@ -142,6 +143,62 @@ ThrowCompletionOr<bool> Array::set_length(PropertyDescriptor const& property_des
return true;
}
// 1.1.1.2 CompareArrayElements ( x, y, comparefn ), https://tc39.es/proposal-change-array-by-copy/#sec-comparearrayelements
ThrowCompletionOr<double> compare_array_elements(GlobalObject& global_object, Value x, Value y, FunctionObject* comparefn)
{
auto& vm = global_object.vm();
// 1. If x and y are both undefined, return +0𝔽.
if (x.is_undefined() && y.is_undefined())
return 0;
// 2. If x is undefined, return 1𝔽.
if (x.is_undefined())
return 1;
// 3. If y is undefined, return -1𝔽.
if (y.is_undefined())
return -1;
// 4. If comparefn is not undefined, then
if (comparefn != nullptr) {
// a. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
auto value = TRY(call(global_object, comparefn, js_undefined(), x, y));
auto value_number = TRY(value.to_number(global_object));
// b. If v is NaN, return +0𝔽.
if (value_number.is_nan())
return 0;
// c. Return v.
return value_number.as_double();
}
// 5. Let xString be ? ToString(x).
auto* x_string = js_string(vm, TRY(x.to_string(global_object)));
// 6. Let yString be ? ToString(y).
auto* y_string = js_string(vm, TRY(y.to_string(global_object)));
// 7. Let xSmaller be ! IsLessThan(xString, yString, true).
// FIXME: Update order of parameters in our is_less_than() impl.
auto x_smaller = MUST(is_less_than(global_object, true, x_string, y_string));
// 8. If xSmaller is true, return -1𝔽.
if (x_smaller == TriState::True)
return -1;
// 9. Let ySmaller be ! IsLessThan(yString, xString, true).
auto y_smaller = MUST(is_less_than(global_object, true, y_string, x_string));
// 10. If ySmaller is true, return 1𝔽.
if (y_smaller == TriState::True)
return 1;
// 11. Return +0𝔽.
return 0;
}
// NON-STANDARD: Used to return the value of the ephemeral length property
ThrowCompletionOr<Optional<PropertyDescriptor>> Array::internal_get_own_property(PropertyKey const& property_key) const
{

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -50,4 +51,6 @@ private:
bool m_length_writable { true };
};
ThrowCompletionOr<double> compare_array_elements(GlobalObject&, Value x, Value y, FunctionObject* comparefn);
}