May 11, 2016

ECMAScript Frozen Realms Spec Proposal

1Realms Objects#

Note IMPORTANT this section references the Realm API spec proposal, specifically, it adds new capabilities to the Realm Objects.

1.1Abstract Operations#

1.1.1SetSpawnGlobalBindings ( realmRec, globalNames )#

The abstract operation SetSpawnGlobalBindings with arguments realmRec, and globalNames performs the following steps:

  1. Assert: realmRec is a Realm Record.
  2. Assert: globalNames is a List.
  3. Let global be realmRec.[[GlobalObject]].
  4. For each element name of globalNames in List order,
    1. Assert: name is specified as a Global Object in clause 18.
    2. Let desc be the fully populated data property descriptor for the property containing the specified attributes for the Global Object denoted by name. For those listed in 18.2, 18.3, or 18.4 the value of the [[Value]] attribute is the corresponding intrinsic object from realmRec.
    3. Perform ? DefinePropertyOrThrow(global, name, desc).
  5. Return global.

1.1.2CreateSpawnIntrinsics ( realmRec, parentIntrinsics, freshIntrinsicNames )#

The abstract operation CreateSpawnIntrinsics with arguments realmRec, parentIntrinsics, and intrinsicNames performs the following steps:

  1. Assert: realmRec is a Realm Record.
  2. Assert: parentIntrinsics is a Record.
  3. Assert: freshIntrinsicNames is a List.
  4. Let intrinsics be a new Record.
  5. Set realmRec.[[Intrinsics]] to intrinsics.
  6. For each name listed in column one of Table 7,
    1. If freshIntrinsicNames contains the value of name, then
      1. Let O be a new object value fully and recursively populated with property values as defined by the specification of each object in clauses 18-26. All object property values are newly created object values. All values that are built-in function objects are created by performing CreateBuiltinFunction(realmRec, <steps>, <prototype>, <slots>) where <steps> is the definition of that function provided by this specification, <prototype> is the specified value of the function's [[Prototype]] internal slot and <slots> is a list of the names, if any, of the function's specified internal slots.
    2. Else,
      1. Let O be the value corresponding to the field name denoted by name from parentIntrinsics record.
    3. Set field of intrinsics whose field name is name and value is O.
  7. Return intrinsics.
Note

The creation of the intrinsics and their properties must be ordered to avoid any dependencies upon objects that have not yet been created.

1.1.3CreateSpawnRealm ( parentRealmRec )#

The abstract operation CreateSpawnRealm with argument parentRealmRec performs the following steps:
  1. Assert: parentRealmRec is a Realm Record.
  2. Let realmRec be a new Realm Record.
  3. Let intrinsics be ! CreateSpawnIntrinsics(realmRec, parentRealmRec.[[Intrinsics]], « "%eval%", "%Function%" »).
  4. Set realmRec.[[Intrinsics]] to intrinsics.
  5. Set realmRec.[[TemplateMap]] to a new empty List.
  6. Let freshObject to ObjectCreate(parentRealmRec.[[GlobalObject]]).
  7. Perform ? SetRealmGlobalObject(realmRec, freshObject, undefined).
  8. Perform ? SetSpawnGlobalBindings(realmRec, « "eval", "Function" »).
  9. Return realmRec.

1.1.4SetFrozenGlobalBindings ( realmRec )#

The abstract operation SetFrozenGlobalBindings with argument realmRec performs the following steps:
  1. Assert: realmRec is a Realm Record.
  2. Let global be realmRec.[[GlobalObject]].
  3. For each property of the Global Object specified in clause 18, do
    1. Let name be the String value of the property name.
    2. Let desc be the fully populated data property descriptor for the immutable property containing the specified attributes for the property. For properties listed in 18.2, 18.3, or 18.4 the value of the [[Value]] attribute is the corresponding intrinsic object from realmRec.
    3. Perform ? DefinePropertyOrThrow(global, name, desc).
  4. Return global.
Note These primordials include all the primordials defined as mandatory in ES2017. These primordials must include no other objects or properties beyond those specified here.

1.1.5FreezeRealmIntrinsics ( realmRec )#

The abstract operation FreezeRealmIntrinsics with argument realmRec performs the following steps:
  1. Assert: realmRec is a Realm Record.
  2. Let intrinsics be realm.[[Intrinsics]].
  3. Let DatePrototype be intrinsics.[[%DatePrototype%]].
  4. Perform ? CreateMethodProperty (DatePrototype, "now", undefined).
  5. Let Math be intrinsics.[[%Math%]].
  6. Perform ? CreateMethodProperty (Math, "random", undefined).
  7. For each value corresponding to a field name in intrinsics, do:
    1. Perform ? SetIntegrityLevel(value, "frozen") and make the value object transitively immutable.
  8. Return intrinsics.
Note In order to attain the necessary deep immutability of an immutable root realm, two of its primordials must be modified from the existing standard: An immutable root realm's Date object has its now() method removed and the Date Constructor should throw a TypeError when called as a constructor or a function, rather than reveal the current time. An immutable root realm's Math object has its random() method removed.

1.2Properties of the Realm Constructor#

The value of the [[Prototype]] internal slot of the Realm constructor is the intrinsic object %FunctionPrototype%.

1.2.1Realm.immutableRoot ()#

When the Realm.immutableRoot function is called with no arguments, the following steps are taken:
  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%RealmPrototype%", « [[Realm]] »).
  3. Let realmRec be CreateRealm().
  4. Set O's [[Realm]] internal slot to realmRec.
  5. Perform ? ExtractRealmMethods(O).
  6. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined).
  7. Perform ? FreezeRealmIntrinsics(realmRec).
  8. Let globalObject be ? SetFrozenGlobalBindings(realmRec).
  9. Perform ? SetIntegrityLevel(globalObject, "frozen").
  10. Return O.
Note 1 Realm.immutableRoot() obtains an immutable root realm in which all primordials are already transitively immutable. These primordials must include no other objects or properties beyond those specified here. In an immutable root realm the global object itself is also transitively immutable. Specifically, it contains no host-specific objects. This frozen global object is a plain object whose [[Prototype]] is Object.prototype, i.e., the %ObjectPrototype% intrinsic of that immutable root realm. Note 2 Since two immutable root realms are forever the same in all ways except object identity, we leave it implementation-defined whether Realm.immutableRoot() always creates a fresh one, or always returns the same one. On any given implementation, it must either be always fresh or always the same.

1.3Properties of the Realm Prototype Object#

1.3.1Realm.prototype.spawn ([ endowments ])#

When the Realm.prototype.spawn function is called with optional argument endowments, the following steps are taken:
  1. Let parent be this value.
  2. If Type(parent) is not Object, throw a TypeError exception.
  3. If parent is not an instance of a concrete instance of Realm, throw a TypeError exception.
  4. Let O be ? ObjectCreate(parent, « [[Realm]] »).
  5. Let realmRec be ? CreateSpawnRealm(parent.[[Realm]]).
  6. Set O's [[Realm]] internal slot to realmRec.
  7. If endowments is provided, then
    1. If Type(endowments) is not an Object, throw a TypeError exception.
    2. Let globalObject be realmRec.[[GlobalObject]].
    3. Let props be ? ToObject(endowments).
    4. Let keys be ? props.[[OwnPropertyKeys]]().
    5. Repeat for each element propName of keys in List order,
      1. Let propDesc be ? props.[[GetOwnProperty]](propName).
      2. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
        1. Let propValue be ? Get(props, propName).
        2. Perform ? CreateDataPropertyOrThrow(globalObject, propName, propValue).
  8. Return O.