github.com/gopherjs/gopherjs@v1.19.0-beta1.0.20240506212314-27071a8796e4/compiler/natives/src/sync/atomic/atomic.go (about)

     1  //go:build js
     2  // +build js
     3  
     4  package atomic
     5  
     6  import (
     7  	"unsafe"
     8  
     9  	"github.com/gopherjs/gopherjs/js"
    10  )
    11  
    12  func SwapInt32(addr *int32, new int32) int32 {
    13  	old := *addr
    14  	*addr = new
    15  	return old
    16  }
    17  
    18  func SwapInt64(addr *int64, new int64) int64 {
    19  	old := *addr
    20  	*addr = new
    21  	return old
    22  }
    23  
    24  func SwapUint32(addr *uint32, new uint32) uint32 {
    25  	old := *addr
    26  	*addr = new
    27  	return old
    28  }
    29  
    30  func SwapUint64(addr *uint64, new uint64) uint64 {
    31  	old := *addr
    32  	*addr = new
    33  	return old
    34  }
    35  
    36  func SwapUintptr(addr *uintptr, new uintptr) uintptr {
    37  	old := *addr
    38  	*addr = new
    39  	return old
    40  }
    41  
    42  func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
    43  	old := *addr
    44  	*addr = new
    45  	return old
    46  }
    47  
    48  func CompareAndSwapInt32(addr *int32, old, new int32) bool {
    49  	if *addr == old {
    50  		*addr = new
    51  		return true
    52  	}
    53  	return false
    54  }
    55  
    56  func CompareAndSwapInt64(addr *int64, old, new int64) bool {
    57  	if *addr == old {
    58  		*addr = new
    59  		return true
    60  	}
    61  	return false
    62  }
    63  
    64  func CompareAndSwapUint32(addr *uint32, old, new uint32) bool {
    65  	if *addr == old {
    66  		*addr = new
    67  		return true
    68  	}
    69  	return false
    70  }
    71  
    72  func CompareAndSwapUint64(addr *uint64, old, new uint64) bool {
    73  	if *addr == old {
    74  		*addr = new
    75  		return true
    76  	}
    77  	return false
    78  }
    79  
    80  func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) bool {
    81  	if *addr == old {
    82  		*addr = new
    83  		return true
    84  	}
    85  	return false
    86  }
    87  
    88  func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) bool {
    89  	if *addr == old {
    90  		*addr = new
    91  		return true
    92  	}
    93  	return false
    94  }
    95  
    96  func AddInt32(addr *int32, delta int32) int32 {
    97  	new := *addr + delta
    98  	*addr = new
    99  	return new
   100  }
   101  
   102  func AddUint32(addr *uint32, delta uint32) uint32 {
   103  	new := *addr + delta
   104  	*addr = new
   105  	return new
   106  }
   107  
   108  func AddInt64(addr *int64, delta int64) int64 {
   109  	new := *addr + delta
   110  	*addr = new
   111  	return new
   112  }
   113  
   114  func AddUint64(addr *uint64, delta uint64) uint64 {
   115  	new := *addr + delta
   116  	*addr = new
   117  	return new
   118  }
   119  
   120  func AddUintptr(addr *uintptr, delta uintptr) uintptr {
   121  	new := *addr + delta
   122  	*addr = new
   123  	return new
   124  }
   125  
   126  func LoadInt32(addr *int32) int32 {
   127  	return *addr
   128  }
   129  
   130  func LoadInt64(addr *int64) int64 {
   131  	return *addr
   132  }
   133  
   134  func LoadUint32(addr *uint32) uint32 {
   135  	return *addr
   136  }
   137  
   138  func LoadUint64(addr *uint64) uint64 {
   139  	return *addr
   140  }
   141  
   142  func LoadUintptr(addr *uintptr) uintptr {
   143  	return *addr
   144  }
   145  
   146  func LoadPointer(addr *unsafe.Pointer) unsafe.Pointer {
   147  	return *addr
   148  }
   149  
   150  func StoreInt32(addr *int32, val int32) {
   151  	*addr = val
   152  }
   153  
   154  func StoreInt64(addr *int64, val int64) {
   155  	*addr = val
   156  }
   157  
   158  func StoreUint32(addr *uint32, val uint32) {
   159  	*addr = val
   160  }
   161  
   162  func StoreUint64(addr *uint64, val uint64) {
   163  	*addr = val
   164  }
   165  
   166  func StoreUintptr(addr *uintptr, val uintptr) {
   167  	*addr = val
   168  }
   169  
   170  func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
   171  	*addr = val
   172  }
   173  
   174  func (v *Value) Load() (x interface{}) {
   175  	return v.v
   176  }
   177  
   178  func (v *Value) Store(new interface{}) {
   179  	v.checkNew("store", new)
   180  	v.v = new
   181  }
   182  
   183  func (v *Value) Swap(new interface{}) (old interface{}) {
   184  	v.checkNew("swap", new)
   185  	old, v.v = v.v, new
   186  	return old
   187  }
   188  
   189  func (v *Value) CompareAndSwap(old, new interface{}) (swapped bool) {
   190  	v.checkNew("compare and swap", new)
   191  
   192  	if !(v.v == nil && old == nil) && !sameType(old, new) {
   193  		panic("sync/atomic: compare and swap of inconsistently typed values into Value")
   194  	}
   195  
   196  	if v.v != old {
   197  		return false
   198  	}
   199  
   200  	v.v = new
   201  
   202  	return true
   203  }
   204  
   205  func (v *Value) checkNew(op string, new interface{}) {
   206  	if new == nil {
   207  		panic("sync/atomic: " + op + " of nil value into Value")
   208  	}
   209  
   210  	if v.v != nil && !sameType(new, v.v) {
   211  		panic("sync/atomic: " + op + " of inconsistently typed value into Value")
   212  	}
   213  }
   214  
   215  // sameType returns true if x and y contain the same concrete Go types.
   216  func sameType(x, y interface{}) bool {
   217  	// This relies upon the fact that an interface in GopherJS is represented
   218  	// by the instance of the underlying Go type. Primitive values (e.g. bools)
   219  	// are still wrapped into a Go type object, so we can rely upon constructors
   220  	// existing and differing for different types.
   221  	return js.InternalObject(x).Get("constructor") == js.InternalObject(y).Get("constructor")
   222  }
   223  
   224  //gopherjs:purge for go1.19 without generics
   225  type Pointer[T any] struct{}