Skip to content

Commit

Permalink
fix: refactor liveSlots so it could provide vat globals
Browse files Browse the repository at this point in the history
This splits up `makeLiveslots` so that the `buildRootObject` function is
provided later, after it returns. This makes it possible to delay the import
of the vat code until after liveslots has provided globals to put into its
Compartment.

This does not yet provide any globals (the `vatGlobals` which `makeLiveslots`
returns is empty). Nor does it change the vat managers to use the
`vatGlobals` in any way. But these changes should be a lot easier now.

refs #1867
  • Loading branch information
warner committed Oct 21, 2020
1 parent b64e149 commit 165205f
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 80 deletions.
91 changes: 43 additions & 48 deletions packages/SwingSet/src/kernel/liveSlots.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,27 @@ import { insistCapData } from '../capdata';
*
* @param {*} syscall Kernel syscall interface that the vat will have access to
* @param {*} _state Object to store and retrieve state; not used // TODO fix wart
* @param {*} buildRootObject Function that will create a root object for the new vat
* @param {*} forVatID Vat ID label, for use in debug diagostics
* @param {*} vatPowers
* @param {*} vatParameters
* @returns {*} an extended dispatcher object for the new vat
* @returns {*} { vatGlobals, dispatch, setBuildRootObject }
*
* setBuildRootObject should be called, once, with a function that will
* create a root object for the new vat The caller provided buildRootObject
* function produces and returns the new vat's root object:
*
* buildRootObject(vatPowers, vatParameters)
*/
function build(
syscall,
_state,
buildRootObject,
forVatID,
vatPowers,
vatParameters,
) {
function build(syscall, _state, forVatID, vatPowers, vatParameters) {
const enableLSDebug = false;
function lsdebug(...args) {
if (enableLSDebug) {
console.log(...args);
}
}

let didRoot = false;

const outstandingProxies = new WeakSet();

/**
Expand Down Expand Up @@ -342,6 +342,7 @@ function build(
}

function deliver(target, method, argsdata, result) {
assert(didRoot);
insistCapData(argsdata);
lsdebug(
`ls[${forVatID}].dispatch.deliver ${target}.${method} -> ${result}`,
Expand Down Expand Up @@ -472,6 +473,7 @@ function build(
}

function notifyFulfillToData(promiseID, data) {
assert(didRoot);
insistCapData(data);
lsdebug(
`ls.dispatch.notifyFulfillToData(${promiseID}, ${data.body}, ${data.slots})`,
Expand All @@ -488,6 +490,7 @@ function build(
}

function notifyFulfillToPresence(promiseID, slot) {
assert(didRoot);
lsdebug(`ls.dispatch.notifyFulfillToPresence(${promiseID}, ${slot})`);
insistVatType('promise', promiseID);
// TODO: insist that we do not have decider authority for promiseID
Expand All @@ -506,6 +509,7 @@ function build(
// TODO: when we add notifyForward, guard against cycles

function notifyReject(promiseID, data) {
assert(didRoot);
insistCapData(data);
lsdebug(
`ls.dispatch.notifyReject(${promiseID}, ${data.body}, ${data.slots})`,
Expand All @@ -532,25 +536,31 @@ function build(
// vats which use D are in: acorn-eventual-send, cosmic-swingset
// (bootstrap, bridge, vat-http), swingset

// here we finally invoke the vat code, and get back the root object
const rootObject = buildRootObject(
harden({ D, exitVat, exitVatWithFailure, ...vatPowers }),
harden(vatParameters),
);
mustPassByPresence(rootObject);
const vatGlobals = harden({}); // for later use: #1846

function setBuildRootObject(buildRootObject) {
assert(!didRoot);
didRoot = true;

const rootSlot = makeVatSlot('object', true, 0);
valToSlot.set(rootObject, rootSlot);
slotToVal.set(rootSlot, rootObject);
// here we finally invoke the vat code, and get back the root object
const rootObject = buildRootObject(
harden({ D, exitVat, exitVatWithFailure, ...vatPowers }),
harden(vatParameters),
);
mustPassByPresence(rootObject);

const rootSlot = makeVatSlot('object', true, 0);
valToSlot.set(rootObject, rootSlot);
slotToVal.set(rootSlot, rootObject);
}

return {
m,
const dispatch = harden({
deliver,
// subscribe,
notifyFulfillToData,
notifyFulfillToPresence,
notifyReject,
};
});
return harden({ vatGlobals, setBuildRootObject, dispatch, m });
}

/**
Expand All @@ -559,14 +569,14 @@ function build(
*
* @param {*} syscall Kernel syscall interface that the vat will have access to
* @param {*} state Object to store and retrieve state
* @param {*} buildRootObject Function that will create a root object for the new vat
* @param {*} forVatID Vat ID label, for use in debug diagostics
* @param {*} vatPowers
* @param {*} vatParameters
* @returns {*} a dispatcher object for the new vat
* @returns {*} { vatGlobals, dispatch, setBuildRootObject }
*
* The caller provided buildRootObject function produces and returns the new vat's
* root object:
* setBuildRootObject should be called, once, with a function that will
* create a root object for the new vat The caller provided buildRootObject
* function produces and returns the new vat's root object:
*
* buildRootObject(vatPowers, vatParameters)
*
Expand All @@ -589,33 +599,18 @@ function build(
export function makeLiveSlots(
syscall,
state,
buildRootObject,
forVatID = 'unknown',
vatPowers = harden({}),
vatParameters = harden({}),
) {
const {
deliver,
notifyFulfillToData,
notifyFulfillToPresence,
notifyReject,
} = build(
syscall,
state,
buildRootObject,
forVatID,
{ ...vatPowers, getInterfaceOf, Remotable, makeMarshal },
vatParameters,
);
return harden({
deliver,
notifyFulfillToData,
notifyFulfillToPresence,
notifyReject,
});
const allVatPowers = { ...vatPowers, getInterfaceOf, Remotable, makeMarshal };
const r = build(syscall, state, forVatID, allVatPowers, vatParameters);
const { vatGlobals, dispatch, setBuildRootObject } = r; // omit 'm'
return harden({ vatGlobals, dispatch, setBuildRootObject });
}

// for tests
export function makeMarshaller(syscall) {
return { m: build(syscall, null, _E => harden({})).m };
const { m } = build(syscall);
return { m };
}
11 changes: 3 additions & 8 deletions packages/SwingSet/src/kernel/vatManager/localVatManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,9 @@ export function makeLocalVatManagerFactory(tools) {
let dispatch;
if (typeof vatNS.buildRootObject === 'function') {
const { buildRootObject } = vatNS;
dispatch = makeLiveSlots(
syscall,
state,
buildRootObject,
vatID,
vatPowers,
vatParameters,
);
const r = makeLiveSlots(syscall, state, vatID, vatPowers, vatParameters);
r.setBuildRootObject(buildRootObject);
dispatch = r.dispatch;
} else if (enableSetup) {
const setup = vatNS.default;
assert(setup, `vat source bundle lacks (default) setup() function`);
Expand Down
11 changes: 3 additions & 8 deletions packages/SwingSet/src/kernel/vatManager/nodeWorkerSupervisor.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,9 @@ parentPort.on('message', ([type, ...margs]) => {
makeMarshal,
testLog,
};
dispatch = makeLiveSlots(
syscall,
state,
vatNS.buildRootObject,
vatID,
vatPowers,
vatParameters,
);
const r = makeLiveSlots(syscall, state, vatID, vatPowers, vatParameters);
r.setBuildRootObject(vatNS.buildRootObject);
dispatch = r.dispatch;
workerLog(`got dispatch:`, Object.keys(dispatch).join(','));
sendUplink(['dispatchReady']);
});
Expand Down
11 changes: 3 additions & 8 deletions packages/SwingSet/src/kernel/vatManager/subprocessSupervisor.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,9 @@ fromParent.on('data', data => {
makeMarshal,
testLog,
};
dispatch = makeLiveSlots(
syscall,
state,
vatNS.buildRootObject,
vatID,
vatPowers,
vatParameters,
);
const r = makeLiveSlots(syscall, state, vatID, vatPowers, vatParameters);
r.setBuildRootObject(vatNS.buildRootObject);
dispatch = r.dispatch;
workerLog(`got dispatch:`, Object.keys(dispatch).join(','));
sendUplink(['dispatchReady']);
});
Expand Down
16 changes: 11 additions & 5 deletions packages/SwingSet/test/test-liveslots.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ function buildSyscall() {
return { log, syscall };
}

function makeDispatch(syscall, build) {
const { setBuildRootObject, dispatch } = makeLiveSlots(syscall, null, 'vatA');
setBuildRootObject(build);
return dispatch;
}

test('calls', async t => {
const { log, syscall } = buildSyscall();

Expand All @@ -53,7 +59,7 @@ test('calls', async t => {
},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);
t.deepEqual(log, []);
const rootA = 'o+0';

Expand Down Expand Up @@ -113,7 +119,7 @@ test('liveslots pipelines to syscall.send', async t => {
},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);
t.deepEqual(log, []);
const rootA = 'o+0';
const x = 'o-5';
Expand Down Expand Up @@ -177,7 +183,7 @@ test('liveslots pipeline/non-pipeline calls', async t => {
},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);

t.deepEqual(log, []);

Expand Down Expand Up @@ -258,7 +264,7 @@ async function doOutboundPromise(t, mode) {
},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);

t.deepEqual(log, []);

Expand Down Expand Up @@ -371,7 +377,7 @@ async function doResultPromise(t, mode) {
},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);
t.deepEqual(log, []);

const slot0arg = { '@qclass': 'slot', index: 0 };
Expand Down
12 changes: 9 additions & 3 deletions packages/SwingSet/test/test-vpid-liveslots.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ function resolutionOf(vpid, mode, targets) {
}
}

function makeDispatch(syscall, build) {
const { setBuildRootObject, dispatch } = makeLiveSlots(syscall, null, 'vatA');
setBuildRootObject(build);
return dispatch;
}

async function doVatResolveCase1(t, mode) {
// case 1
const { log, syscall } = buildSyscall();
Expand All @@ -207,7 +213,7 @@ async function doVatResolveCase1(t, mode) {
},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);
t.deepEqual(log, []);

const rootA = 'o+0';
Expand Down Expand Up @@ -374,7 +380,7 @@ async function doVatResolveCase23(t, which, mode, stalls) {
},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);
t.deepEqual(log, []);

const rootA = 'o+0';
Expand Down Expand Up @@ -605,7 +611,7 @@ async function doVatResolveCase4(t, mode) {
four() {},
});
}
const dispatch = makeLiveSlots(syscall, {}, build, 'vatA');
const dispatch = makeDispatch(syscall, build);
t.deepEqual(log, []);

const rootA = 'o+0';
Expand Down

0 comments on commit 165205f

Please sign in to comment.