summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-07-11 08:57:54 -0400
committerLinus Groh <mail@linusgroh.de>2021-07-14 20:44:42 +0100
commitf4ea6b182404e510d05ebd1e36c4160660d1ef1a (patch)
treed76a72dd2f3abaa67e2501e6baeb4e3686498cf4 /Userland/Libraries
parenta61723ec599be984523e40030c05e3a3f3af7e67 (diff)
downloadserenity-f4ea6b182404e510d05ebd1e36c4160660d1ef1a.zip
LibJS: Implement TypedArray GetModifySetValueInBuffer abstract operation
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/Runtime/ArrayBuffer.h21
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArray.h3
2 files changed, 24 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
index 4d712e56f4..681f363190 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
+++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h
@@ -7,6 +7,7 @@
#pragma once
#include <AK/ByteBuffer.h>
+#include <AK/Function.h>
#include <AK/Variant.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Object.h>
@@ -16,6 +17,9 @@ namespace JS {
struct ClampedU8 {
};
+// 25.1.1 Notation (read-modify-write modification function), https://tc39.es/ecma262/#sec-arraybuffer-notation
+using ReadWriteModifyFunction = Function<ByteBuffer(ByteBuffer, ByteBuffer)>;
+
class ArrayBuffer : public Object {
JS_OBJECT(ArrayBuffer, Object);
@@ -45,6 +49,8 @@ public:
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);
+ template<typename T>
+ Value get_modify_set_value(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true);
private:
virtual void visit_edges(Visitor&) override;
@@ -190,4 +196,19 @@ Value ArrayBuffer::set_value(size_t byte_index, Value value, [[maybe_unused]] bo
return js_undefined();
}
+// 25.1.2.13 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-getmodifysetvalueinbuffer
+template<typename T>
+Value ArrayBuffer::get_modify_set_value(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian)
+{
+ auto raw_bytes = numeric_to_raw_bytes<T>(global_object(), value, is_little_endian);
+
+ // FIXME: Check for shared buffer
+
+ auto raw_bytes_read = buffer_impl().slice(byte_index, sizeof(T));
+ auto raw_bytes_modified = operation(raw_bytes_read, raw_bytes);
+ raw_bytes_modified.span().copy_to(buffer_impl().span().slice(byte_index));
+
+ return raw_bytes_to_numeric<T>(global_object(), raw_bytes_read, is_little_endian);
+}
+
}
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h
index 83d40f6cc7..fb501170e1 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArray.h
+++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h
@@ -44,6 +44,8 @@ public:
virtual Value get_value_from_buffer(size_t byte_index, ArrayBuffer::Order, bool is_little_endian = true) const = 0;
// 25.1.2.12 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-setvalueinbuffer
virtual void set_value_in_buffer(size_t byte_index, Value, ArrayBuffer::Order, bool is_little_endian = true) = 0;
+ // 25.1.2.13 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-getmodifysetvalueinbuffer
+ virtual Value get_modify_set_value_in_buffer(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true) = 0;
protected:
explicit TypedArrayBase(Object& prototype)
@@ -438,6 +440,7 @@ public:
Value get_value_from_buffer(size_t byte_index, ArrayBuffer::Order order, bool is_little_endian = true) const override { return viewed_array_buffer()->template get_value<T>(byte_index, true, order, is_little_endian); }
void set_value_in_buffer(size_t byte_index, Value value, ArrayBuffer::Order order, bool is_little_endian = true) override { viewed_array_buffer()->template set_value<T>(byte_index, value, true, order, is_little_endian); }
+ Value get_modify_set_value_in_buffer(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true) override { return viewed_array_buffer()->template get_modify_set_value<T>(byte_index, value, move(operation), is_little_endian); }
protected:
TypedArray(u32 array_length, Object& prototype)