Stage 2 Draft / January 12, 2021


Changes to ArrayCreate

To enable the new API, this proposal modifies ArrayCreate to add an internal slot to each array.

1 ArrayCreate ( length [ , proto ] )

The abstract operation ArrayCreate takes argument length (a non-negative integer) and optional argument proto. It is used to specify the creation of new Array exotic objects. It performs the following steps when called:

  1. If length > 232 - 1, throw a RangeError exception.
  2. If proto is not present, set proto to %Array.prototype%.
  3. Let A be ! MakeBasicObject(« [[Prototype]], [[Extensible]], [[TemplateObject]] »).
  4. Set A.[[Prototype]] to proto.
  5. Set A.[[TemplateObject]] to false.
  6. Set A.[[DefineOwnProperty]] as specified in
  7. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  8. Return A.

Changes to GetTemplateObject

To enable the new API, this proposal modifies GetTemplateObject to change the value of the new internal slot.

2 Runtime Semantics: GetTemplateObject ( templateLiteral )

The abstract operation GetTemplateObject is called with a Parse Node, templateLiteral, as an argument. It performs the following steps:

  1. Let realm be the current Realm Record.
  2. Let templateRegistry be realm.[[TemplateMap]].
  3. For each element e of templateRegistry, do
    1. If e.[[Site]] is the same Parse Node as templateLiteral, then
      1. Return e.[[Array]].
  4. Let rawStrings be TemplateStrings of templateLiteral with argument true.
  5. Let cookedStrings be TemplateStrings of templateLiteral with argument false.
  6. Let count be the number of elements in the List cookedStrings.
  7. Assert: count ≤ 232 - 1.
  8. Let template be ! ArrayCreate(count).
  9. Set template.[[TemplateObject]] to true.
  10. Let rawObj be ! ArrayCreate(count).
  11. Let index be 0.
  12. ...

New APIs

This adds a builtin static method to Array to allow distinguishing template string literal objects

Added under Properties of the Array Constructor:

3 Array.isTemplateObject ( value )

When the isTemplateObject method is called with argument value the following steps are taken:

  1. If IsArray(value) is true and value.[[TemplateObject]] is true then
    1. Return true.
  2. Return false.

IsTemplateObject is realm-agnostic. Since template objects are frozen before escaping GetTemplateObject, testing (IsTemplateObject(x) and x.[[Prototype]] is the realm's %ArrayPrototype%) is sufficient to determine whether an x is a template object in a particular realm.

In user code, Array.isTemplateObject(x) && x instanceof Array is an equivalent test, assuming no changes to builtins.