Skip to content

Commit

Permalink
feat(import-bundle): accept symbol-named properties on inescapableGlo…
Browse files Browse the repository at this point in the history
…balProperties

Previously, the `inescapableGlobalProperties` option to
`importBundle()` only accepted enumerable string-named
properties. This commit changes that to accept all properties (even
unenumerable ones), and to accept symbol-named properties (instead of
only string-named ones).

We'll use this to provide `passStyleOf` to the vat environment built
by liveslots, so it can use a real WeakMap, instead of the (slower)
"virtual object -aware WeakMap".

closes #2376
  • Loading branch information
warner committed Jul 23, 2024
1 parent 655a74c commit 9bc7aaf
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
7 changes: 5 additions & 2 deletions packages/import-bundle/src/compartment-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ export function wrapInescapableCompartment(
// there are details to work out.
c.globalThis.Compartment = NewCompartment;

for (const prop of Object.keys(inescapableGlobalProperties)) {
// Use Reflect.ownKeys, not Object.keys, because we want both
// string-named and symbol-named properties. Note that
// Reflect.ownKeys also includes non-enumerable keys.
for (const prop of Reflect.ownKeys(inescapableGlobalProperties)) {
Object.defineProperty(c.globalThis, prop, {
value: inescapableGlobalProperties[prop],
writable: true,
enumerable: false,
enumerable: false, // TODO: really? why?
configurable: true,
});
}
Expand Down
21 changes: 20 additions & 1 deletion packages/import-bundle/test/compartment-wrapper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { wrapInescapableCompartment } from '../src/compartment-wrapper.js';

const createChild = `() => new Compartment({console})`;

// simulate what pass-style wants to give a liveslots environment
const symbolEndowment = () => 0;
const endowmentSymbol = Symbol.for('endowmentSymbol');

function check(t, c, n) {
t.is(c.evaluate('Compartment.name'), 'Compartment', `${n}.Compartment.name`);

Expand All @@ -21,11 +25,26 @@ function check(t, c, n) {

t.is(c.evaluate('WeakMap'), 'replaced');
t.is(c.evaluate('globalThis.WeakMap'), 'replaced');
t.is(c.evaluate('globalThis.unenumerable'), 'yep');
t.is(c.evaluate(`globalThis[Symbol.for('endowmentSymbol')]`), symbolEndowment);
}

// match what @endo/pass-style does, but note that import-bundle
// does/should not depend upon on pass-style in any way
//
// alternative: have one of pass-style and import-bundle have a
// devDependencies on the other (avoid a cycle, avoid strong/"normal"
// `dependencies`), to allow a more thorough test, which is currently
// only really exercised by the agoric-sdk/swingset-liveslots test

test('wrap', t => {
const inescapableTransforms = [];
const inescapableGlobalProperties = { WeakMap: 'replaced' };
const inescapableGlobalProperties = {
WeakMap: 'replaced',
[endowmentSymbol]: symbolEndowment,
};
Object.defineProperty(inescapableGlobalProperties, 'unenumerable',
{ value: 'yep', enumerable: false });
const WrappedCompartment = wrapInescapableCompartment(
Compartment,
inescapableTransforms,
Expand Down

0 comments on commit 9bc7aaf

Please sign in to comment.