summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-06-14 02:02:53 +0300
committerLinus Groh <mail@linusgroh.de>2021-06-14 01:45:04 +0100
commitd7a70eb77ce7bc3baf8a03800e3cda3771f3e71e (patch)
tree30fffdfff4b2eecbf537c3bb83e4f7ac74cb4995 /Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
parentc54b9a692011d8094f20f6852ddac0f77edddc24 (diff)
downloadserenity-d7a70eb77ce7bc3baf8a03800e3cda3771f3e71e.zip
LibJS: Add all of the DataView.prototype.set* methods
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/ArrayBuffer.h')
-rw-r--r--Userland/Libraries/LibJS/Runtime/ArrayBuffer.h57
1 files changed, 57 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
index cc9b5f1a49..c2ee642ca3 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
+++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
@@ -40,6 +40,8 @@ public:
};
template<typename type>
Value get_value(size_t byte_index, bool is_typed_array, Order, bool is_little_endian = true);
+ template<typename type>
+ Value set_value(size_t byte_index, Value value, bool is_typed_array, Order, bool is_little_endian = true);
private:
virtual void visit_edges(Visitor&) override;
@@ -108,4 +110,59 @@ Value ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_a
return raw_bytes_to_numeric<T>(global_object(), move(raw_value), is_little_endian);
}
+// 25.1.2.11 NumericToRawBytes ( type, value, isLittleEndian ), https://tc39.es/ecma262/#sec-numerictorawbytes
+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));
+ 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]);
+ };
+ if constexpr (IsSame<T, 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>) {
+ 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>)
+ 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);
+ 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();
+ return raw_bytes;
+ }
+}
+
+// 25.1.2.12 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-setvalueinbuffer
+template<typename T>
+Value ArrayBuffer::set_value(size_t byte_index, Value value, [[maybe_unused]] bool is_typed_array, Order, bool is_little_endian)
+{
+ auto raw_bytes = numeric_to_raw_bytes<T>(global_object(), value, is_little_endian);
+
+ // FIXME: Check for shared buffer
+
+ raw_bytes.span().copy_to(buffer_impl().span().slice(byte_index));
+ return js_undefined();
+}
+
}