Skip to content

Commit

Permalink
refactor(SwingSet): Simplify some functions for comprehensibility and…
Browse files Browse the repository at this point in the history
… interactive debugging
  • Loading branch information
gibson042 committed Feb 4, 2025
1 parent 15a18d7 commit 0ac88bd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 52 deletions.
19 changes: 9 additions & 10 deletions packages/SwingSet/src/supervisors/supervisor-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@ function makeSupervisorDispatch(dispatch) {
async function dispatchToVat(delivery) {
// the (low-level) vat is responsible for giving up agency, but we still
// protect against exceptions
return Promise.resolve(delivery)
.then(dispatch)
.then(
res => harden(['ok', res, null]),
err => {
// TODO react more thoughtfully, maybe terminate the vat
console.warn(`error during vat dispatch() of ${delivery}`, err);
return harden(['error', `${err}`, null]);
},
);
await null;
try {
const res = await dispatch(delivery);
return harden(['ok', res, null]);
} catch (err) {
// TODO react more thoughtfully, maybe terminate the vat
console.warn(`error during vat dispatch() of ${delivery}`, err);
return harden(['error', `${err}`, null]);
}
}

return harden(dispatchToVat);
Expand Down
75 changes: 33 additions & 42 deletions packages/SwingSet/tools/run-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,25 @@ export const makeRunUtils = (controller, harness) => {
};

/**
* @typedef {import('@endo/eventual-send').EProxy & {
* sendOnly: (presence: unknown) => Record<string, (...args: any) => void>;
* vat: (name: string) => Record<string, (...args: any) => Promise<any>>;
* }} EVProxy
* @typedef {import('@endo/eventual-send').EProxy | object} EVProxyMethods
* @property {(presence: unknown) => Record<string, (...args: any) => Promise<void>>} sendOnly
* Returns a "methods proxy" for the presence that ignores the results of
* each method invocation.
* @property {(name: string) => Record<string, (...args: any) => Promise<any>>} vat
* Returns a "methods proxy" for the root object of the specified vat.
* So e.g. `EV.vat('foo').m(0)` becomes
* `controller.queueToVatRoot('foo', 'm', [0])`.
* @property {(presence: unknown) => Record<string, Promise<any>>} get
* Returns a "values proxy" for the presence for which each requested
* property manifests as a promise.
*/
/**
* @typedef {import('@endo/eventual-send').EProxy & EVProxyMethods} EVProxy
* Given a presence, return a "methods proxy" for which each requested
* property manifests as a method that forwards its invocation through the
* controller to the presence as an invocation of an identically-named method
* with identical arguments (modulo passable translation).
* So e.g. `EV(x).m(0)` becomes `controller.queueToVatObject(x, 'm', [0])`.
*/

// IMPORTANT WARNING TO USERS OF `EV`
Expand Down Expand Up @@ -103,50 +118,26 @@ export const makeRunUtils = (controller, harness) => {
// promise that can remain pending indefinitely, possibly to be settled by a
// future message delivery.

const makeMethodsProxy = (invoker, target, voidResult = false) =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() => invoker(target, method, args), voidResult);
return harden(boundMethod);
},
});

/** @type {EVProxy} */
// @ts-expect-error cast, approximate
const EV = Object.assign(
presence =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() =>
controller.queueToVatObject(presence, method, args),
);
return harden(boundMethod);
},
}),
presence => makeMethodsProxy(controller.queueToVatObject, presence),
{
vat: vatName =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(() =>
controller.queueToVatRoot(vatName, method, args),
);
return harden(boundMethod);
},
}),
vat: vatName => makeMethodsProxy(controller.queueToVatRoot, vatName),
sendOnly: presence =>
new Proxy(harden({}), {
get: (_t, method, _rx) => {
const boundMethod = (...args) =>
queueAndRun(
() => controller.queueToVatObject(presence, method, args),
true,
);
return harden(boundMethod);
},
}),
makeMethodsProxy(controller.queueToVatObject, presence, true),
get: presence =>
new Proxy(harden({}), {
get: (_t, pathElement, _rx) =>
queueAndRun(() =>
controller.queueToVatRoot('bootstrap', 'awaitVatObject', [
presence,
[pathElement],
]),
),
get: (_t, key, _rx) =>
EV.vat('bootstrap').awaitVatObject(presence, [key]),
}),
},
);
Expand Down

0 comments on commit 0ac88bd

Please sign in to comment.