ECMAScript Shared Memory and Atomics - asm.js addenda

Revised: 2016-01-22

Introduction

This document defines the changes and amendments to asm.js semantics to support the proposal for ECMAScript shared memory and atomics. Please refer to that document for full information about the semantics.

This specification is a restatement of an earlier work, along with later bug fixes. The earlier work is obsolete.

Changelog:

1Terminology

An "integer-typed array" is one of the TypedArray views Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, and Uint32Array.

A "float-typed array" is one of the TypedArray views Float32Array and Float64Array.

2Views

The heap memory passed to the asm.js module at link time must be a SharedArrayBuffer if and only if the module references the Atomics object (see below). If this constraint fails then a soft link error ensues and execution falls back to non-asm.js, cf the asm.js spec section 7.

3Atomics

There is a new known stdlib object Atomics. This object provides a number of known, static methods, a subset of the methods provided in the full specification. The atomic operations have the same dynamic semantics in asm.js as in full JS.

Note

The following Atomics names are not available as intrinsics in asm.js:

  • Atomics.futexWait()
  • Atomics.futexWake()
  • Atomics.futexWakeOrRequeue()
  • Atomics.OK
  • Atomics.NOTEQUAL
  • Atomics.TIMEDOUT

The futex methods can be accessed through the FFI (with the heap passed implicitly) and the operation result values can be expanded into constant values, as they have known values.

3.1Atomics.load(view, index)

3.1.1Static constraints

The view must name an integer-typed array mapped onto shared memory.

The index must be an expression of static type Intish. If the element byte size of view is not 1 then index must have the form C, where C is a constant, or the form E>>K, where E is some expression and K is a constant that is the log-base-2 of the element byte size of view.

The result type of Atomics.load is Int.

Note

Treating atomic accesses as "syntax" rather than as "calls" -- ie, requiring a shift for the index expression -- fits in with how they will be used and allows for simplifictions in code generation.

3.2 Atomics.store(view, index, value)

3.2.1Static constraints

The view and index arguments are constrained as for Atomics.load.

The value must be an expression of static type Intish.

The result type of Atomics.store is the actual type of value.

3.3 Atomics.exchange(view, index, value)

3.3.1Static constraints

The view, index, and value arguments are constrained as for Atomics.store.

The result type of Atomics.exchange is Int.

3.4 Atomics.add(view, index, value)

As for Atomics.exchange.

3.5 Atomics.sub(view, index, value)

As for Atomics.exchange.

3.6 Atomics.and(view, index, value)

As for Atomics.exchange.

3.7 Atomics.or(view, index, value)

As for Atomics.exchange.

3.8 Atomics.xor(view, index, value)

As for Atomics.exchange.

3.9 Atomics.compareExchange(view, index, expected, replacement)

3.9.1Static constraints

The view and index arguments are constrained as for Atomics.load.

The expected and replacement arguments must be expressions of static type Intish.

The result type of Atomics.compareExchange is Int.

3.10 Atomics.fence()

Implements a full memory barrier.

Note

Atomics.fence() is no longer a part of the Shared Memory and Atomics specification and we do not expect to reintroduce it. It is implemented in Firefox, for now, but will likely be removed.

3.10.1Static constraints

The result type of Atomics.fence is void.

3.11 Atomics.isLockFree(size)

3.11.1Static constraints

The size argument must be an integer constant.

The result type of Atomics.isLockFree is Int, a boolean value.

Note

Again, treating Atomics.isLockFree as syntax rather than as a call fits in with how it will be used and provides guarantees that it will be resolved at compile time.