summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorLuke <luke.wilde@live.co.uk>2021-06-17 00:43:24 +0100
committerLinus Groh <mail@linusgroh.de>2021-06-17 02:20:03 +0100
commit80edf6f5b62f3ff8bfa198943a09e08769cd6ff9 (patch)
tree4f360dcce418c899f73dea4d406af110b8bf6bc9 /Userland/Libraries
parent7ff144d533514420a60395e7dc9b41397846d90a (diff)
downloadserenity-80edf6f5b62f3ff8bfa198943a09e08769cd6ff9.zip
LibJS: Refactor numeric_to_raw_bytes and raw_bytes_to_numeric
This is to make use of the new Value conversion methods. This also moves the clamped u8 tag to ArrayBuffer from TypedArray and the conversion to these methods, as the spec does it here.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/Runtime/ArrayBuffer.h73
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArray.h3
2 files changed, 49 insertions, 27 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
index c2ee642ca3..1e43e608bb 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
+++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
@@ -13,6 +13,9 @@
namespace JS {
+struct ClampedU8 {
+};
+
class ArrayBuffer : public Object {
JS_OBJECT(ArrayBuffer, Object);
@@ -70,26 +73,27 @@ static Value raw_bytes_to_numeric(GlobalObject& global_object, ByteBuffer raw_va
for (size_t i = 0; i < raw_value.size() / 2; ++i)
swap(raw_value[i], raw_value[raw_value.size() - 1 - i]);
}
- if constexpr (IsSame<T, float>) {
+ using UnderlyingBufferDataType = Conditional<IsSame<ClampedU8, T>, u8, T>;
+ if constexpr (IsSame<UnderlyingBufferDataType, float>) {
float value;
raw_value.span().copy_to({ &value, sizeof(float) });
if (isnan(value))
return js_nan();
return Value(value);
}
- if constexpr (IsSame<T, double>) {
+ if constexpr (IsSame<UnderlyingBufferDataType, double>) {
double value;
raw_value.span().copy_to({ &value, sizeof(double) });
if (isnan(value))
return js_nan();
return Value(value);
}
- if constexpr (!IsIntegral<T>)
+ if constexpr (!IsIntegral<UnderlyingBufferDataType>)
VERIFY_NOT_REACHED();
- T int_value = 0;
- raw_value.span().copy_to({ &int_value, sizeof(T) });
- if constexpr (sizeof(T) == 8) {
- if constexpr (IsSigned<T>)
+ UnderlyingBufferDataType int_value = 0;
+ raw_value.span().copy_to({ &int_value, sizeof(UnderlyingBufferDataType) });
+ if constexpr (sizeof(UnderlyingBufferDataType) == 8) {
+ if constexpr (IsSigned<UnderlyingBufferDataType>)
return js_bigint(global_object.heap(), Crypto::SignedBigInteger::create_from(int_value));
else
return js_bigint(global_object.heap(), Crypto::SignedBigInteger { Crypto::UnsignedBigInteger::create_from(int_value) });
@@ -114,41 +118,62 @@ Value ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_a
template<typename T>
static ByteBuffer numeric_to_raw_bytes(GlobalObject& global_object, Value value, bool is_little_endian)
{
- ByteBuffer raw_bytes = ByteBuffer::create_uninitialized(sizeof(T));
+ using UnderlyingBufferDataType = Conditional<IsSame<ClampedU8, T>, u8, T>;
+ ByteBuffer raw_bytes = ByteBuffer::create_uninitialized(sizeof(UnderlyingBufferDataType));
auto flip_if_needed = [&]() {
if (is_little_endian)
return;
- VERIFY(sizeof(T) % 2 == 0);
- for (size_t i = 0; i < sizeof(T) / 2; ++i)
- swap(raw_bytes[i], raw_bytes[sizeof(T) - 1 - i]);
+ VERIFY(sizeof(UnderlyingBufferDataType) % 2 == 0);
+ for (size_t i = 0; i < sizeof(UnderlyingBufferDataType) / 2; ++i)
+ swap(raw_bytes[i], raw_bytes[sizeof(UnderlyingBufferDataType) - 1 - i]);
};
- if constexpr (IsSame<T, float>) {
+ if constexpr (IsSame<UnderlyingBufferDataType, float>) {
float raw_value = value.to_double(global_object);
ReadonlyBytes { &raw_value, sizeof(float) }.copy_to(raw_bytes);
flip_if_needed();
return raw_bytes;
}
- if constexpr (IsSame<T, double>) {
+ if constexpr (IsSame<UnderlyingBufferDataType, double>) {
double raw_value = value.to_double(global_object);
ReadonlyBytes { &raw_value, sizeof(double) }.copy_to(raw_bytes);
flip_if_needed();
return raw_bytes;
}
- if constexpr (!IsIntegral<T>)
+ if constexpr (!IsIntegral<UnderlyingBufferDataType>)
VERIFY_NOT_REACHED();
- if constexpr (sizeof(T) == 8) {
- u64 int_value = value.as_bigint().big_integer().to_u64();
- ReadonlyBytes { &int_value, sizeof(u64) }.copy_to(raw_bytes);
+ if constexpr (sizeof(UnderlyingBufferDataType) == 8) {
+ UnderlyingBufferDataType int_value;
+
+ if constexpr (IsSigned<UnderlyingBufferDataType>)
+ int_value = value.to_bigint_int64(global_object);
+ else
+ int_value = value.to_bigint_uint64(global_object);
+
+ ReadonlyBytes { &int_value, sizeof(UnderlyingBufferDataType) }.copy_to(raw_bytes);
flip_if_needed();
return raw_bytes;
} else {
- T int_value;
- if constexpr (IsSigned<T>)
- int_value = value.to_i32(global_object);
- else
- int_value = value.to_u32(global_object);
- ReadonlyBytes { &int_value, sizeof(T) }.copy_to(raw_bytes);
- flip_if_needed();
+ UnderlyingBufferDataType int_value;
+ if constexpr (IsSigned<UnderlyingBufferDataType>) {
+ if constexpr (sizeof(UnderlyingBufferDataType) == 4)
+ int_value = value.to_i32(global_object);
+ else if constexpr (sizeof(UnderlyingBufferDataType) == 2)
+ int_value = value.to_i16(global_object);
+ else
+ int_value = value.to_i8(global_object);
+ } else {
+ if constexpr (sizeof(UnderlyingBufferDataType) == 4)
+ int_value = value.to_u32(global_object);
+ else if constexpr (sizeof(UnderlyingBufferDataType) == 2)
+ int_value = value.to_u16(global_object);
+ else if constexpr (!IsSame<T, ClampedU8>)
+ int_value = value.to_u8(global_object);
+ else
+ int_value = value.to_u8_clamp(global_object);
+ }
+ ReadonlyBytes { &int_value, sizeof(UnderlyingBufferDataType) }.copy_to(raw_bytes);
+ if constexpr (sizeof(UnderlyingBufferDataType) % 2 == 0)
+ flip_if_needed();
return raw_bytes;
}
}
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h
index 0ef0e600b6..c38b01c644 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArray.h
+++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h
@@ -44,9 +44,6 @@ private:
virtual void visit_edges(Visitor&) override;
};
-struct ClampedU8 {
-};
-
template<typename T>
class TypedArray : public TypedArrayBase {
JS_OBJECT(TypedArray, TypedArrayBase);