Skip to content

Commit

Permalink
Merge pull request #633 from Agoric/149-eval-source-urls
Browse files Browse the repository at this point in the history
Add source filenames to evaluated bundle code
  • Loading branch information
michaelfig committed Feb 29, 2020
2 parents c963123 + 069aa64 commit 32b94d3
Show file tree
Hide file tree
Showing 32 changed files with 442 additions and 73 deletions.
1 change: 1 addition & 0 deletions packages/SwingSet/scripts/build-kernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import bundleSource from '@agoric/bundle-source';
async function main() {
const { source, sourceMap } = await bundleSource(
`${__dirname}/../src/kernel/index.js`,
'nestedEvaluate',
);
const actualSource = `export default ${source}\n${sourceMap}`;
const f = await fs.promises.open('src/bundles/kernel', 'w', 0o644);
Expand Down
51 changes: 31 additions & 20 deletions packages/SwingSet/src/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import { insistStorageAPI } from './storageAPI';
import { insistCapData } from './capdata';
import { parseVatSlot } from './parseVatSlots';

// FIXME: Put this somewhere better.
process.on('unhandledRejection', e => console.log('unhandledRejection', e));

const ADMIN_DEVICE_PATH = require.resolve('./kernel/vatAdmin/vatAdmin-src');
const ADMIN_VAT_PATH = require.resolve('./kernel/vatAdmin/vatAdminWrapper');

Expand Down Expand Up @@ -197,24 +200,29 @@ function realmRegisterEndOfCrank(fn) {
{ registerEndOfCrank },
);

return src => {
// FIXME: Note that this replaceGlobalMeter endowment is not any
// worse than before metering existed. However, it probably is
// only necessary to be added to the kernel, rather than all
// static vats once we add metering support to the dynamic vat
// implementation.
// FIXME: Same for registerEndOfCrank.
return s.evaluate(src, {
require: r,
registerEndOfCrank: realmRegisterEndOfCrank,
replaceGlobalMeter,
})().default;
return (src, filePrefix = '/SwingSet-bundled-source') => {
const nestedEvaluate = source =>
s.evaluate(source, {
// Support both getExport and nestedEvaluate module format.
require: r,
nestedEvaluate,

// FIXME: Note that this replaceGlobalMeter endowment is not any
// worse than before metering existed. However, it probably is
// only necessary to be added to the kernel, rather than all
// static vats once we add metering support to the dynamic vat
// implementation.
// FIXME: Same for registerEndOfCrank.
registerEndOfCrank: realmRegisterEndOfCrank,
replaceGlobalMeter,
});
return nestedEvaluate(src)(filePrefix).default;
};
}

function buildSESKernel(sesEvaluator, endowments) {
const kernelSource = getKernelSource();
const buildKernel = sesEvaluator(kernelSource);
const buildKernel = sesEvaluator(kernelSource, '/SwingSet-kernel');
return buildKernel(endowments);
}

Expand Down Expand Up @@ -258,7 +266,7 @@ export async function buildVatController(config, withSES = true, argv = []) {
// Evaluate source to produce a setup function. This binds withSES from the
// enclosing context and evaluates it either in a SES context, or without SES
// by directly calling require().
async function evaluateToSetup(sourceIndex) {
async function evaluateToSetup(sourceIndex, filePrefix = undefined) {
if (!(sourceIndex[0] === '.' || path.isAbsolute(sourceIndex))) {
throw Error(
'sourceIndex must be relative (./foo) or absolute (/foo) not bare (foo)',
Expand All @@ -271,9 +279,12 @@ export async function buildVatController(config, withSES = true, argv = []) {
// (which is expected to initialize some state and export some facetIDs)
let setup;
if (withSES) {
const { source, sourceMap } = await bundleSource(`${sourceIndex}`);
const { source, sourceMap } = await bundleSource(
`${sourceIndex}`,
'nestedEvaluate',
);
const actualSource = `(${source})\n${sourceMap}`;
setup = sesEvaluator(actualSource);
setup = sesEvaluator(actualSource, filePrefix);
} else {
// eslint-disable-next-line global-require,import/no-dynamic-require
setup = require(`${sourceIndex}`).default;
Expand All @@ -287,8 +298,8 @@ export async function buildVatController(config, withSES = true, argv = []) {
setImmediate,
hostStorage,
runEndOfCrank,
vatAdminDevSetup: await evaluateToSetup(ADMIN_DEVICE_PATH),
vatAdminVatSetup: await evaluateToSetup(ADMIN_VAT_PATH),
vatAdminDevSetup: await evaluateToSetup(ADMIN_DEVICE_PATH, '/SwingSet/src'),
vatAdminVatSetup: await evaluateToSetup(ADMIN_VAT_PATH, '/SwingSet/src'),
};

const kernel = withSES
Expand All @@ -297,12 +308,12 @@ export async function buildVatController(config, withSES = true, argv = []) {

async function addGenesisVat(name, sourceIndex, options = {}) {
console.log(`= adding vat '${name}' from ${sourceIndex}`);
const setup = await evaluateToSetup(sourceIndex);
const setup = await evaluateToSetup(sourceIndex, `/SwingSet-vat-${name}`);
kernel.addGenesisVat(name, setup, options);
}

async function addGenesisDevice(name, sourceIndex, endowments) {
const setup = await evaluateToSetup(sourceIndex);
const setup = await evaluateToSetup(sourceIndex, `/SwingSet-dev-${name}`);
kernel.addGenesisDevice(name, setup, endowments);
}

Expand Down
31 changes: 31 additions & 0 deletions packages/bundle-source/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,34 @@ or inside an async function (and therefore outside of Jessie), do:
const { moduleFormat, source, sourceMap } = await sourceBundleP;
...
```

## getExport moduleFormat

The first main `moduleFormat` is the `"getExport"` format. It generates
source like:

```js
function getExport() {
let exports = {};
const module = { exports };
// CommonJS source translated from the inputs.
...
return module.exports;
}
```

To evaluate it and obtain the resulting module namespace, you need to endow
a `require` function to resolve external imports.

## nestedEvaluate moduleFormat

This is logically similar to the `getExport` format, except that the code
may additionally depend upon a `nestedEvaluate(src)` function to be used
to evaluate submodules in the same context as the parent function.

The advantage of this format is that it helps preserve the filenames within
the bundle in the event of any stack traces.

Also, the toplevel `getExport(filePrefix = "/bundled-source")` accepts an
optional `filePrefix` argument (which is prepended to relative paths for the
bundled files) in order to help give context to stack traces.
1 change: 1 addition & 0 deletions packages/bundle-source/demo/dir1/encourage.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const message = `You're great!`;
export const encourage = nick => `Hey ${nick}! ${message}`;
export const makeError = msg => Error(msg);
5 changes: 4 additions & 1 deletion packages/bundle-source/demo/dir1/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import harden from '@agoric/harden';
import { encourage } from './encourage';
import { encourage, makeError } from './encourage';
import more from './sub/more';

export default function makeEncourager() {
return harden({
encourage,
makeError,
more,
});
}
3 changes: 3 additions & 0 deletions packages/bundle-source/demo/dir1/sub/more.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const things = require('./things.js');

exports.more = `have more ${things.description}`;
1 change: 1 addition & 0 deletions packages/bundle-source/demo/dir1/sub/things.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.description = 'many different things';
6 changes: 4 additions & 2 deletions packages/bundle-source/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
},
"dependencies": {
"@agoric/acorn-eventual-send": "^2.0.0",
"@agoric/evaluate": "^2.2.0",
"@agoric/harden": "^0.0.4",
"@rollup/plugin-commonjs": "^11.0.2",
"@rollup/plugin-node-resolve": "^7.1.1",
"acorn": "^7.1.0",
"esm": "^3.2.5",
"rollup": "^1.25.1",
"rollup-plugin-node-resolve": "^5.2.0"
"rollup": "^1.32.0"
},
"keywords": [],
"files": [
Expand Down
Loading

0 comments on commit 32b94d3

Please sign in to comment.