@metamask/ocap-kernel
Version:
OCap kernel core components
169 lines • 6.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCListMethods = getCListMethods;
const base_ts_1 = require("./base.cjs");
const reachable_ts_1 = require("./reachable.cjs");
const refcount_ts_1 = require("./refcount.cjs");
const parse_ref_ts_1 = require("../utils/parse-ref.cjs");
const promise_ref_ts_1 = require("../utils/promise-ref.cjs");
const reachable_ts_2 = require("../utils/reachable.cjs");
/**
* Get the c-list methods that provide functionality for managing c-lists.
*
* @param ctx - The store context.
* @returns The c-list store.
*/
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function getCListMethods(ctx) {
const { getSlotKey } = (0, base_ts_1.getBaseMethods)(ctx.kv);
const { clearReachableFlag } = (0, reachable_ts_1.getReachableMethods)(ctx);
const { decrementRefCount } = (0, refcount_ts_1.getRefCountMethods)(ctx);
/**
* Add an entry to an endpoint's c-list, creating a new bidirectional mapping
* between an ERef belonging to the endpoint and a KRef belonging to the
* kernel.
*
* @param endpointId - The endpoint whose c-list is to be added to.
* @param kref - The KRef.
* @param eref - The ERef.
*/
function addCListEntry(endpointId, kref, eref) {
ctx.kv.set(getSlotKey(endpointId, kref), (0, reachable_ts_2.buildReachableAndVatSlot)(true, eref));
ctx.kv.set(getSlotKey(endpointId, eref), kref);
}
/**
* Test if there's a c-list entry for some slot.
*
* @param endpointId - The endpoint of interest
* @param slot - The slot of interest
* @returns true iff this vat has a c-list entry mapping for `slot`.
*/
function hasCListEntry(endpointId, slot) {
return ctx.kv.get(getSlotKey(endpointId, slot)) !== undefined;
}
/**
* Remove an entry from an endpoint's c-list.
*
* @param endpointId - The endpoint whose c-list entry is to be removed.
* @param kref - The KRef.
* @param eref - The ERef.
*/
function deleteCListEntry(endpointId, kref, eref) {
const kernelKey = getSlotKey(endpointId, kref);
const vatKey = getSlotKey(endpointId, eref);
assert(ctx.kv.get(kernelKey));
clearReachableFlag(endpointId, kref);
const { direction } = (0, parse_ref_ts_1.parseRef)(eref);
decrementRefCount(kref, 'delete|kref', {
isExport: direction === 'export',
onlyRecognizable: true,
});
ctx.kv.delete(kernelKey);
ctx.kv.delete(vatKey);
}
/**
* Generate a new eref for a kernel object or promise being imported into an
* endpoint.
*
* @param endpointId - The endpoint the kref is being imported into.
* @param kref - The kref for the kernel object or promise in question.
*
* @returns A new eref in the scope of the given endpoint for the given kernel entity.
*/
function allocateErefForKref(endpointId, kref) {
let id;
const refTag = endpointId.startsWith('v') ? '' : endpointId[0];
let refType;
if ((0, promise_ref_ts_1.isPromiseRef)(kref)) {
id = ctx.kv.get(`e.nextPromiseId.${endpointId}`);
ctx.kv.set(`e.nextPromiseId.${endpointId}`, `${Number(id) + 1}`);
refType = 'p';
}
else {
id = ctx.kv.get(`e.nextObjectId.${endpointId}`);
ctx.kv.set(`e.nextObjectId.${endpointId}`, `${Number(id) + 1}`);
refType = 'o';
}
const eref = `${refTag}${refType}-${id}`;
addCListEntry(endpointId, kref, eref);
return eref;
}
/**
* Look up the ERef that and endpoint's c-list maps a KRef to.
*
* @param endpointId - The endpoint in question.
* @param eref - The ERef to look up.
* @returns The KRef corresponding to `eref` in the given endpoints c-list, or undefined
* if there is no such mapping.
*/
function erefToKref(endpointId, eref) {
return ctx.kv.get(getSlotKey(endpointId, eref));
}
/**
* Look up the KRef that and endpoint's c-list maps an ERef to.
*
* @param endpointId - The endpoint in question.
* @param kref - The KRef to look up.
* @returns The given endpoint's ERef corresponding to `kref`, or undefined if
* there is no such mapping.
*/
function krefToEref(endpointId, kref) {
const key = getSlotKey(endpointId, kref);
const data = ctx.kv.get(key);
if (!data) {
return undefined;
}
const { vatSlot } = (0, reachable_ts_2.parseReachableAndVatSlot)(data);
return vatSlot;
}
/**
* Look up the ERef that and endpoint's c-list maps a KRef to.
*
* @param endpointId - The endpoint in question.
* @param krefs - The KRefs to look up.
* @returns The given endpoint's ERefs corresponding to `krefs`
*/
function krefsToExistingErefs(endpointId, krefs) {
return krefs
.map((kref) => krefToEref(endpointId, kref))
.filter((eref) => Boolean(eref));
}
/**
* Remove an entry from an endpoint's c-list given an eref.
*
* @param endpointId - The endpoint whose c-list entry is to be removed.
* @param eref - The ERef.
*/
function forgetEref(endpointId, eref) {
const kref = erefToKref(endpointId, eref);
if (kref) {
deleteCListEntry(endpointId, kref, eref);
}
}
/**
* Remove an entry from an endpoint's c-list given a kref.
*
* @param endpointId - The endpoint whose c-list entry is to be removed.
* @param kref - The Kref.
*/
function forgetKref(endpointId, kref) {
const eref = krefToEref(endpointId, kref);
if (eref) {
deleteCListEntry(endpointId, kref, eref);
}
}
return {
// C-List entries
addCListEntry,
hasCListEntry,
deleteCListEntry,
// Eref allocation
allocateErefForKref,
erefToKref,
krefToEref,
forgetEref,
forgetKref,
krefsToExistingErefs,
};
}
//# sourceMappingURL=clist.cjs.map