Use assert() to guard the weakmaps used as private fields
Make the Realm constructor throw TypeError
MODIFY
shim/src/realm.js
shim/src/realm.js
@@ -6,6 +6,7 @@ import {
createSafeEvaluatorWhichTakesEndowments,
createFunctionEvaluator
} from './evaluators';
+import { assert } from './utilities';
import { create, defineProperty, defineProperties, freeze, arrayConcat } from './commons';
// Create a registry to mimic a private static members on the realm classes.
@@ -14,30 +15,20 @@ import { create, defineProperty, defineProperties, freeze, arrayConcat } from '.
const UnsafeRecForRealmClass = new WeakMap();
function getUnsafeRecForRealmClass(RealmClass) {
- if (Object(RealmClass) !== RealmClass) {
// Detect non-objects.
- throw new TypeError('internal error: bad object, not a Realm constructor');
- }
- // spec just says throw TypeError
- // todo: but shim should include a message
- if (!UnsafeRecForRealmClass.has(RealmClass)) {
+ assert(Object(RealmClass) === RealmClass, 'bad object, not a Realm constructor');
// RealmClass has no unsafeRec. Shoud not proceed.
- throw new TypeError('internal error: bad object');
- }
+ assert(UnsafeRecForRealmClass.has(RealmClass), 'Realm constructor has no record');
+
return UnsafeRecForRealmClass.get(RealmClass);
}
function registerUnsafeRecForRealmClass(RealmClass, unsafeRec) {
- if (Object(RealmClass) !== RealmClass) {
// Detect non-objects.
- throw new TypeError('internal error: bad object, not a Realm constructor');
- }
- // spec just says throw TypeError
- // todo: but shim should include a message
- if (UnsafeRecForRealmClass.has(RealmClass)) {
- // Attempt to change an existing unsafeRec on a Realm. Shoud not proceed.
- throw new TypeError('internal error: bad object');
- }
+ assert(Object(RealmClass) === RealmClass, 'bad object, not a Realm constructor');
+ // RealmClass already has unsafeRec. Shoud not proceed.
+ assert(!UnsafeRecForRealmClass.has(RealmClass), 'Realm constructor already has a record');
+
UnsafeRecForRealmClass.set(RealmClass, unsafeRec);
}
@@ -47,28 +38,20 @@ function registerUnsafeRecForRealmClass(RealmClass, unsafeRec) {
const RealmRecForRealmInstance = new WeakMap();
function getRealmRecForRealmInstance(realm) {
- if (Object(realm) !== realm) {
// Detect non-objects.
- throw new TypeError('bad object, not a Realm instance');
- }
- if (!RealmRecForRealmInstance.has(realm)) {
+ assert(Object(realm) === realm, 'bad object, not a Realm instance');
// Realm instance has no realmRec. Should not proceed.
- throw new TypeError(
- 'bad object, use Realm.makeRootRealm() or .makeCompartment() instead of "new Realm"'
- );
- }
+ assert(RealmRecForRealmInstance.has(realm), 'Realm instance has no record');
+
return RealmRecForRealmInstance.get(realm);
}
function registerRealmRecForRealmInstance(realm, realmRec) {
- if (Object(realm) !== realm) {
// Detect non-objects.
- throw new TypeError('internal error: bad object, not a Realm instance');
- }
- if (RealmRecForRealmInstance.has(realm)) {
+ assert(Object(realm) === realm, 'bad object, not a Realm instance');
// Attempt to change an existing realmRec on a realm instance. Should not proceed.
- throw new TypeError('internal error: Realm instance is already present');
- }
+ assert(!RealmRecForRealmInstance.has(realm), 'Realm instance already has a record');
+
RealmRecForRealmInstance.set(realm, realmRec);
}

MODIFY
shim/src/realmFacade.js
shim/src/realmFacade.js
@@ -12,7 +12,7 @@ export function buildChildRealm(BaseRealm) {
// *after* user code has had a chance to pollute its environment, or it
// could be used to gain access to BaseRealm and primal-realm Error
// objects.
- const { defineProperty } = Object;
+ const { create, defineProperty } = Object;
const errorConstructors = new Map([
['EvalError', EvalError],
@@ -66,14 +66,27 @@ export function buildChildRealm(BaseRealm) {
}
class Realm {
+ constructor() {
+ // The Realm constructor is not intended to be used with the new operator
+ // or to be subclassed. It may be used as the value of an extends clause
+ // of a class definition but a super call to the Realm constructor will
+ // cause an exception.
+
+ // When Realm is called as a function, an exception is also raised because
+ // a class constructor cannot be invoked without 'new'.
+ throw new TypeError('Realm is not a constructor');
+ }
+
static makeRootRealm(...args) {
- const r = new Realm();
+ // Bypass the constructor.
+ const r = create(Realm.prototype);
callAndWrapError(initRootRealm, Realm, r, ...args);
return r;
}
static makeCompartment(...args) {
- const r = new Realm();
+ // Bypass the constructor.
+ const r = create(Realm.prototype);
callAndWrapError(initCompartment, Realm, r, ...args);
return r;
}

Use assert() to guard the weakmaps used as private fields
Make the Realm constructor throw TypeError