summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorObinna Ikeh <hikenike6@gmail.com>2022-06-26 08:53:41 +0100
committerLinus Groh <mail@linusgroh.de>2022-06-29 13:36:54 +0100
commitee9353702c4eea6edef76cd6c4288656d678d17c (patch)
tree9d009992c5a1ae9f87fc014ad8a2460b3bf3ebd0 /Userland
parent05058d185c5f08d54e6aad0ca4fe268706525f27 (diff)
downloadserenity-ee9353702c4eea6edef76cd6c4288656d678d17c.zip
LibJS: Implement element comparison function for typed arrays
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArray.cpp57
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArray.h1
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> { \