ECMAScript® 2024 Language Specification

Draft ECMA-262 / December 6, 2023

9.7 Agents

An agent comprises a set of ECMAScript execution contexts, an execution context stack, a running execution context, an Agent Record, and an executing thread. Except for the executing thread, the constituents of an agent belong exclusively to that agent.

An agent's executing thread executes algorithmic steps on the agent's execution contexts independently of other agents, except that an executing thread may be used as the executing thread by multiple agents, provided none of the agents sharing the thread have an Agent Record whose [[CanBlock]] field is true.

Note 1

Some web browsers share a single executing thread across multiple unrelated tabs of a browser window, for example.

While an agent's executing thread is executing algorithmic steps, the agent is the surrounding agent for those steps. The steps use the surrounding agent to access the specification-level execution objects held within the agent: the running execution context, the execution context stack, and the Agent Record's fields.

An agent signifier is a globally-unique opaque value used to identify an Agent.

Table 29: Agent Record Fields
Field Name Value Meaning
[[LittleEndian]] a Boolean The default value computed for the isLittleEndian parameter when it is needed by the algorithms GetValueFromBuffer and SetValueInBuffer. The choice is implementation-defined and should be the alternative that is most efficient for the implementation. Once the value has been observed it cannot change.
[[CanBlock]] a Boolean Determines whether the agent can block or not.
[[Signifier]] an agent signifier Uniquely identifies the agent within its agent cluster.
[[IsLockFree1]] a Boolean true if atomic operations on one-byte values are lock-free, false otherwise.
[[IsLockFree2]] a Boolean true if atomic operations on two-byte values are lock-free, false otherwise.
[[IsLockFree8]] a Boolean true if atomic operations on eight-byte values are lock-free, false otherwise.
[[CandidateExecution]] a candidate execution Record See the memory model.
[[KeptAlive]] a List of either Objects or Symbols Initially a new empty List, representing the list of objects and/or symbols to be kept alive until the end of the current Job

Once the values of [[Signifier]], [[IsLockFree1]], and [[IsLockFree2]] have been observed by any agent in the agent cluster they cannot change.

Note 2

The values of [[IsLockFree1]] and [[IsLockFree2]] are not necessarily determined by the hardware, but may also reflect implementation choices that can vary over time and between ECMAScript implementations.

There is no [[IsLockFree4]] field: 4-byte atomic operations are always lock-free.

In practice, if an atomic operation is implemented with any type of lock the operation is not lock-free. Lock-free does not imply wait-free: there is no upper bound on how many machine steps may be required to complete a lock-free atomic operation.

That an atomic access of size n is lock-free does not imply anything about the (perceived) atomicity of non-atomic accesses of size n, specifically, non-atomic accesses may still be performed as a sequence of several separate memory accesses. See ReadSharedMemory and WriteSharedMemory for details.

Note 3

An agent is a specification mechanism and need not correspond to any particular artefact of an ECMAScript implementation.

9.7.1 AgentSignifier ( )

The abstract operation AgentSignifier takes no arguments and returns an agent signifier. It performs the following steps when called:

  1. Let AR be the Agent Record of the surrounding agent.
  2. Return AR.[[Signifier]].

9.7.2 AgentCanSuspend ( )

The abstract operation AgentCanSuspend takes no arguments and returns a Boolean. It performs the following steps when called:

  1. Let AR be the Agent Record of the surrounding agent.
  2. Return AR.[[CanBlock]].

In some environments it may not be reasonable for a given agent to suspend. For example, in a web browser environment, it may be reasonable to disallow suspending a document's main event handling thread, while still allowing workers' event handling threads to suspend.