Skip to content

Commit

Permalink
fix(compartment-map): Restore test fixture maker and support for exit…
Browse files Browse the repository at this point in the history
… modules from archives
  • Loading branch information
kriskowal committed Jun 26, 2021
1 parent fcb433f commit 2aae715
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 10 deletions.
7 changes: 5 additions & 2 deletions packages/compartment-mapper/src/archive.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ const addSourcesToArchive = async (archive, sources) => {
* @returns {Promise<Uint8Array>}
*/
export const makeArchive = async (powers, moduleLocation, options) => {
const { moduleTransforms, modules = {}, dev = false } = options || {};
const { moduleTransforms, modules: exitModules = {}, dev = false } =
options || {};
const { read } = unpackReadPowers(powers);
const {
packageLocation,
Expand Down Expand Up @@ -191,15 +192,17 @@ export const makeArchive = async (powers, moduleLocation, options) => {
packageLocation,
sources,
compartments,
exitModules,
);

// Induce importHook to record all the necessary modules to import the given module specifier.
const compartment = assemble(compartmentMap, {
resolve,
modules,
modules: exitModules,
makeImportHook,
moduleTransforms,
parserForLanguage,
archiveOnly: true,
});
await compartment.load(entryModuleSpecifier);

Expand Down
52 changes: 47 additions & 5 deletions packages/compartment-mapper/src/assemble.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,29 @@ const { entries, fromEntries, freeze } = Object;
const { hasOwnProperty } = Object.prototype;
const { apply } = Reflect;

const inertStaticModuleRecord = {
imports: [],
exports: [],
execute() {
throw new Error(
`Assertion failed: compartment graphs built for archives cannot be initialized`,
);
},
};

const inertModuleNamespace = new Compartment(
{},
{},
{
resolveHook() {
return '';
},
async importHook() {
return inertStaticModuleRecord;
},
},
).module('');

const defaultCompartment = Compartment;

// q, as in quote, for strings in error messages.
Expand Down Expand Up @@ -155,6 +178,7 @@ const trimModuleSpecifierPrefix = (moduleSpecifier, prefix) => {
* @param {Record<string, ModuleDescriptor>} moduleDescriptors
* @param {Record<string, ModuleDescriptor>} scopeDescriptors
* @param {Record<string, string>} exitModules
* @param {boolean} archiveOnly
* @returns {ModuleMapHook | undefined}
*/
const makeModuleMapHook = (
Expand All @@ -163,6 +187,7 @@ const makeModuleMapHook = (
moduleDescriptors,
scopeDescriptors,
exitModules,
archiveOnly,
) => {
/**
* @param {string} moduleSpecifier
Expand All @@ -177,10 +202,10 @@ const makeModuleMapHook = (
exit,
} = moduleDescriptor;
if (exit !== undefined) {
// TODO Currenly, only the entry package can connect to built-in modules.
// TODO Currenly, every package can connect to built-in modules.
// Policies should be able to allow third-party modules to exit to
// built-ins, or have built-ins subverted by modules from specific
// compartments.
// built-ins explicitly, or have built-ins subverted by modules from
// specific compartments.
const module = exitModules[exit];
if (module === undefined) {
throw new Error(
Expand All @@ -189,7 +214,11 @@ const makeModuleMapHook = (
)}, may be missing from ${compartmentName} package.json`,
);
}
return module;
if (archiveOnly) {
return inertModuleNamespace;
} else {
return module;
}
}
if (foreignModuleSpecifier !== undefined) {
const foreignCompartment = compartments[foreignCompartmentName];
Expand All @@ -202,6 +231,17 @@ const makeModuleMapHook = (
}
return foreignCompartment.module(foreignModuleSpecifier);
}
} else if (has(exitModules, moduleSpecifier)) {
// When linking off the filesystem as with `importLocation`,
// there isn't a module descriptor for every module.
// TODO grant access to built-in modules contingent on a policy in the
// application's entry package descriptor.
moduleDescriptors[moduleSpecifier] = { exit: moduleSpecifier };
if (archiveOnly) {
return inertModuleNamespace;
} else {
return exitModules[moduleSpecifier];
}
}

// Search for a scope that shares a prefix with the requested module
Expand Down Expand Up @@ -281,6 +321,7 @@ export const link = (
moduleTransforms = {},
__shimTransforms__ = [],
modules: exitModules = {},
archiveOnly = false,
Compartment = defaultCompartment,
},
) => {
Expand Down Expand Up @@ -318,12 +359,13 @@ export const link = (
modules,
scopes,
exitModules,
archiveOnly,
);
const resolveHook = resolve;
resolvers[compartmentName] = resolve;

// TODO also thread powers selectively.
const compartment = new Compartment(globals, exitModules, {
const compartment = new Compartment(globals, undefined, {
resolveHook,
importHook,
moduleMapHook,
Expand Down
3 changes: 2 additions & 1 deletion packages/compartment-mapper/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ export const moduleJSDocTypes = true;
* @property {AssembleImportHook} makeImportHook
* @property {ParserForLanguage} parserForLanguage
* @property {ModuleTransforms} [moduleTransforms]
* @property {boolean} [archiveOnly]
*/

/**
Expand Down Expand Up @@ -235,6 +236,6 @@ export const moduleJSDocTypes = true;
/**
* @typedef {Object} ArchiveOptions
* @property {ModuleTransforms} [moduleTransforms]
* @property {Record<string, any>} [modules]
* @property {Record<string, never>} [modules]
* @property {boolean} [dev]
*/
14 changes: 13 additions & 1 deletion packages/compartment-mapper/test/app.agar-make.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// The archive may need to be regenerated if the test fixture and assertions
// have been changed.

/* global process */

import 'ses';
import fs from 'fs';
import { writeArchive } from '../archive.js';
Expand All @@ -20,4 +22,14 @@ const fixture = new URL(
).toString();
const archiveFixture = new URL('app.agar', import.meta.url).toString();

writeArchive(write, readPowers, archiveFixture, fixture);
const mitt = err =>
process.nextTick(() => {
throw err;
});

writeArchive(write, readPowers, archiveFixture, fixture, {
dev: true,
modules: {
builtin: true,
},
}).catch(mitt);
2 changes: 1 addition & 1 deletion packages/compartment-mapper/test/test-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ test('writeArchive / loadArchive', async t => {
};

await writeArchive(fakeWrite, readPowers, 'app.agar', fixture, {
modules,
modules: { builtin: true },
dev: true,
});
const application = await loadArchive(fakeRead, 'app.agar');
Expand Down

0 comments on commit 2aae715

Please sign in to comment.