diff options
-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> { \ |