From e8e56d903e5d356c41aedfd07fadf0d363c82476 Mon Sep 17 00:00:00 2001 From: "Mark S. Miller" Date: Sun, 5 May 2024 22:00:23 -0700 Subject: [PATCH] feat(asyncFlow): E support --- packages/async-flow/src/replay-membrane.js | 50 ++++++++++++++++++---- packages/async-flow/src/type-guards.js | 14 +++--- packages/async-flow/src/types.js | 6 +++ 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/packages/async-flow/src/replay-membrane.js b/packages/async-flow/src/replay-membrane.js index 9833ea81bfc0..e4639653f2e9 100644 --- a/packages/async-flow/src/replay-membrane.js +++ b/packages/async-flow/src/replay-membrane.js @@ -3,11 +3,10 @@ import { Fail, b, q } from '@endo/errors'; import { Far, Remotable, getInterfaceOf } from '@endo/pass-style'; import { E } from '@endo/eventual-send'; import { getMethodNames } from '@endo/eventual-send/utils.js'; -import { makePromiseKit } from '@endo/promise-kit'; import { makeEquate } from './equate.js'; import { makeConvertKit } from './convert.js'; -const { fromEntries, defineProperties } = Object; +const { fromEntries, defineProperties, assign } = Object; /** * @param {LogStore} log @@ -195,6 +194,45 @@ export const makeReplayMembrane = ( } }; + // //////////////// Eventual Send //////////////////////////////////////////// + + const guestHandler = harden({ + applyMethod(guestTarget, verb, _guestArgs, _guestReturnedP) { + Fail`guest eventual send not yet supported: ${guestTarget}.${b(verb)}(...)`; + }, + applyFunction(guestTarget, _guestArgs, _guestReturnedP) { + Fail`guest eventual call not yet supported: ${guestTarget}`; + }, + get(guestPresence, prop) { + Fail`guest eventual get not yet supported: ${guestPresence}.${b(prop)}`; + }, + }); + + const makeGuestPresence = (iface, methodEntries) => { + let guestPresence; + void new HandledPromise((_res, _rej, resolveWithPresence) => { + guestPresence = resolveWithPresence(guestHandler); + }); // no unfulfilledHandler + if (typeof guestPresence !== 'object') { + throw Fail`presence expected to be object ${guestPresence}`; + } + assign(guestPresence, fromEntries(methodEntries)); + const result = Remotable(iface, undefined, guestPresence); + result === guestPresence || + Fail`Remotable expected to make presence in place: ${guestPresence} vs ${result}`; + return result; + }; + + const makeGuestPromiseKit = () => { + let resolve; + let reject; + const promise = new HandledPromise((res, rej, _resPres) => { + resolve = res; + reject = rej; + }, guestHandler); + return harden({ promise, resolve, reject }); + }; + // //////////////// Converters /////////////////////////////////////////////// const makeGuestForHostRemotable = hRem => { @@ -234,18 +272,14 @@ export const makeReplayMembrane = ( name, makeGuestMethod(name), ]); - // TODO in order to support E *well*, - // use HandledPromise to make gRem a remote presence for hRem - gRem = Remotable(guestIface, undefined, fromEntries(guestMethods)); + gRem = makeGuestPresence(guestIface, guestMethods); } return gRem; }; harden(makeGuestForHostRemotable); const makeGuestForHostVow = hVow => { - // TODO in order to support E *well*, - // use HandledPromise to make `promise` a handled promise for hVow - const { promise, resolve, reject } = makePromiseKit(); + const { promise, resolve, reject } = makeGuestPromiseKit(); guestPromiseMap.set(promise, harden({ resolve, reject })); watchWake(hVow); diff --git a/packages/async-flow/src/type-guards.js b/packages/async-flow/src/type-guards.js index 65551bd5f89e..c3ebc5267391 100644 --- a/packages/async-flow/src/type-guards.js +++ b/packages/async-flow/src/type-guards.js @@ -42,13 +42,13 @@ export const LogEntryShape = M.or( M.arrayOf(M.any()), M.number(), ], - // [ - // 'checkSend', - // M.or(M.remotable('host target'), VowShape), - // M.opt(PropertyKeyShape), - // M.arrayOf(M.any()), - // M.number(), - // ], + [ + 'checkSend', + M.or(M.remotable('host target'), VowShape), + M.opt(PropertyKeyShape), + M.arrayOf(M.any()), + M.number(), + ], // ['checkReturn', M.number(), M.any()], // ['checkThrow', M.number(), M.any()], ); diff --git a/packages/async-flow/src/types.js b/packages/async-flow/src/types.js index 842574673906..cc5e5a1f315d 100644 --- a/packages/async-flow/src/types.js +++ b/packages/async-flow/src/types.js @@ -95,6 +95,12 @@ * optVerb: PropertyKey|undefined, * args: Host[], * callIndex: number + * ] | [ + * op: 'checkSend', + * target: Host, + * optVerb: PropertyKey|undefined, + * args: Host[], + * callIndex: number * ]} LogEntry */