@@ -10,7 +10,7 @@ use crate::{
1010 ecmascript:: {
1111 abstract_operations:: type_conversion:: {
1212 number_convert_to_integer_or_infinity, to_big_int, to_index,
13- to_integer_number_or_infinity, try_to_index, validate_index,
13+ to_integer_number_or_infinity, to_integer_or_infinity , try_to_index, validate_index,
1414 } ,
1515 builders:: ordinary_object_builder:: OrdinaryObjectBuilder ,
1616 builtins:: {
@@ -308,13 +308,63 @@ impl AtomicsObject {
308308 . map ( |v| v. into_value ( ) )
309309 }
310310
311+ /// ### [25.4.8 Atomics.isLockFree ( size )](https://tc39.es/ecma262/#sec-atomics.islockfree)
312+ ///
313+ /// > NOTE: This function is an optimization primitive. The intuition is
314+ /// > that if the atomic step of an atomic primitive (**compareExchange**,
315+ /// > **load**, **store**, **add**, **sub**, **and**, **or**, **xor**, or
316+ /// > **exchange**) on a datum of size `n` bytes will be performed without
317+ /// > the surrounding agent acquiring a lock outside the n bytes comprising
318+ /// > the datum, then **Atomics.isLockFree**(`n`) will return **true**.
319+ /// > High-performance algorithms will use this function to determine
320+ /// > whether to use locks or atomic operations in critical sections. If an
321+ /// > atomic primitive is not lock-free then it is often more efficient for
322+ /// > an algorithm to provide its own locking.
323+ /// >
324+ /// > **Atomics.isLockFree**(4) always returns **true** as that can be
325+ /// > supported on all known relevant hardware. Being able to assume this
326+ /// > will generally simplify programs.
327+ /// >
328+ /// > Regardless of the value returned by this function, all atomic
329+ /// > operations are guaranteed to be atomic. For example, they will never
330+ /// > have a visible operation take place in the middle of the operation
331+ /// > (e.g., "tearing").
311332 fn is_lock_free < ' gc > (
312333 agent : & mut Agent ,
313334 _this_value : Value ,
314- _arguments : ArgumentsList ,
335+ arguments : ArgumentsList ,
315336 gc : GcScope < ' gc , ' _ > ,
316337 ) -> JsResult < ' gc , Value < ' gc > > {
317- Err ( agent. todo ( "Atomics.isLockFree" , gc. into_nogc ( ) ) )
338+ let size = arguments. get ( 0 ) . bind ( gc. nogc ( ) ) ;
339+ // 1. Let n be ? ToIntegerOrInfinity(size).
340+ let n = to_integer_or_infinity ( agent, size. unbind ( ) , gc) ?. into_i64 ( ) ;
341+ // 2. Let AR be the Agent Record of the surrounding agent.
342+ // 3. If n = 1, return AR.[[IsLockFree1]].
343+ #[ cfg( target_has_atomic = "8" ) ]
344+ if n == 1 {
345+ return Ok ( true . into ( ) ) ;
346+ }
347+ // 4. If n = 2, return AR.[[IsLockFree2]].
348+ #[ cfg( target_has_atomic = "16" ) ]
349+ if n == 2 {
350+ return Ok ( true . into ( ) ) ;
351+ }
352+ // 5. If n = 4, return true.
353+ #[ cfg( target_has_atomic = "32" ) ]
354+ if n == 4 {
355+ return Ok ( true . into ( ) ) ;
356+ }
357+ #[ cfg( not( target_has_atomic = "32" ) ) ]
358+ const {
359+ panic ! ( "Atomics requires 32-bit lock-free atomics" )
360+ } ;
361+ // 6. If n = 8, return AR.[[IsLockFree8]].
362+ #[ cfg( target_has_atomic = "64" ) ]
363+ if n == 8 {
364+ return Ok ( true . into ( ) ) ;
365+ }
366+ // 7. Return false.
367+ Ok ( false . into ( ) )
318368 }
319369
320370 /// ### [25.4.9 Atomics.load ( typedArray, index )](https://tc39.es/ecma262/#sec-atomics.load)
0 commit comments