ECMA-262 (12th Edition) ECMAScript 2021 Language Specification - page 20

 

  Главная      Manuals     ECMA-262 (12th Edition) ECMAScript 2021 Language Specification

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     18      19      20      21     ..

 

 

 

ECMA-262 (12th Edition) ECMAScript 2021 Language Specification - page 20

 

 

Job

 is an 

Abstract Closure

 with no parameters that initiates an ECMAScript computation when no other

ECMAScript computation is currently in progress.

Jobs are scheduled for execution by ECMAScript 

host

 environments. This specification describes the 

host hook

HostEnqueuePromiseJob

 to schedule one kind of job; hosts may define additional 

abstract operations

 which schedule

jobs. Such operations accept a 

Job

 

Abstract Closure

 as the parameter and schedule it to be performed at some future

time. Their implementations must conform to the following requirements:

At some future point in time, when there is no 

running execution context

 and the 

execution context stack

 is

empty, the implementation must:

1.  Perform any 

host-defined

 preparation steps.

2. 

Invoke

 the 

Job

 

Abstract Closure

.

3.  Perform any 

host-defined

 cleanup steps, after which the 

execution context stack

 must be empty.

Only one 

Job

 may be actively undergoing evaluation at any point in time.

Once evaluation of a 

Job

 starts, it must run to completion before evaluation of any other 

Job

 starts.

The 

Abstract Closure

 must return a normal completion, implementing its own handling of errors.

NOTE 1

At any particular time, 

scriptOrModule

 (a 

Script Record

, a 

Module Record

, or 

null

) is the 

active script or module

 if all of

the following conditions are true:

GetActiveScriptOrModule

() is 

scriptOrModule

.

If 

scriptOrModule

 is a 

Script Record

 or 

Module Record

, let 

ec

 be the topmost 

execution context

 on the 

execution

context stack

 whose ScriptOrModule component is 

scriptOrModule

. The 

Realm

 component of 

ec

 is

scriptOrModule

.[[Realm]].

At any particular time, an execution is 

prepared to evaluate ECMAScript code

 if all of the following conditions are true:

The 

execution context stack

 is not empty.

The 

Realm

 component of the topmost 

execution context

 on the 

execution context stack

 is a 

Realm Record

.

NOTE 2

Particular kinds of Jobs have additional conformance requirements.

JobCallback Record

 is a 

Record

 value used to store a 

function object

 and a 

host-defined

 value. Function objects that

Host

 environments are not required to treat Jobs uniformly with respect to scheduling. For

example, web browsers and Node.js treat Promise-handling Jobs as a higher priority than other
work; future features may add Jobs that are not treated at such a high priority.

Host

 environments may prepare an execution to evaluate code by pushing execution contexts

onto the 

execution context stack

. The specific steps ar

implementation-defined

.

The specific choice of 

Realm

 is up to the 

host environment

. This initial 

execution context

 and

Realm

 is only in use before any callback function is invoked. When a callback function related to

Job

, like a Promise handler, is invoked, the invocation pushes its own 

execution context

 and

Realm

.

9.4  Jobs and Host Operations to Enqueue Jobs

9.4.1  JobCallback Records

211

are invoked via a 

Job

 enqueued by the 

host

 may have additional 

host-defined

 context. To propagate the state, 

Job

Abstract Closures should not capture and call function objects directly. Instead, use 

HostMakeJobCallback

 and

HostCallJobCallback

.

NOTE

JobCallback Records have the fields listed in 

Table 27

.

Table 27: 

JobCallback Record

 Fields

Field Name

Value

Meaning

[[Callback]]

function object

The function to invoke when the 

Job

 is invoked.

[[HostDefined]] Any, default value is 

empty

. Field reserved for use by hosts.

The 

host-defined

 abstract operation HostMakeJobCallback takes argument 

callback

 (a 

function object

).

The implementation of HostMakeJobCallback must conform to the following requirements:

It must always complete normally (i.e., not return an 

abrupt completion

).

It must always return a 

JobCallback Record

 whose [[Callback]] field is 

callback

.

The default implementation of HostMakeJobCallback performs the following steps when called:

1. 

Assert

IsCallable

(

callback

) is 

true

.

2.  Return the 

JobCallback Record

 { [[Callback]]: 

callback

, [[HostDefined]]: 

empty

 }.

ECMAScript hosts that are not web browsers must use the default implementation of HostMakeJobCallback.

NOTE

The 

host-defined

 abstract operation HostCallJobCallback takes arguments 

jobCallback

 (a 

JobCallback Record

), 

V

 (an

ECMAScript language value

), and 

argumentsList

 (a 

List

 of ECMAScript language values).

The implementation of HostCallJobCallback must conform to the following requirements:

It must always perform and return the result of 

Call

(

jobCallback

.[[Callback]], 

V

argumentsList

).

NOTE

The WHATWG HTML specification (

https://html.spec.whatwg.org/

), for example, uses the

host-defined

 value to propagate the incumbent settings object for Promise callbacks.

This is called at the time that the callback is passed to the function that is responsible for its being
eventually scheduled and run. For example, 

promise.then(thenAction)

promise.then(thenAction)

 calls

MakeJobCallback on 

thenAction

thenAction

 at the time of invoking 

Promise.prototype.then

Promise.prototype.then

,

not at the time of scheduling the reaction 

Job

.

This requirement means that hosts cannot change the [[Call]] behaviour of function objects
defined in this specification.

9.4.2  HostMakeJobCallback ( 

callback

 )

9.4.3  HostCallJobCallback ( 

jobCallback

V

argumentsList

 )

212

The default implementation of HostCallJobCallback performs the following steps when called:

1. 

Assert

IsCallable

(

jobCallback

.[[Callback]]) is 

true

.

2.  Return ? 

Call

(

jobCallback

.[[Callback]], 

V

argumentsList

).

ECMAScript hosts that are not web browsers must use the default implementation of HostCallJobCallback.

The 

host-defined

 abstract operation HostEnqueuePromiseJob takes arguments 

job

 (a 

Job

 

Abstract Closure

) and 

realm

(a 

Realm Record

 or 

null

). It schedules 

job

 to be performed at some future time. The Abstract Closures used with this

algorithm are intended to be related to the handling of Promises, or otherwise, to be scheduled with equal priority to
Promise handling operations.

The implementation of HostEnqueuePromiseJob must conform to the requirements in 

9.4

 as well as the following:

If 

realm

 is not 

null

, each time 

job

 is invoked the implementation must perform 

implementation-defined

 steps

such that execution is 

prepared to evaluate ECMAScript code

 at the time of 

job

's invocation.

Let 

scriptOrModule

 be 

GetActiveScriptOrModule

() at the time HostEnqueuePromiseJob is invoked. If 

realm

 is

not 

null

, each time 

job

 is invoked the implementation must perform 

implementation-defined

 steps such that

scriptOrModule

 is the 

active script or module

 at the time of 

job

's invocation.

Jobs must run in the same order as the HostEnqueuePromiseJob invocations that scheduled them.

NOTE

The abstract operation InitializeHostDefinedRealm takes no arguments. It performs the following steps when called:

1.  Let 

realm

 be 

CreateRealm

().

2.  Let 

newContext

 be a new 

execution context

.

3.  Set the Function of 

newContext

 to 

null

.

4.  Set the 

Realm

 of 

newContext

 to 

realm

.

5.  Set the ScriptOrModule of 

newContext

 to 

null

.

6.  Push 

newContext

 onto the 

execution context stack

newContext

 is now the 

running execution context

.

7.  If the 

host

 requires use of an 

exotic object

 to serve as 

realm

's 

global object

, let 

global

 be such an object created in

host-defined

 manner. Otherwise, let 

global

 be 

undefined

, indicating that an 

ordinary object

 should be created

as the 

global object

.

8.  If the 

host

 requires that the 

this

this

 binding in 

realm

's global scope return an object other than the 

global object

,

let 

thisValue

 be such an object created in a 

host-defined

 manner. Otherwise, let 

thisValue

 be 

undefined

,

The 

realm

 for Jobs returned by 

NewPromiseResolveThenableJob

 is usually the result of calling

GetFunctionRealm

 on the 

then

 

function object

. The 

realm

 for Jobs returned by

NewPromiseReactionJob

 is usually the result of calling 

GetFunctionRealm

 on the handler if the

handler is not 

undefined

. If the handler is 

undefined

realm

 is 

null

. For both kinds of Jobs, when

GetFunctionRealm

 completes abnormally (i.e. called on a revoked Proxy), 

realm

 is the current

Realm

 at the time of the 

GetFunctionRealm

 call. When the 

realm

 is 

null

, no user ECMAScript

code will be evaluated and no new ECMAScript objects (e.g. Error objects) will be created. The
WHATWG HTML specification (

https://html.spec.whatwg.org/

), for example, uses 

realm

 to

check for the ability to run script and for the 

entry

 concept.

9.4.4  HostEnqueuePromiseJob ( 

job

realm

 )

9.5  InitializeHostDefinedRealm ( )

213

indicating that 

realm

's global 

this

this

 binding should be the 

global object

.

9.  Perform 

SetRealmGlobalObject

(

realm

global

thisValue

).

10.  Let 

globalObj

 be ? 

SetDefaultGlobalBindings

(

realm

).

11.  Create any 

host-defined

 

global object

 properties on 

globalObj

.

12.  Return 

NormalCompletion

(

empty

).

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 a job 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]] property is 

true

.

NOTE 1

While an 

agent

's 

executing thread

 executes jobs, the 

agent

 is the 

surrounding agent

 for the code in those jobs. The code

uses 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.

Some web browsers share a single 

executing thread

 across multiple unrelated tabs of a browser

window, for example.

9.6  Agents

214

Table 28: 

Agent Record

 Fields

Field Name

Value

Meaning

[[LittleEndian]]

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]]

Boolean

Determines whether the 

agent

 can block or not.

[[Signifier]]

Any
globally-
unique
value

Uniquely identifies the 

agent

 within its 

agent cluster

.

[[IsLockFree1]]

Boolean

true

 if atomic operations on one-byte values are lock-free, 

false

 otherwise.

[[IsLockFree2]]

Boolean

true

 if atomic operations on two-byte values are lock-free, 

false

 otherwise.

[[IsLockFree8]]

Boolean

true

 if atomic operations on eight-byte values are lock-free, 

false

 otherwise.

[[CandidateExecution]] A

candidate
execution
Record

See the 

memory model

.

[[KeptAlive]]

List

 of

objects

Initially a new empty 

List

, representing the list of objects 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]] property: 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.

215

NOTE 3

The abstract operation AgentSignifier takes no arguments. It performs the following steps when called:

1.  Let 

AR

 be the 

Agent Record

 of the 

surrounding agent

.

2.  Return 

AR

.[[Signifier]].

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

1.  Let 

AR

 be the 

Agent Record

 of the 

surrounding agent

.

2.  Return 

AR

.[[CanBlock]].

NOTE

An 

agent cluster

 is a maximal set of agents that can communicate by operating on shared memory.

NOTE 1

Every 

agent

 belongs to exactly one agent cluster.

NOTE 2

All agents within a cluster must have the same value for the [[LittleEndian]] property in their respective 

Agent

Records.

NOTE 3

All agents within a cluster must have the same values for the [[IsLockFree1]] property in their respective 

Agent

Records; similarly for the [[IsLockFree2]] property.

An 

agent

 is a specification mechanism and need not correspond to any particular artefact of an

ECMAScript implementation.

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.

Programs within different agents may share memory by unspecified means. At a minimum, the
backing memory for SharedArrayBuffer objects can be shared among the agents in the cluster.

There may be agents that can communicate by message passing that cannot share memory; they
are never in the same agent cluster.

The agents in a cluster need not all be alive at some particular point in time. If 

agent

 

A

 creates

another 

agent

 

B

, after which 

A

 terminates and 

B

 creates 

agent

 

C

, the three agents are in the same

cluster if 

A

 could share some memory with 

B

 and 

B

 could share some memory with 

C

.

If different agents within an agent cluster have different values of [[LittleEndian]] it becomes
hard to use shared memory for multi-byte data.

9.6.1  AgentSignifier ( )

9.6.2  AgentCanSuspend ( )

9.7  Agent Clusters

216

All agents within a cluster must have different values for the [[Signifier]] property in their respective 

Agent

 Records.

An embedding may deactivate (stop forward progress) or activate (resume forward progress) an 

agent

 without the

agent

's knowledge or cooperation. If the embedding does so, it must not leave some agents in the cluster active while

other agents in the cluster are deactivated indefinitely.

NOTE 4

An embedding may terminate an 

agent

 without any of the 

agent

's cluster's other agents' prior knowledge or

cooperation. If an 

agent

 is terminated not by programmatic action of its own or of another 

agent

 in the cluster but by

forces external to the cluster, then the embedding must choose one of two strategies: Either terminate all the agents in
the cluster, or provide reliable APIs that allow the agents in the cluster to coordinate so that at least one remaining
member of the cluster will be able to detect the termination, with the termination data containing enough information
to identify the 

agent

 that was terminated.

NOTE 5

Prior to any evaluation of any ECMAScript code by any 

agent

 in a cluster, the [[CandidateExecution]] field of the

Agent Record

 for all agents in the cluster is set to the initial 

candidate execution

. The initial 

candidate execution

 is an

empty candidate execution

 whose [[EventsRecords]] field is a 

List

 containing, for each 

agent

, an 

Agent Events Record

whose [[AgentSignifier]] field is that 

agent

's signifier, and whose [[EventList]] and [[AgentSynchronizesWith]] fields

are empty Lists.

NOTE 6

NOTE 7

The purpose of the preceding restriction is to avoid a situation where an 

agent

 deadlocks or

starves because another 

agent

 has been deactivated. For example, if an HTML shared worker that

has a lifetime independent of documents in any windows were allowed to share memory with
the dedicated worker of such an independent document, and the document and its dedicated
worker were to be deactivated while the dedicated worker holds a lock (say, the document is
pushed into its window's history), and the shared worker then tries to acquire the lock, then the
shared worker will be blocked until the dedicated worker is activated again, if ever. Meanwhile
other workers trying to access the shared worker from other windows will starve.

The implication of the restriction is that it will not be possible to share memory between agents
that don't belong to the same suspend/wake collective within the embedding.

Examples of that type of termination are: operating systems or users terminating agents that are
running in separate processes; the embedding itself terminating an 

agent

 that is running in-

process with the other agents when per-

agent

 resource accounting indicates that the 

agent

 is

runaway.

All agents in an agent cluster share the same 

candidate execution

 in its 

Agent Record

's

[[CandidateExecution]] field. The 

candidate execution

 is a specification mechanism used by the

memory model

.

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

9.8  Forward Progress

217

For an 

agent

 to 

make forward progress

 is for it to perform an evaluation step according to this specification.

An 

agent

 becomes 

blocked

 when its 

running execution context

 waits synchronously and indefinitely for an external

event. Only agents whose 

Agent Record

's [[CanBlock]] property is 

true

 can become blocked in this sense. An 

unblocked

agent

 is one that is not blocked.

Implementations must ensure that:

every unblocked 

agent

 with a dedicated 

executing thread

 eventually makes forward progress

in a set of agents that share an 

executing thread

, one 

agent

 eventually makes forward progress

an 

agent

 does not cause another 

agent

 to become blocked except via explicit APIs that provide blocking.

NOTE

This specification does not make any guarantees that any object will be garbage collected. Objects which are not 

live

may be released after long periods of time, or never at all. For this reason, this specification uses the term "may" when
describing behaviour triggered by garbage collection.

The semantics of 

WeakRef

 and 

FinalizationRegistry

 objects is based on two operations which happen at particular

points in time:

When 

WeakRef.prototype.deref

WeakRef.prototype.deref

 is called, the referent (if 

undefined

 is not returned) is kept alive so

that subsequent, synchronous accesses also return the object. This list is reset when synchronous work is done
using the 

ClearKeptObjects

 abstract operation.

When an object which is registered with a 

FinalizationRegistry

 becomes unreachable, a call of the

FinalizationRegistry

's cleanup callback may eventually be made, after synchronous ECMAScript execution

completes. The 

FinalizationRegistry

 cleanup is performed with the 

CleanupFinalizationRegistry

 abstract

operation.

Neither of these actions (

ClearKeptObjects

 or 

CleanupFinalizationRegistry

) may interrupt synchronous ECMAScript

execution. Because hosts may assemble longer, synchronous ECMAScript execution runs, this specification defers the
scheduling of 

ClearKeptObjects

 and 

CleanupFinalizationRegistry

 to the 

host environment

.

Some ECMAScript implementations include garbage collector implementations which run in the background,
including when ECMAScript is idle. Letting the 

host environment

 schedule 

CleanupFinalizationRegistry

 allows it to

resume ECMAScript execution in order to run finalizer work, which may free up held values, reducing overall
memory usage.

For some set of objects 

S

, a 

hypothetical WeakRef-oblivious

 execution with respect to 

S

 is an execution whereby the

abstract operation 

WeakRefDeref

 of a 

WeakRef

 whose referent is an element of 

S

 always returns 

undefined

.

This, along with the liveness guarantee in the 

memory model

, ensures that all 

SeqCst

 writes

eventually become observable to all agents.

9.9  Processing Model of WeakRef and FinalizationRegistry Objects

9.9.1  Objectives

9.9.2  Liveness

218

NOTE 1

NOTE 2

NOTE 3

At any point during evaluation, a set of objects 

S

 is considered 

live

 if either of the following conditions is met:

Any element in 

S

 is included in any 

agent

's [[KeptAlive]] 

List

.

There exists a valid future hypothetical WeakRef-oblivious execution with respect to 

S

 that observes the Object

value of any object in 

S

.

NOTE 4

NOTE 5

NOTE 6

At any time, if a set of objects 

S

 is not 

live

, an ECMAScript implementation may perform the following steps

atomically:

1.  For each element 

obj

 of 

S

, do

a.  For each 

WeakRef

 

ref

 such that 

ref

.[[WeakRefTarget]] is 

obj

, do

i.  Set 

ref

.[[WeakRefTarget]] to 

empty

.

WeakRef

-obliviousness, together with liveness, capture two notions. One, that a 

WeakRef

 itself

does not keep an object alive. Two, that cycles in liveness does not imply that an object is live. To
be concrete, if determining 

obj

's liveness depends on determining the liveness of another

WeakRef

 referent, 

obj2

obj2

's liveness cannot assume 

obj

's liveness, which would be circular

reasoning.

WeakRef

-obliviousness is defined on sets of objects instead of individual objects to account for

cycles. If it were defined on individual objects, then an object in a cycle will be considered live
even though its Object value is only observed via WeakRefs of other objects in the cycle.

Colloquially, we say that an individual object is live if every set of objects containing it is live.

The intuition the second condition above intends to capture is that an object is live if its identity
is observable via non-

WeakRef

 means. An object's identity may be observed by observing a strict

equality comparison between objects or observing the object being used as key in a Map.

Presence of an object in a field, an internal slot, or a property does not imply that the object is
live. For example if the object in question is never passed back to the program, then it cannot be
observed.

This is the case for keys in a WeakMap, members of a WeakSet, as well as the [[WeakRefTarget]]
and [[UnregisterToken]] fields of a 

FinalizationRegistry

 Cell record.

The above definition implies that, if a key in a WeakMap is not live, then its corresponding value
is not necessarily live either.

Liveness is the lower bound for guaranteeing which WeakRefs engines must not empty. Liveness
as defined here is undecidable. In practice, engines use conservative approximations such as
reachability. There is expected to be significant implementation leeway.

9.9.3  Execution

219

b.  For each 

FinalizationRegistry

 

fg

 such that 

fg

.[[Cells]] contains a 

Record

 

cell

 such that 

cell

.

[[WeakRefTarget]] is 

obj

, do

i.  Set 

cell

.[[WeakRefTarget]] to 

empty

.

ii.  Optionally, perform ! 

HostEnqueueFinalizationRegistryCleanupJob

(

fg

).

c.  For each WeakMap 

map

 such that 

map

.[[WeakMapData]] contains a 

Record

 

r

 such that 

r

.[[Key]] is 

obj

, do

i.  Set 

r

.[[Key]] to 

empty

.

ii.  Set 

r

.[[Value]] to 

empty

.

d.  For each WeakSet 

set

 such that 

set

.[[WeakSetData]] contains 

obj

, do

i.  Replace the element of 

set

.[[WeakSetData]] whose value is 

obj

 with an element whose value is

empty

.

NOTE 1

NOTE 2

The abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument 

finalizationRegistry

 (a

FinalizationRegistry

). HostEnqueueFinalizationRegistryCleanupJob is an 

implementation-defined

 abstract operation

that is expected to call 

CleanupFinalizationRegistry

(

finalizationRegistry

) at some point in the future, if possible. The

host

's responsibility is to make this call at a time which does not interrupt synchronous ECMAScript code execution.

Together with the definition of liveness, this clause prescribes legal optimizations that an
implementation may apply regarding WeakRefs.

It is possible to access an object without observing its identity. Optimizations such as dead
variable elimination and scalar replacement on properties of non-escaping objects whose identity
is not observed are allowed. These optimizations are thus allowed to observably empty
WeakRefs that point to such objects.

On the other hand, if an object's identity is observable, and that object is in the [[WeakRefTarget]]
internal slot of a 

WeakRef

, optimizations such as rematerialization that observably empty the

WeakRef

 are prohibited.

Because calling 

HostEnqueueFinalizationRegistryCleanupJob

 is optional, registered objects in a

FinalizationRegistry

 do not necessarily hold that 

FinalizationRegistry

 

live

. Implementations may

omit 

FinalizationRegistry

 callbacks for any reason, e.g., if the 

FinalizationRegistry

 itself becomes

dead, or if the application is shutting down.

Implementations are not obligated to empty WeakRefs for maximal sets of non-

live

 objects.

If an implementation chooses a non-

live

 set 

S

 in which to empty WeakRefs, it must empty

WeakRefs for all objects in 

S

 simultaneously. In other words, an implementation must not empty

WeakRef

 pointing to an object 

obj

 without emptying out other WeakRefs that, if not emptied,

could result in an execution that observes the Object value of 

obj

.

9.9.4  Host Hooks

9.9.4.1  HostEnqueueFinalizationRegistryCleanupJob ( 

finalizationRegistry

 )

9.10  ClearKeptObjects ( )

220

The abstract operation ClearKeptObjects takes no arguments. ECMAScript implementations are expected to call
ClearKeptObjects when a synchronous sequence of ECMAScript executions completes. It performs the following steps
when called:

1.  Let 

agentRecord

 be the 

surrounding agent

's 

Agent Record

.

2.  Set 

agentRecord

.[[KeptAlive]] to a new empty 

List

.

The abstract operation AddToKeptObjects takes argument 

object

 (an Object). It performs the following steps when

called:

1.  Let 

agentRecord

 be the 

surrounding agent

's 

Agent Record

.

2.  Append 

object

 to 

agentRecord

.[[KeptAlive]].

NOTE

The abstract operation CleanupFinalizationRegistry takes argument 

finalizationRegistry

 (a 

FinalizationRegistry

). It

performs the following steps when called:

1. 

Assert

finalizationRegistry

 has [[Cells]] and [[CleanupCallback]] internal slots.

2.  Let 

callback

 be 

finalizationRegistry

.[[CleanupCallback]].

3.  While 

finalizationRegistry

.[[Cells]] contains a 

Record

 

cell

 such that 

cell

.[[WeakRefTarget]] is 

empty

, an

implementation may perform the following steps:

a.  Choose any such 

cell

.

b.  Remove 

cell

 from 

finalizationRegistry

.[[Cells]].

c.  Perform ? 

Call

(

callback

undefined

, « 

cell

.[[HeldValue]] »).

4.  Return 

NormalCompletion

(

undefined

).

All ordinary objects have an internal slot called [[Prototype]]. The value of this internal slot is either 

null

 or an object

and is used for implementing inheritance. Data properties of the [[Prototype]] object are inherited (and visible as
properties of the child object) for the purposes of get access, but not for set access. Accessor properties are inherited
for both get access and set access.

Every 

ordinary object

 has a Boolean-valued [[Extensible]] internal slot which is used to fulfill the extensibility-related

internal method invariants specified in 

6.1.7.3

. Namely, once the value of an object's [[Extensible]] internal slot has

been set to 

false

, it is no longer possible to add properties to the object, to modify the value of the object's

When the abstract operation AddToKeptObjects is called with a target object reference, it adds
the target to a list that will point strongly at the target until 

ClearKeptObjects

 is called.

9.11  AddToKeptObjects ( 

object

 )

9.12  CleanupFinalizationRegistry ( 

finalizationRegistry

 )

10  Ordinary and Exotic Objects Behaviours

10.1  Ordinary Object Internal Methods and Internal Slots

221

[[Prototype]] internal slot, or to subsequently change the value of [[Extensible]] to 

true

.

In the following algorithm descriptions, assume 

O

 is an 

ordinary object

P

 is a property key value, 

V

 is any

ECMAScript language value

, and 

Desc

 is a 

Property Descriptor

 record.

Each 

ordinary object

 internal method delegates to a similarly-named abstract operation. If such an abstract operation

depends on another internal method, then the internal method is invoked on 

O

 rather than calling the similarly-

named abstract operation directly. These semantics ensure that exotic objects have their overridden internal methods
invoked when 

ordinary object

 internal methods are applied to them.

The [[GetPrototypeOf]] internal method of an 

ordinary object

 

O

 takes no arguments. It performs the following steps

when called:

1.  Return ! 

OrdinaryGetPrototypeOf

(

O

).

The abstract operation OrdinaryGetPrototypeOf takes argument 

O

 (an Object). It performs the following steps when

called:

1.  Return 

O

.[[Prototype]].

The [[SetPrototypeOf]] internal method of an 

ordinary object

 

O

 takes argument 

V

 (an Object or 

null

). It performs the

following steps when called:

1.  Return ! 

OrdinarySetPrototypeOf

(

O

V

).

The abstract operation OrdinarySetPrototypeOf takes arguments 

O

 (an Object) and 

V

 (an 

ECMAScript language

value

). It performs the following steps when called:

1. 

Assert

: Either 

Type

(

V

) is Object or 

Type

(

V

) is Null.

2.  Let 

current

 be 

O

.[[Prototype]].

3.  If 

SameValue

(

V

current

) is 

true

, return 

true

.

4.  Let 

extensible

 be 

O

.[[Extensible]].

5.  If 

extensible

 is 

false

, return 

false

.

6.  Let 

p

 be 

V

.

7.  Let 

done

 be 

false

.

8.  Repeat, while 

done

 is 

false

,

a.  If 

p

 is 

null

, set 

done

 to 

true

.

b.  Else if 

SameValue

(

p

O

) is 

true

, return 

false

.

c.  Else,

i.  If 

p

.[[GetPrototypeOf]] is not the 

ordinary object

 internal method defined in 

10.1.1

, set 

done

 to

true

.

ii.  Else, set 

p

 to 

p

.[[Prototype]].

10.1.1  [[GetPrototypeOf]] ( )

10.1.1.1  OrdinaryGetPrototypeOf ( 

O

 )

10.1.2  [[SetPrototypeOf]] ( 

V

 )

10.1.2.1  OrdinarySetPrototypeOf ( 

O

V

 )

222

9.  Set 

O

.[[Prototype]] to 

V

.

10.  Return 

true

.

NOTE

The [[IsExtensible]] internal method of an 

ordinary object

 

O

 takes no arguments. It performs the following steps when

called:

1.  Return ! 

OrdinaryIsExtensible

(

O

).

The abstract operation OrdinaryIsExtensible takes argument 

O

 (an Object). It performs the following steps when

called:

1.  Return 

O

.[[Extensible]].

The [[PreventExtensions]] internal method of an 

ordinary object

 

O

 takes no arguments. It performs the following steps

when called:

1.  Return ! 

OrdinaryPreventExtensions

(

O

).

The abstract operation OrdinaryPreventExtensions takes argument 

O

 (an Object). It performs the following steps

when called:

1.  Set 

O

.[[Extensible]] to 

false

.

2.  Return 

true

.

The [[GetOwnProperty]] internal method of an 

ordinary object

 

O

 takes argument 

P

 (a property key). It performs the

following steps when called:

1.  Return ! 

OrdinaryGetOwnProperty

(

O

P

).

The abstract operation OrdinaryGetOwnProperty takes arguments 

O

 (an Object) and 

P

 (a property key). It performs

the following steps when called:

1. 

Assert

IsPropertyKey

(

P

) is 

true

.

The loop in step 

8

 guarantees that there will be no circularities in any prototype chain that only

includes objects that use the 

ordinary object

 definitions for [[GetPrototypeOf]] and

[[SetPrototypeOf]].

10.1.3  [[IsExtensible]] ( )

10.1.3.1  OrdinaryIsExtensible ( 

O

 )

10.1.4  [[PreventExtensions]] ( )

10.1.4.1  OrdinaryPreventExtensions ( 

O

 )

10.1.5  [[GetOwnProperty]] ( 

P

 )

10.1.5.1  OrdinaryGetOwnProperty ( 

O

P

 )

223

2.  If 

O

 does not have an own property with key 

P

, return 

undefined

.

3.  Let 

D

 be a newly created 

Property Descriptor

 with no fields.

4.  Let 

X

 be 

O

's own property whose key is 

P

.

5.  If 

X

 is a 

data property

, then

a.  Set 

D

.[[Value]] to the value of 

X

's [[Value]] attribute.

b.  Set 

D

.[[Writable]] to the value of 

X

's [[Writable]] attribute.

6.  Else,

a. 

Assert

X

 is an 

accessor property

.

b.  Set 

D

.[[Get]] to the value of 

X

's [[Get]] attribute.

c.  Set 

D

.[[Set]] to the value of 

X

's [[Set]] attribute.

7.  Set 

D

.[[Enumerable]] to the value of 

X

's [[Enumerable]] attribute.

8.  Set 

D

.[[Configurable]] to the value of 

X

's [[Configurable]] attribute.

9.  Return 

D

.

The [[DefineOwnProperty]] internal method of an 

ordinary object

 

O

 takes arguments 

P

 (a property key) and 

Desc

 (a

Property Descriptor

). It performs the following steps when called:

1.  Return ? 

OrdinaryDefineOwnProperty

(

O

P

Desc

).

The abstract operation OrdinaryDefineOwnProperty takes arguments 

O

 (an Object), 

P

 (a property key), and 

Desc

 (a

Property Descriptor

). It performs the following steps when called:

1.  Let 

current

 be ? 

O

.[[GetOwnProperty]](

P

).

2.  Let 

extensible

 be ? 

IsExtensible

(

O

).

3.  Return 

ValidateAndApplyPropertyDescriptor

(

O

P

extensible

Desc

current

).

The abstract operation IsCompatiblePropertyDescriptor takes arguments 

Extensible

 (a Boolean), 

Desc

 (a 

Property

Descriptor

), and 

Current

 (a 

Property Descriptor

). It performs the following steps when called:

1.  Return 

ValidateAndApplyPropertyDescriptor

(

undefined

undefined

Extensible

Desc

Current

).

The abstract operation ValidateAndApplyPropertyDescriptor takes arguments 

O

 (an Object or 

undefined

), 

P

 (a

property key), 

extensible

 (a Boolean), 

Desc

 (a 

Property Descriptor

), and 

current

 (a 

Property Descriptor

). It performs the

following steps when called:

NOTE

1. 

Assert

: If 

O

 is not 

undefined

, then 

IsPropertyKey

(

P

) is 

true

.

2.  If 

current

 is 

undefined

, then

a.  If 

extensible

 is 

false

, return 

false

.

If 

undefined

 is passed as 

O

, only validation is performed and no object updates are performed.

10.1.6  [[DefineOwnProperty]] ( 

P

Desc

 )

10.1.6.1  OrdinaryDefineOwnProperty ( 

O

P

Desc

 )

10.1.6.2  IsCompatiblePropertyDescriptor ( 

Extensible

Desc

Current

 )

10.1.6.3  ValidateAndApplyPropertyDescriptor ( 

O

P

extensible

Desc

current

 )

224

b. 

Assert

extensible

 is 

true

.

c.  If 

IsGenericDescriptor

(

Desc

) is 

true

 or 

IsDataDescriptor

(

Desc

) is 

true

, then

i.  If 

O

 is not 

undefined

, create an own 

data property

 named 

P

 of object 

O

 whose [[Value]],

[[Writable]], [[Enumerable]], and [[Configurable]] attribute values are described by 

Desc

. If the

value of an attribute field of 

Desc

 is absent, the attribute of the newly created property is set to its

default value

.

d.  Else,

i. 

Assert

: ! 

IsAccessorDescriptor

(

Desc

) is 

true

.

ii.  If 

O

 is not 

undefined

, create an own 

accessor property

 named 

P

 of object 

O

 whose [[Get]], [[Set]],

[[Enumerable]], and [[Configurable]] attribute values are described by 

Desc

. If the value of an

attribute field of 

Desc

 is absent, the attribute of the newly created property is set to its 

default

value

.

e.  Return 

true

.

3.  If every field in 

Desc

 is absent, return 

true

.

4.  If 

current

.[[Configurable]] is 

false

, then

a.  If 

Desc

.[[Configurable]] is present and its value is 

true

, return 

false

.

b.  If 

Desc

.[[Enumerable]] is present and ! 

SameValue

(

Desc

.[[Enumerable]], 

current

.[[Enumerable]]) is 

false

,

return 

false

.

5.  If ! 

IsGenericDescriptor

(

Desc

) is 

true

, then

a.  NOTE: No further validation is required.

6.  Else if ! 

SameValue

(! 

IsDataDescriptor

(

current

), ! 

IsDataDescriptor

(

Desc

)) is 

false

, then

a.  If 

current

.[[Configurable]] is 

false

, return 

false

.

b.  If 

IsDataDescriptor

(

current

) is 

true

, then

i.  If 

O

 is not 

undefined

, convert the property named 

P

 of object 

O

 from a 

data property

 to an

accessor property

. Preserve the existing values of the converted property's [[Configurable]] and

[[Enumerable]] attributes and set the rest of the property's attributes to their 

default values

.

c.  Else,

i.  If 

O

 is not 

undefined

, convert the property named 

P

 of object 

O

 from an 

accessor property

 to a

data property

. Preserve the existing values of the converted property's [[Configurable]] and

[[Enumerable]] attributes and set the rest of the property's attributes to their 

default values

.

7.  Else if 

IsDataDescriptor

(

current

) and 

IsDataDescriptor

(

Desc

) are both 

true

, then

a.  If 

current

.[[Configurable]] is 

false

 and 

current

.[[Writable]] is 

false

, then

i.  If 

Desc

.[[Writable]] is present and 

Desc

.[[Writable]] is 

true

, return 

false

.

ii.  If 

Desc

.[[Value]] is present and 

SameValue

(

Desc

.[[Value]], 

current

.[[Value]]) is 

false

, return 

false

.

iii.  Return 

true

.

8.  Else,

a. 

Assert

: ! 

IsAccessorDescriptor

(

current

) and ! 

IsAccessorDescriptor

(

Desc

) are both 

true

.

b.  If 

current

.[[Configurable]] is 

false

, then

i.  If 

Desc

.[[Set]] is present and 

SameValue

(

Desc

.[[Set]], 

current

.[[Set]]) is 

false

, return 

false

.

ii.  If 

Desc

.[[Get]] is present and 

SameValue

(

Desc

.[[Get]], 

current

.[[Get]]) is 

false

, return 

false

.

iii.  Return 

true

.

9.  If 

O

 is not 

undefined

, then

a.  For each field of 

Desc

 that is present, set the corresponding attribute of the property named 

P

 of object 

O

to the value of the field.

10.  Return 

true

.

10.1.7  [[HasProperty]] ( 

P

 )

225

The [[HasProperty]] internal method of an 

ordinary object

 

O

 takes argument 

P

 (a property key). It performs the

following steps when called:

1.  Return ? 

OrdinaryHasProperty

(

O

P

).

The abstract operation OrdinaryHasProperty takes arguments 

O

 (an Object) and 

P

 (a property key). It performs the

following steps when called:

1. 

Assert

IsPropertyKey

(

P

) is 

true

.

2.  Let 

hasOwn

 be ? 

O

.[[GetOwnProperty]](

P

).

3.  If 

hasOwn

 is not 

undefined

, return 

true

.

4.  Let 

parent

 be ? 

O

.[[GetPrototypeOf]]().

5.  If 

parent

 is not 

null

, then

a.  Return ? 

parent

.[[HasProperty]](

P

).

6.  Return 

false

.

The [[Get]] internal method of an 

ordinary object

 

O

 takes arguments 

P

 (a property key) and 

Receiver

 (an 

ECMAScript

language value

). It performs the following steps when called:

1.  Return ? 

OrdinaryGet

(

O

P

Receiver

).

The abstract operation OrdinaryGet takes arguments 

O

 (an Object), 

P

 (a property key), and 

Receiver

 (an 

ECMAScript

language value

). It performs the following steps when called:

1. 

Assert

IsPropertyKey

(

P

) is 

true

.

2.  Let 

desc

 be ? 

O

.[[GetOwnProperty]](

P

).

3.  If 

desc

 is 

undefined

, then

a.  Let 

parent

 be ? 

O

.[[GetPrototypeOf]]().

b.  If 

parent

 is 

null

, return 

undefined

.

c.  Return ? 

parent

.[[Get]](

P

Receiver

).

4.  If 

IsDataDescriptor

(

desc

) is 

true

, return 

desc

.[[Value]].

5. 

Assert

IsAccessorDescriptor

(

desc

) is 

true

.

6.  Let 

getter

 be 

desc

.[[Get]].

7.  If 

getter

 is 

undefined

, return 

undefined

.

8.  Return ? 

Call

(

getter

Receiver

).

The [[Set]] internal method of an 

ordinary object

 

O

 takes arguments 

P

 (a property key), 

V

 (an 

ECMAScript language

value

), and 

Receiver

 (an 

ECMAScript language value

). It performs the following steps when called:

1.  Return ? 

OrdinarySet

(

O

P

V

Receiver

).

10.1.7.1  OrdinaryHasProperty ( 

O

P

 )

10.1.8  [[Get]] ( 

P

Receiver

 )

10.1.8.1  OrdinaryGet ( 

O

P

Receiver

 )

10.1.9  [[Set]] ( 

P

V

Receiver

 )

226

 

 

 

 

 

 

 

Content      ..     18      19      20      21     ..