Skip to content

Commit

Permalink
fix(compartment-mapper): Deterministic archives
Browse files Browse the repository at this point in the history
  • Loading branch information
kriskowal committed May 25, 2021
1 parent 0d80376 commit 577cdd8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/compartment-mapper/NEWS.md
Expand Up @@ -20,6 +20,7 @@ User-visible changes to the compartment mapper:
removal of the `ses/lockdown` light layering (there is no heavy layer to
distinguish as the weight has shifted to the `@endo/static-module-record`
package).
* Archives are now deterministic.

## 0.2.4 (2021-03-30)

Expand Down
48 changes: 29 additions & 19 deletions packages/compartment-mapper/src/archive.js
Expand Up @@ -28,7 +28,7 @@ const parserForLanguage = {
*/
const resolveLocation = (rel, abs) => new URL(rel, abs).toString();

const { entries, fromEntries, values } = Object;
const { keys, entries, fromEntries } = Object;

/**
* @param {Record<string, CompartmentDescriptor>} compartments
Expand All @@ -53,31 +53,39 @@ const renameCompartments = compartments => {
*/
const translateCompartmentMap = (compartments, sources, renames) => {
const result = {};
for (const [name, compartment] of entries(compartments)) {
for (const name of keys(compartments).sort()) {
const compartment = compartments[name];
const { label } = compartment;

// rename module compartments
/** @type {Record<string, ModuleDescriptor>} */
const modules = {};
for (const [name, module] of entries(compartment.modules || {})) {
const compartment = module.compartment
? renames[module.compartment]
: undefined;
modules[name] = {
...module,
compartment,
};
const compartmentModules = compartment.modules;
if (compartment.modules) {
for (const name of keys(compartmentModules).sort()) {
const module = compartmentModules[name];
const compartment = module.compartment
? renames[module.compartment]
: undefined;
modules[name] = {
...module,
compartment,
};
}
}

// integrate sources into modules
const compartmentSources = sources[name];
for (const [name, source] of entries(compartmentSources || {})) {
const { location, parser, exit } = source;
modules[name] = {
location,
parser,
exit,
};
if (compartmentSources) {
for (const name of keys(compartmentSources).sort()) {
const source = compartmentSources[name];
const { location, parser, exit } = source;
modules[name] = {
location,
parser,
exit,
};
}
}

result[renames[name]] = {
Expand Down Expand Up @@ -111,9 +119,11 @@ const renameSources = (sources, renames) => {
* @param {Sources} sources
*/
const addSourcesToArchive = async (archive, sources) => {
for (const [compartment, modules] of entries(sources)) {
for (const compartment of keys(sources).sort()) {
const modules = sources[compartment];
const compartmentLocation = resolveLocation(`${compartment}/`, 'file:///');
for (const { location, bytes } of values(modules)) {
for (const specifier of keys(modules).sort()) {
const { bytes, location } = modules[specifier];
if (location !== undefined) {
const moduleLocation = resolveLocation(location, compartmentLocation);
const path = new URL(moduleLocation).pathname.slice(1); // elide initial "/"
Expand Down
16 changes: 8 additions & 8 deletions packages/compartment-mapper/src/node-modules.js
Expand Up @@ -26,7 +26,7 @@
import { inferExports } from './infer-exports.js';
import { parseLocatedJson } from './json.js';

const { create, entries, keys, values } = Object;
const { create, keys, values } = Object;

const decoder = new TextDecoder();

Expand Down Expand Up @@ -222,7 +222,7 @@ const graphPackage = async (
/** @type {Record<string, string>} */
const dependencies = {};
const children = [];
for (const name of keys(packageDescriptor.dependencies || {})) {
for (const name of keys(packageDescriptor.dependencies || {}).sort()) {
children.push(
// Mutual recursion ahead:
// eslint-disable-next-line no-use-before-define
Expand Down Expand Up @@ -364,17 +364,17 @@ const translateGraph = (
// The full map includes every exported module from every dependencey
// package and is a complete list of every external module that the
// corresponding compartment can import.
for (const [
packageLocation,
{ label, dependencies, parsers, types },
] of entries(graph)) {
for (const packageLocation of keys(graph).sort()) {
const { label, dependencies, parsers, types } = graph[packageLocation];
/** @type {Record<string, ModuleDescriptor>} */
const modules = {};
/** @type {Record<string, ScopeDescriptor>} */
const scopes = {};
for (const [dependencyName, packageLocation] of entries(dependencies)) {
for (const dependencyName of keys(dependencies).sort()) {
const packageLocation = dependencies[dependencyName];
const { exports, explicit } = graph[packageLocation];
for (const [exportName, module] of entries(exports)) {
for (const exportName of keys(exports).sort()) {
const module = exports[exportName];
modules[exportName] = {
compartment: packageLocation,
module,
Expand Down

0 comments on commit 577cdd8

Please sign in to comment.