diff --git a/packages/default-evaluate-options/src/index.js b/packages/default-evaluate-options/src/index.js index c776c0d1346..c12df7740ed 100644 --- a/packages/default-evaluate-options/src/index.js +++ b/packages/default-evaluate-options/src/index.js @@ -1,6 +1,6 @@ import { parse } from '@agoric/babel-parser'; import generate from '@babel/generator'; -import makeEventualSendTransformer from '@agoric/transform-eventual-send'; +import makeEventualSendTransformer from '@agoric/transform-eventual-send/src/rewriter'; export default function makeDefaultEvaluateOptions() { const shims = []; diff --git a/packages/transform-eventual-send/src/index.js b/packages/transform-eventual-send/src/index.js index 2ae2933de48..2e0467dc917 100644 --- a/packages/transform-eventual-send/src/index.js +++ b/packages/transform-eventual-send/src/index.js @@ -1,5 +1,3 @@ -import eventualSendBundle from './bundles/eventual-send'; - export function makeTransform(parser, generate) { function transform(source) { // Parse with eventualSend enabled, rewriting to @@ -17,87 +15,3 @@ export function makeTransform(parser, generate) { } return transform; } - -// this transformer is meant for the SES1 evaluation format, with mutable -// endowments and stuff - -function makeEventualSendTransformer(parser, generate) { - const transformer = makeTransform(parser, generate); - let HandledPromise; - let evaluateProgram; - let myRequire; - let recursive = false; - const transform = { - closeOverSES(s) { - // FIXME: This will go away when we can bundle an @agoric/harden that understands SES. - myRequire = name => { - if (name === '@agoric/harden') { - return s.global.SES.harden; - } - throw Error(`Unrecognized require ${name}`); - }; - // FIXME: This should be replaced with ss.evaluateProgram support in SES. - evaluateProgram = (src, endowments = {}) => s.evaluate(src, endowments); - }, - rewrite(ss) { - const source = ss.src; - const endowments = ss.endowments || {}; - if (!recursive && !('HandledPromise' in endowments)) { - // Use a getter to postpone initialization. - Object.defineProperty(endowments, 'HandledPromise', { - get() { - if (!HandledPromise) { - // Get a HandledPromise endowment for the evaluator. - // It will be hardened in the evaluator's context. - const nestedEvaluate = src => - (evaluateProgram || ss.evaluateProgram)(src, { - require: myRequire || require, - nestedEvaluate, - }); - const { - source: evSendSrc, - moduleFormat, - sourceMap, - } = eventualSendBundle; - if ( - moduleFormat === 'getExport' || - moduleFormat === 'nestedEvaluate' - ) { - recursive = true; - try { - const ns = nestedEvaluate(`(${evSendSrc}\n${sourceMap})`)(); - HandledPromise = ns.HandledPromise; - } finally { - recursive = false; - } - } else { - throw Error(`Unrecognized moduleFormat ${moduleFormat}`); - } - } - return HandledPromise; - }, - }); - } - - const maybeSource = transformer(source); - - // Work around Babel appending semicolons. - const actualSource = - ss.sourceType === 'expression' && - maybeSource.endsWith(';') && - !source.endsWith(';') - ? maybeSource.slice(0, -1) - : maybeSource; - - return { - ...ss, - endowments, - src: actualSource, - }; - }, - }; - - return [transform]; -} - -export default makeEventualSendTransformer; diff --git a/packages/transform-eventual-send/src/rewriter.js b/packages/transform-eventual-send/src/rewriter.js new file mode 100644 index 00000000000..d5208d26b5d --- /dev/null +++ b/packages/transform-eventual-send/src/rewriter.js @@ -0,0 +1,86 @@ +import { makeTransform } from './index'; +import eventualSendBundle from './bundles/eventual-send'; + +// this transformer is meant for the SES1 evaluation format, with mutable +// endowments and stuff + +function makeEventualSendTransformer(parser, generate) { + const transformer = makeTransform(parser, generate); + let HandledPromise; + let evaluateProgram; + let myRequire; + let recursive = false; + const transform = { + closeOverSES(s) { + // FIXME: This will go away when we can bundle an @agoric/harden that understands SES. + myRequire = name => { + if (name === '@agoric/harden') { + return s.global.SES.harden; + } + throw Error(`Unrecognized require ${name}`); + }; + // FIXME: This should be replaced with ss.evaluateProgram support in SES. + evaluateProgram = (src, endowments = {}) => s.evaluate(src, endowments); + }, + rewrite(ss) { + const source = ss.src; + const endowments = ss.endowments || {}; + if (!recursive && !('HandledPromise' in endowments)) { + // Use a getter to postpone initialization. + Object.defineProperty(endowments, 'HandledPromise', { + get() { + if (!HandledPromise) { + // Get a HandledPromise endowment for the evaluator. + // It will be hardened in the evaluator's context. + const nestedEvaluate = src => + (evaluateProgram || ss.evaluateProgram)(src, { + require: myRequire || require, + nestedEvaluate, + }); + const { + source: evSendSrc, + moduleFormat, + sourceMap, + } = eventualSendBundle; + if ( + moduleFormat === 'getExport' || + moduleFormat === 'nestedEvaluate' + ) { + recursive = true; + try { + const ns = nestedEvaluate(`(${evSendSrc}\n${sourceMap})`)(); + HandledPromise = ns.HandledPromise; + } finally { + recursive = false; + } + } else { + throw Error(`Unrecognized moduleFormat ${moduleFormat}`); + } + } + return HandledPromise; + }, + }); + } + + const maybeSource = transformer(source); + + // Work around Babel appending semicolons. + const actualSource = + ss.sourceType === 'expression' && + maybeSource.endsWith(';') && + !source.endsWith(';') + ? maybeSource.slice(0, -1) + : maybeSource; + + return { + ...ss, + endowments, + src: actualSource, + }; + }, + }; + + return [transform]; +} + +export default makeEventualSendTransformer; diff --git a/packages/transform-eventual-send/test/ses-test.js b/packages/transform-eventual-send/test/ses-test.js index f5f34042446..2cf8b4a6e2a 100644 --- a/packages/transform-eventual-send/test/ses-test.js +++ b/packages/transform-eventual-send/test/ses-test.js @@ -10,7 +10,7 @@ import eventualSend from '@agoric/acorn-eventual-send'; import * as acorn from 'acorn'; import * as astring from 'astring'; -import makeEventualSendTransformer from '../src'; +import makeEventualSendTransformer from '../src/rewriter'; // FIXME: This should be unnecessary when SES has support // for passing `evaluateProgram` through to the rewriter state.