UNPKG

@metamask/ocap-kernel

Version:
72 lines 3.03 kB
import { insistVatSyscallObject, insistVatSyscallResult } from "@agoric/swingset-liveslots"; /** * This returns a function that is provided to liveslots as the 'syscall' * argument: an object with one method per syscall type. These methods return * data, or nothing. If the kernel experiences a problem executing the syscall, * the method will throw, or the kernel will kill the vat, or both. * * I should be given a `syscallToManager` function that accepts a * VatSyscallObject and (synchronously) returns a VatSyscallResult. * * @param supervisor - The VatSupervisor for which we're providing syscall services. * @param kv - A key/value store for holding the vat's persistent state. * * @returns a syscall object suitable for use by liveslots. */ function makeSupervisorSyscall(supervisor, kv) { /** * Actually perform the syscall operation. * * @param vso - A descriptor for the syscall to be performed. * @returns the result from performing the syscall. */ function doSyscall(vso) { insistVatSyscallObject(vso); let syscallResult; try { syscallResult = supervisor.executeSyscall(vso); } catch (problem) { console.warn(`supervisor got error during syscall:`, problem); throw problem; } const vsr = syscallResult; insistVatSyscallResult(vsr); const [type, ...rest] = vsr; switch (type) { case 'ok': { const [data] = rest; return data; } case 'error': { const [problem] = rest; throw Error(`syscall.${vso[0]} failed: ${problem}`); } default: throw Error(`unknown result type ${type}`); } } // this will be given to liveslots, it should have distinct methods that // return immediate results or throw errors const syscallForVat = { send: (target, methargs, result) => doSyscall(['send', target, { methargs, result }]), subscribe: (vpid) => doSyscall(['subscribe', vpid]), resolve: (resolutions) => doSyscall(['resolve', resolutions]), exit: (isFailure, info) => doSyscall(['exit', isFailure, info]), dropImports: (vrefs) => doSyscall(['dropImports', vrefs]), retireImports: (vrefs) => doSyscall(['retireImports', vrefs]), retireExports: (vrefs) => doSyscall(['retireExports', vrefs]), abandonExports: (vrefs) => doSyscall(['abandonExports', vrefs]), callNow: (_target, _method, _args) => { throw Error(`callNow not supported (we have no devices)`); }, vatstoreGet: (key) => kv.get(key), vatstoreGetNextKey: (priorKey) => kv.getNextKey(priorKey), vatstoreSet: (key, value) => kv.set(key, value), vatstoreDelete: (key) => kv.delete(key), }; return harden(syscallForVat); } harden(makeSupervisorSyscall); export { makeSupervisorSyscall }; //# sourceMappingURL=syscall.mjs.map