diff options
author | Obinna Ikeh <hikenike6@gmail.com> | 2022-06-26 08:53:41 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-06-29 13:36:54 +0100 |
commit | ee9353702c4eea6edef76cd6c4288656d678d17c (patch) | |
tree | 9d009992c5a1ae9f87fc014ad8a2460b3bf3ebd0 /Userland | |
parent | 05058d185c5f08d54e6aad0ca4fe268706525f27 (diff) | |
download | serenity-ee9353702c4eea6edef76cd6c4288656d678d17c.zip |
LibJS: Implement element comparison function for typed arrays
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/TypedArray.cpp | 57 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/TypedArray.h | 1 |
2 files changed, 58 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index d597fc4d25..e885748350 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -347,6 +347,63 @@ ThrowCompletionOr<TypedArrayBase*> typed_array_create(GlobalObject& global_objec return &typed_array; } +// 1.2.2.1.2 CompareTypedArrayElements ( x, y, comparefn, buffer ), https://tc39.es/proposal-change-array-by-copy/#sec-comparetypedarrayelements +ThrowCompletionOr<double> compare_typed_array_elements(GlobalObject& global_object, Value x, Value y, FunctionObject* comparefn, ArrayBuffer& buffer) +{ + auto& vm = global_object.vm(); + // 1. Assert: Both Type(x) and Type(y) are Number or both are BigInt. + VERIFY(((x.is_number() && y.is_number()) || (x.is_bigint() && y.is_bigint()))); + + // 2. 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 IsDetachedBuffer(buffer) is true, throw a TypeError exception. + if (buffer.is_detached()) + return vm.throw_completion<TypeError>(global_object, ErrorType::DetachedArrayBuffer); + + // c. If v is NaN, return +0๐ฝ. + if (value_number.is_nan()) + return 0; + + // d. Return v. + return value_number.as_double(); + } + + // 3. If x and y are both NaN, return +0๐ฝ. + if (x.is_nan() && y.is_nan()) + return 0; + + // 4. If x is NaN, return 1๐ฝ. + if (x.is_nan()) + return 1; + + // 5. If y is NaN, return -1๐ฝ. + if (y.is_nan()) + return -1; + + // 6. If x < y, return -1๐ฝ. + if (x.is_bigint() + ? (x.as_bigint().big_integer() < y.as_bigint().big_integer()) + : (x.as_double() < y.as_double())) + return -1; + + // 7. If x > y, return 1๐ฝ. + if (x.is_bigint() + ? (x.as_bigint().big_integer() > y.as_bigint().big_integer()) + : (x.as_double() > y.as_double())) + return 1; + + // 9. If x is +0๐ฝ and y is -0๐ฝ, return 1๐ฝ. + if (x.is_positive_zero() && y.is_negative_zero()) + return 1; + + // 10. Return +0๐ฝ. + return 0; +} + void TypedArrayBase::visit_edges(Visitor& visitor) { Base::visit_edges(visitor); diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index d11711f3aa..839482fc54 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -451,6 +451,7 @@ private: }; ThrowCompletionOr<TypedArrayBase*> typed_array_create(GlobalObject& global_object, FunctionObject& constructor, MarkedVector<Value> arguments); +ThrowCompletionOr<double> compare_typed_array_elements(GlobalObject& global_object, Value x, Value y, FunctionObject* comparefn, ArrayBuffer&); #define JS_DECLARE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type) \ class ClassName : public TypedArray<Type> { \ |