summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-07-11 11:45:21 -0400
committerLinus Groh <mail@linusgroh.de>2021-07-14 20:44:42 +0100
commit940875c9fd704ce9d7e74d3499bbdd220841d0c5 (patch)
tree4509e3f8d019672397cf43d4da55710a8f0c516b /Userland/Libraries/LibJS
parentcc3b96743a295f029ba5938157bbc7529648c95f (diff)
downloadserenity-940875c9fd704ce9d7e74d3499bbdd220841d0c5.zip
LibJS: Implement Atomics.load
Diffstat (limited to 'Userland/Libraries/LibJS')
-rw-r--r--Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp24
-rw-r--r--Userland/Libraries/LibJS/Runtime/AtomicsObject.h1
-rw-r--r--Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h1
-rw-r--r--Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.load.js54
4 files changed, 80 insertions, 0 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp b/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp
index 69cd8773c4..ce6e0dd770 100644
--- a/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp
+++ b/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp
@@ -118,6 +118,7 @@ void AtomicsObject::initialize(GlobalObject& global_object)
u8 attr = Attribute::Writable | Attribute::Configurable;
define_native_function(vm.names.add, add, 3, attr);
+ define_native_function(vm.names.load, load, 2, attr);
// 25.4.15 Atomics [ @@toStringTag ], https://tc39.es/ecma262/#sec-atomics-@@tostringtag
define_direct_property(*vm.well_known_symbol_to_string_tag(), js_string(global_object.heap(), "Atomics"), Attribute::Configurable);
@@ -141,4 +142,27 @@ JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::add)
VERIFY_NOT_REACHED();
}
+// 25.4.8 Atomics.load ( typedArray, index ), https://tc39.es/ecma262/#sec-atomics.load
+JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::load)
+{
+ auto* typed_array = typed_array_from(global_object, vm.argument(0));
+ if (!typed_array)
+ return {};
+
+ validate_integer_typed_array(global_object, *typed_array);
+ if (vm.exception())
+ return {};
+
+ auto indexed_position = validate_atomic_access(global_object, *typed_array, vm.argument(1));
+ if (!indexed_position.has_value())
+ return {};
+
+ if (typed_array->viewed_array_buffer()->is_detached()) {
+ vm.throw_exception<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
+ return {};
+ }
+
+ return typed_array->get_value_from_buffer(*indexed_position, ArrayBuffer::Order::SeqCst, true);
+}
+
}
diff --git a/Userland/Libraries/LibJS/Runtime/AtomicsObject.h b/Userland/Libraries/LibJS/Runtime/AtomicsObject.h
index 2e33dbf001..8a4e842cd9 100644
--- a/Userland/Libraries/LibJS/Runtime/AtomicsObject.h
+++ b/Userland/Libraries/LibJS/Runtime/AtomicsObject.h
@@ -20,6 +20,7 @@ public:
private:
JS_DECLARE_NATIVE_FUNCTION(add);
+ JS_DECLARE_NATIVE_FUNCTION(load);
};
}
diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
index 530cca681e..ec05f5167c 100644
--- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
+++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h
@@ -224,6 +224,7 @@ namespace JS {
P(lastIndexOf) \
P(length) \
P(link) \
+ P(load) \
P(log) \
P(log1p) \
P(log2) \
diff --git a/Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.load.js b/Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.load.js
new file mode 100644
index 0000000000..49acdeda2f
--- /dev/null
+++ b/Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.load.js
@@ -0,0 +1,54 @@
+test("invariants", () => {
+ expect(Atomics.load).toHaveLength(2);
+});
+
+test("error cases", () => {
+ expect(() => {
+ Atomics.load("not an array", 0);
+ }).toThrow(TypeError);
+
+ expect(() => {
+ const bad_array_type = new Float32Array(4);
+ Atomics.load(bad_array_type, 0);
+ }).toThrow(TypeError);
+
+ expect(() => {
+ const bad_array_type = new Uint8ClampedArray(4);
+ Atomics.load(bad_array_type, 0);
+ }).toThrow(TypeError);
+
+ expect(() => {
+ const array = new Int32Array(4);
+ Atomics.load(array, 100);
+ }).toThrow(RangeError);
+});
+
+test("basic functionality (non-BigInt)", () => {
+ [Int8Array, Int16Array, Int32Array, Uint8Array, Uint16Array, Uint32Array].forEach(ArrayType => {
+ const array = new ArrayType(4);
+ array[0] = 1;
+ array[1] = 2;
+ array[2] = 3;
+ array[3] = 4;
+
+ expect(Atomics.load(array, 0)).toBe(1);
+ expect(Atomics.load(array, 1)).toBe(2);
+ expect(Atomics.load(array, 2)).toBe(3);
+ expect(Atomics.load(array, 3)).toBe(4);
+ });
+});
+
+test("basic functionality (BigInt)", () => {
+ [BigInt64Array, BigUint64Array].forEach(ArrayType => {
+ const array = new ArrayType(4);
+ array[0] = 1n;
+ array[1] = 2n;
+ array[2] = 3n;
+ array[3] = 4n;
+
+ expect(Atomics.load(array, 0)).toBe(1n);
+ expect(Atomics.load(array, 1)).toBe(2n);
+ expect(Atomics.load(array, 2)).toBe(3n);
+ expect(Atomics.load(array, 3)).toBe(4n);
+ });
+});