shim: BaseRealm is no longer a class
MODIFY
shim/src/realm.js
shim/src/realm.js
@@ -117,11 +117,11 @@ function createRealmGlobalObject(unsafeRec) {
return Realm;
}
-// TODO: this no longer needs to be a class
-
-class BaseRealm {
- constructor(options) {
+const BaseRealm = {
+ initialize(selfClass, self, options) {
options = Object(options); // Todo: sanitize
+ // note: 'self' is the instance of the Realm, and 'selfClass' is the
+ // Realm constructor (facade) we build in buildChildRealm().
let unsafeRec;
if (
@@ -133,18 +133,7 @@ class BaseRealm {
// the context since we share the intrinsics. We create a new
// set to allow us to define eval() and Function() for the realm.
- // Class constructor only has a [[Construct]] behavior and not
- // a call behavior, therefore the use of "this" cannot be bound
- // by an adversary.
-
- // note: this 'this' comes from the Reflect.construct call in the
- // facade we build above, inside buildChildRealm().
-
- // todo: what if 'this' is e.g. Window but set to inherit from a Realm?
- // confused deputy / private field question. A: it can't be, we're in a
- // constructor, and constructors can't be invoked directly as
- // functions, using a class protects us here
- unsafeRec = getUnsafeRecForRealm(this.constructor);
+ unsafeRec = getUnsafeRecForRealm(selfClass);
} else if (
options.intrinsics === undefined &&
options.isDirectEval === undefined &&
@@ -169,19 +158,17 @@ class BaseRealm {
const realmRec = createRealmRec(unsafeRec);
// todo: is this where we run shims? but only in RootRealms, not compartments
- // note: we never invoke a method on 'this', we only use it as a key in
- // the weakmap. Never say "this." anywhere.
- registerRealmRecForRealmInstance(this, realmRec);
- }
- get global() {
- const { safeGlobal } = getRealmRecForRealmInstance(this);
+ registerRealmRecForRealmInstance(self, realmRec);
+ },
+ getGlobal(self) {
+ const { safeGlobal } = getRealmRecForRealmInstance(self);
return safeGlobal;
- }
- evaluate(x) {
- const { safeEval } = getRealmRecForRealmInstance(this);
+ },
+ evaluate(self, x) {
+ const { safeEval } = getRealmRecForRealmInstance(self);
return safeEval(x);
}
-}
+};
// Create the current unsafeRec from the current "primal" realm (the realm
// where the Realm shim is loaded and executed).

MODIFY
shim/src/realmFacade.js
shim/src/realmFacade.js
@@ -11,8 +11,7 @@ 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, getOwnPropertyDescriptors } = Object;
- const { apply, construct } = Reflect;
+ const { defineProperty } = Object;
const errorConstructors = new Map([
['EvalError', EvalError],
@@ -25,9 +24,9 @@ function buildChildRealm(BaseRealm) {
// Like Realm.apply except that it catches anything thrown and rethrows it
// as an Error from this realm
- function applyAndWrapError(target, thisArgument, ...args) {
+ function callAndWrapError(target, ...args) {
try {
- return apply(target, thisArgument, args);
+ return target(...args);
} catch (err) {
if (Object(err) !== err) {
// err is a primitive value, which is safe to rethrow
@@ -65,21 +64,22 @@ function buildChildRealm(BaseRealm) {
}
}
- const descs = getOwnPropertyDescriptors(BaseRealm.prototype);
// eslint-disable-next-line camelcase
- const descs_global_get = descs.global.get;
+ const baseInitialize = BaseRealm.initialize;
// eslint-disable-next-line camelcase
- const descs_evaluate_value = descs.evaluate.value;
+ const baseGetGlobal = BaseRealm.getGlobal;
+ // eslint-disable-next-line camelcase
+ const baseEvaluate = BaseRealm.evaluate;
class Realm {
constructor(...args) {
- return applyAndWrapError(construct, undefined, BaseRealm, args, Realm);
+ return callAndWrapError(baseInitialize, Realm, this, ...args);
}
get global() {
- return applyAndWrapError(descs_global_get, this);
+ return callAndWrapError(baseGetGlobal, this);
}
evaluate(...args) {
- return applyAndWrapError(descs_evaluate_value, this, args);
+ return callAndWrapError(baseEvaluate, this, ...args);
}
static makeRootRealm() {
return new Realm();

shim: BaseRealm is no longer a class