From 1a3e1bff7b10287a206b7d22178965b2f03ef16a Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 12 Jul 2021 10:35:14 -0400 Subject: [PATCH] LibJS: Implement Atomics.isLockFree --- .../Libraries/LibJS/Runtime/AtomicsObject.cpp | 19 ++++++++++++++ .../Libraries/LibJS/Runtime/AtomicsObject.h | 1 + .../LibJS/Runtime/CommonPropertyNames.h | 1 + .../builtins/Atomics/Atomics.isLockFree.js | 25 +++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.isLockFree.js diff --git a/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp b/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp index 3dc0c051b5..b593509511 100644 --- a/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp @@ -122,6 +122,7 @@ void AtomicsObject::initialize(GlobalObject& global_object) define_native_function(vm.names.and_, and_, 3, attr); define_native_function(vm.names.compareExchange, compare_exchange, 4, attr); define_native_function(vm.names.exchange, exchange, 3, attr); + define_native_function(vm.names.isLockFree, is_lock_free, 1, attr); define_native_function(vm.names.load, load, 2, attr); define_native_function(vm.names.or_, or_, 3, attr); define_native_function(vm.names.store, store, 3, attr); @@ -262,6 +263,24 @@ JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::exchange) VERIFY_NOT_REACHED(); } +// 25.4.7 Atomics.isLockFree ( size ), https://tc39.es/ecma262/#sec-atomics.islockfree +JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::is_lock_free) +{ + auto size = vm.argument(0).to_integer_or_infinity(global_object); + if (vm.exception()) + return {}; + + if (size == 1) + return Value(AK::atomic_is_lock_free()); + if (size == 2) + return Value(AK::atomic_is_lock_free()); + if (size == 4) + return Value(true); + if (size == 8) + return Value(AK::atomic_is_lock_free()); + return Value(false); +} + // 25.4.8 Atomics.load ( typedArray, index ), https://tc39.es/ecma262/#sec-atomics.load JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::load) { diff --git a/Userland/Libraries/LibJS/Runtime/AtomicsObject.h b/Userland/Libraries/LibJS/Runtime/AtomicsObject.h index 95106db872..2b55f9671b 100644 --- a/Userland/Libraries/LibJS/Runtime/AtomicsObject.h +++ b/Userland/Libraries/LibJS/Runtime/AtomicsObject.h @@ -23,6 +23,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(and_); JS_DECLARE_NATIVE_FUNCTION(compare_exchange); JS_DECLARE_NATIVE_FUNCTION(exchange); + JS_DECLARE_NATIVE_FUNCTION(is_lock_free); JS_DECLARE_NATIVE_FUNCTION(load); JS_DECLARE_NATIVE_FUNCTION(or_); JS_DECLARE_NATIVE_FUNCTION(store); diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index ccb146b955..b555d8501c 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -213,6 +213,7 @@ namespace JS { P(isFinite) \ P(isFrozen) \ P(isInteger) \ + P(isLockFree) \ P(isNaN) \ P(isPrototypeOf) \ P(isSafeInteger) \ diff --git a/Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.isLockFree.js b/Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.isLockFree.js new file mode 100644 index 0000000000..dd9470be49 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Atomics/Atomics.isLockFree.js @@ -0,0 +1,25 @@ +test("invariants", () => { + expect(Atomics.isLockFree).toHaveLength(1); +}); + +test("basic functionality", () => { + expect(Atomics.isLockFree(4)).toBeTrue(); + + // Can't assume the return value of sizes 1, 2, and 8, but they shouldn't change. + expect(Atomics.isLockFree(1)).toBe(Atomics.isLockFree(1)); + expect(Atomics.isLockFree(2)).toBe(Atomics.isLockFree(2)); + expect(Atomics.isLockFree(8)).toBe(Atomics.isLockFree(8)); + + expect(Atomics.isLockFree(0)).toBeFalse(); + expect(Atomics.isLockFree(3)).toBeFalse(); + expect(Atomics.isLockFree(5)).toBeFalse(); + expect(Atomics.isLockFree(6)).toBeFalse(); + expect(Atomics.isLockFree(7)).toBeFalse(); + expect(Atomics.isLockFree(9)).toBeFalse(); + expect(Atomics.isLockFree(10)).toBeFalse(); + expect(Atomics.isLockFree(Infinity)).toBeFalse(); + + expect(Atomics.isLockFree("not a number")).toBeFalse(); + expect(Atomics.isLockFree(new Float32Array(4))).toBeFalse(); + expect(Atomics.isLockFree(String.prototype)).toBeFalse(); +});