1 WeakRef Objects

A WeakRef is an object that is used to refer to a target object without preserving it from garbage collection. WeakRefs can dereference to allow access to the target object, if the target object hasn't been reclaimed by garbage collection.

1.1The WeakRef Constructor

The WeakRef constructor:

  • is the intrinsic object %WeakRef%.
  • is the initial value of the WeakRef property of the global object.
  • creates and initializes a new WeakRef object when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakRef behaviour must include a super call to the WeakRef constructor to create and initialize the subclass instance with the internal state necessary to support the WeakRef.prototype built-in methods.

1.1.1 WeakRef ( target )

When the WeakRef function is called with argument target, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If Type(target) is not Object, throw a TypeError exception.
  3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[Target]] »).
  4. Perfom ! KeepDuringJob(target).
  5. Set weakRef.[[Target]] to target.
  6. Return weakRef.

1.2Properties of the WeakRef Constructor

The WeakRef constructor:

  • has a [[Prototype]] internal slot whose value is the intrinsic object %FunctionPrototype%.
  • has the following properties:

1.2.1WeakRef.prototype

The initial value of WeakRef.prototype is the intrinsic %WeakRefPrototype% object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

1.2.2get WeakRef [ @@species ]

WeakRef[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call @@species to determine the constructor to use to create the derived objects. Subclass constructor may over-ride @@species to change the default constructor assignment.

1.3Properties of the WeakRef Prototype Object

The WeakRef prototype object:

  • is the intrinsic object %WeakRefPrototype%.
  • has a [[Prototype]] internal slot whose value is the intrinsic object %ObjectPrototype%.
  • is an ordinary object.
  • does not have a [[Target]] internal slot.

1.3.1WeakRef.prototype.deref ( )

The following steps are taken:

  1. Let weakRef be the this value.
  2. If Type(weakRef) is not Object, throw a TypeError exception.
  3. If weakRef does not have a [[Target]] internal slot, throw a TypeError exception.
  4. Let target be the value of weakRef.[[Target]].
  5. If target is not empty,
    1. Perform ! KeepDuringJob(target).
    2. Return target.
  6. Return undefined.
Note
If the WeakRef returns a target Object that is not undefined, then this target object should not be garbage collected in that turn. The KeepDuringJob operation makes sure read consistency is maintained.
          target = { foo: function() {} };
          let weakRef = new WeakRef(target);

          ... later ...

          if (weakRef.deref()) {
            weakRef.deref().foo();
          }
        
In the above example, if the first deref evaluates to true then the second deref can not fail.

1.4Properties of WeakRef Instances

WeakRef instances are ordinary objects that inherit properties from the WeakRef prototype. WeakRef instances also have a [[Target]] internal slot.

2 FinalizationGroup Objects

A FinalizationGroup is an object that manages registeration and unregisteration of cleanup operations that are performed when target objects are garbage collected.

2.1The FinalizationGroup Constructor

The FinalizationGroup constructor:

  • is the intrinsic object %FinalizationGroup%.
  • is the initial value of the FinalizationGroup property of the global object.
  • creates and initializes a new FinalizationGroup object when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified FinalizationGroup behaviour must include a super call to the FinalizationGroup constructor to create and initialize the subclass instance with the internal state necessary to support the FinalizationGroup.prototype built-in methods.

2.1.1 FinalizationGroup ( cleanupCallback )

When the FinalizationGroup function is called with argument cleanupCallback, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If Type(cleanupCallback) is not Callable, throw a TypeError exception.
  3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[CleanupCallback]], [[Cells]] »).
  4. Set finalizationGroup.[[CleanupCallback]] to cleanupCallback.
  5. Set finalizationGroup.[[Cells]] to be an empty List.
  6. Let agent be the surrounding agent.
  7. Append finalizationGroup to agent.[[FinalizationGroups]].
  8. Return finalizationGroup.

2.2Properties of the FinalizationGroup Constructor

The FinalizationGroup constructor:

  • has a [[Prototype]] internal slot whose value is the intrinsic object %FunctionPrototype%.
  • has the following properties:

2.2.1FinalizationGroup.prototype

The initial value of FinalizationGroup.prototype is the intrinsic %FinalizationGroupPrototype% object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

2.2.2get FinalizationGroup [ @@species ]

FinalizationGroup[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call @@species to determine the constructor to use to create the derived objects. Subclass constructor may over-ride @@species to change the default constructor assignment.

2.3Properties of the FinalizationGroup Prototype Object

The FinalizationGroup prototype object:

  • is the intrinsic object %FinalizationGroupPrototype%.
  • has a [[Prototype]] internal slot whose value is the intrinsic object %ObjectPrototype%.
  • is an ordinary object.
  • does not have a [[Target]] internal slot.

2.3.1FinalizationGroup.prototype.constructor

The initial value of FinalizationGroup.prototype.constructor is the intrinsic object %FinalizationGroup%.

2.3.2FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] )

The following steps are taken:

  1. Let finalizationGroup be the this value.
  2. If Type(finalizationGroup) is not Object, throw a TypeError exception.
  3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception.
  4. Let cell be the Record { [[Target]] : target, [[Holdings]]: holdings, [[UnregisterToken]]: unregisterToken }.
  5. Append cell to finalizationGroup.[[Cells]].
  6. Return undefined.

2.3.3FinalizationGroup.prototype.unregister ( unregisterToken )

The following steps are taken:

  1. Let finalizationGroup be the this value.
  2. If Type(finalizationGroup) is not Object, throw a TypeError exception.
  3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception.
  4. Let removed be false.
  5. For each Record { [[Target]], [[Holdings]], [[UnregisterToken]] } cell that is an element of finalizationGroup.[[Cells]], do
    1. If SameValue(cell.[[UnregisterToken]], unregisterToken) is true, then
      1. Remove cell from finalizationGroup.[[Cells]].
      2. Set removed to true.
  6. Return removed.

2.3.4FinalizationGroup.prototype.cleanupSome ( [ callback ] )

The following steps are taken:

  1. Let finalizationGroup be the this value.
  2. If Type(finalizationGroup) is not Object, throw a TypeError exception.
  3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception.
  4. Perform ! FinalizationGroupCleanupJob(finalizationGroup, callback).
  5. Return undefined.

2.4Properties of FinalizationGroup Instances

FinalizationGroup instances are ordinary objects that inherit properties from the FinalizationGroup prototype. FinalizationGroup instances also have [[Cells]] and [[CleanupCallback]] internal slot.

2.5FinalizationGroup Cleanup Iterator Objects

A FinalizationGroup Cleanup Iterator is an ordinary object, with the structure defined below, that represents a specific iteration over some specific FinalizationGroup instance object. There is not a named constructor for FinalizationGroup Cleanup Iterator objects. Instead, these iterator objects are created when the cleanupCallback of the FinalizationGroup is called.

2.5.1CreateFinalizationGroupCleanupIterator ( finalizationGroup )

The following steps are taken:

  1. Let finalizationGroup be the this value.
  2. If Type(finalizationGroup) is not Object, throw a TypeError exception.
  3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception.
  4. Let iterator be ObjectCreate(%FinalizationGroupCleanupIteratorPrototype%, « [[FinalizationGroup]] »).
  5. Set iterator.[[FinalizationGroup]] to finalizationGroup.
  6. Return iterator.

2.5.2The %FinalizationGroupCleanupIteratorPrototype% Object

The %FinalizationGroupCleanupIteratorPrototyp% object:

  • has properties that are inherited by all FinalizationGroup Cleanup Iterator Objects.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is the intrinsic object %IteratorPrototype%.
  • has the following properties:

2.5.2.1%FinalizationGroupCleanupIteratorPrototype%.next ( )

  1. Let iterator be the this value.
  2. If Type(iterator) is not Object, throw a TypeError exception.
  3. If iterator does not have a [[FinalizationGroup]] internal slot, throw a TypeError exception.
  4. Let finalizationGroup be iterator.[[FinalizationGroup]].
  5. If finalizationGroup is undefined, then
    1. Return CreateIterResultObject(undefined, true).
  6. Assert: finalizationGroup has [[Cells]] internal slot.
  7. If finalizationGroup.[[Cells]] contains a Record cell such that cell.[[Target]] is empty,
    1. Choose any such cell.
    2. Remove cell from finalizationGroup.[[Cells]].
    3. Return CreateIterResultObject(cell.[[Holdings]], false).
  8. Otherwise, return CreateIterResultObject((undefined, true).

2.5.2.2%FinalizationGroupCleanupIteratorPrototype% [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "FinalizationGroup Cleanup Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

2.5.3Properties of FinalizationGroup Cleanup Iterator Instances

FinalizationGroup Cleanup Iterator instances are ordinary objects that inherit properties from the %FinalizationGroupCleanupIteratorPrototype% intrinsic object. FinalizationGroup Cleanup Iteratorinstances are initially created with a [[FinalizationGroup]] internal slot.

3 Abstract Jobs

Table 1: 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-dependent 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.
[[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
[[FinalizationGroups]] List of FinalizationGroup objects Initially a new empty List, representing the set of all FinalizationGroups

At any given time, if all references to a ECMAScript object are from a [[Target]] field or internal slot, and KeepDuringJob was not called on the object during current RunJobs algorithm/since the last microtask checkpoint, the implementation MAY replace the reference to the object in all such [[Target]] fields or internal slots with the value empty.

3.1 DoAgentFinalization ( )

The following steps are performed:

  1. Let agent be the surrounding agent.
  2. For each finalizationGroup in agent.[[FinalizationGroups]], do
    1. Let hasEmptyCell be ! CheckForEmptyCells(finalizationGroup).
    2. If hasEmptyCell is true, then
      1. Perfom EnqueueJob("FinalizationJob", FinalizationGroupCleanupJob, « finalizationGroup »).
  3. Set agent.[[KeptAlive]] to a new empty List.
Editor's Note

In HTML, DoAgentFinalization is called between Step 2 and 3 of the perform a microtask checkpoint algorithm.

In the ECMAScript specification, DoAgentFinalization is called as the last step of RunJobs.

A particular host environment will, in practice, only invoke DoAgentFinalization from one of these callsites. See tc39/ecma262#735 for more information.

3.2 CheckForEmptyCells ( finalizationGroup )

The following steps are performed:

  1. Assert: finalizationGroup has an [[Cells]] internal slot.
  2. For each cell in finalizationGroup.[[Cells]], do
    1. If cell.[[Target]] is empty, then
      1. Return true.
  3. Return false.

3.3 FinalizationGroupCleanupJob ( finalizationGroup [ , callback ] )

The following steps are performed:

  1. Assert: finalizationGroup has [[Cells]] and [[CleanupCallback]] internal slots.
  2. Let iterator be ! CreateFinalizationGroupCleanupIterator(finalizationGroup).
  3. If callback is undefined, set callback to finalizationGroup.[[CleanupCallback]].
  4. Perform ? Call(callback, undefined, iterator).
  5. Return undefined.

3.4KeepDuringJob ( object )

  1. Let agent be the surrounding agent.
  2. Append object to agent.[[KeptAlive]].
Note
When the abstract operation KeepDuringJob is called with a target object reference, it adds the target to an identity Set that will point strongly at the target until the end of the current Job. This may be abstractly implemented as a Set in the current Job that becomes unreachable when the Job ends because the Job becomes unreachable, or as a Set in the current Agent that gets cleared at the end of each Job.