Skip to content

Commit

Permalink
fix: @warner review feedback, mostly resulting in variable renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
FUDCo committed Mar 16, 2022
1 parent ced12a7 commit 00604bd
Show file tree
Hide file tree
Showing 7 changed files with 294 additions and 221 deletions.
4 changes: 2 additions & 2 deletions packages/SwingSet/docs/virtual-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The `actualize` parameter is a function that binds an in-memory instance (the "R

2. A new JavaScript object populated with objects as described in (1). These will become facets of the new instance. The returned object will be an object mapping to the facets by name.

The `actualize` function is called whenever a new virtual object instance is created, whenever such an instance is swapped in from secondary storage, and whenever a reference to a virtual object is received as a parameter of a message and deserialized.
The `actualize` function is called whenever a new virtual object instance is created, whenever such an instance is swapped in from secondary storage, and whenever a reference to a virtual object is received as a parameter of a message and deserialized. The `actualize` function for a given VDO kind must always return the same shape of result: if it returns a single instance body, it must always return a single instance body; if it returns a object full of facets, it must always return an object with the exact same facet names.

The `finish` parameter will, if present (it is optional), be called exactly once as part of instance initialization. It will be invoked immediately after the `actualize` function is called for the first time. In other words, it will be called after the instance per se exists but before that instance is returned from the maker function and thus becomes available to whoever requested its creation. `finish` is passed two parameters: the virtual object's state (exactly as passed to the `actualize` function) and the virtual object itself. The `finish` function can modify the object's state in the context of knowing the object's identity, and thus can be used in cases where a validly initialized instance requires it to participate in some kind of cyclical object graph with other virtual objects. It can also be used, for example, to register the object with outside tracking data structures, or do whatever other post-creation setup is needed for the object to do its job. In particular, if one or more of the object's methods need to refer to the object itself (for example, so it can pass itself to other objects), the `finish` function provides a way to capture that identity as part of the object's state.

Expand Down Expand Up @@ -144,7 +144,7 @@ Note that the `init`, `actualize`, and `finish` functions are defined explicitly
Additional important details:
- The set of state properties of an instance is fully determined by the `init` function. That is, the set of properties that exist on `state` is completely determined by the enumerable properties of the object that `init` returns. State properties cannot thereafter be added or removed.
- The set of state properties of an instance is fully determined by the `init` function. That is, the set of properties that exist on in instance's `state` is completely determined by the enumerable properties of the object that `init` returns. State properties cannot thereafter be added or removed. Currently there is no requirement that all instances of a given kind have the same set of properties, but code authors should not rely on this as such enforcement may be added in the future.
- The values a state property may take are limited to things that are serializable and which may be hardened (and, in fact, _are_ hardened and serialized the moment they are assigned). That is, you can replace what value a state property _has_, but you cannot modify a state property's value in situ. In other words, you can do things like:
Expand Down
85 changes: 56 additions & 29 deletions packages/SwingSet/src/lib/parseVatSlots.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,18 @@ import { assert, details as X } from '@agoric/assert';
// as badly. Also, "slot" is a short, single syllable word, which is nice.
// But still "slot" implies containership which I think is wrong.)

// Object/promise references (in vats) contain a three-tuple of (type,
// allocator flag, index). The 'ownership' flag is expressed as a sign: "-"
// means the index was allocated by the kernel, and thus the actual object
// lives in some other vat (and any messages sent to it must go into the
// kernel). "+" means the index was allocated by this vat, hence the object
// lives in this vat, and we can expect to receive messages for it.

/**
* Parse a vat slot reference string into a vat slot object:
* Parse a vref string into its component parts:
* {
* type: STRING, // 'object', 'device', 'promise'
* allocatedByVat: BOOL, // true=>allocated by vat, false=>by the kernel
* id: Nat,
* subid: Nat,
* baseRef: STRING,
* facet: Nat
* }
*
* A slot string (aka "vref") can take one of the forms:
* A vref string can take one of the forms:
*
* T-N
* T+N
Expand Down Expand Up @@ -60,25 +54,58 @@ import { assert, details as X } from '@agoric/assert';
* F if present (only allowed if I is also present) is a decimal integer
* referencing a facet of the referenced object. In this case N/I denotes
* a particular object instance and F indicates which of several possible
* API facets is being addressed. If present this is returned in the
* `facet` property of the result as a BigInt.
*
* @param {string} s The string to be parsed, as described above.
*
* @returns {*} a vat slot object corresponding to the parameter.
*
* @throws if the given string is syntactically incorrect.
* facets of that instance is being addressed. If present this is returned
* in the `facet` property of the result as a BigInt.
*
* The `baseRef` property of the result is `vref` stripped of any facet indicator.
*
* A "vref" identifies an entity visible to vat code to which messages may be
* sent and which may be compared for equality to other such entities. Let's
* call such an entity an "addressable object".
*
* A "baseRef" designates an entity that is managed by LiveSlots, both as a unit
* of garbage collection specifically and as a unit of memory management more
* generally. Such an entity may be a promise or remotable object or imported
* presence, all of which will always be JavaScript objects in memory, or it may
* be a virtual object or collection, which can be in memory or on disk or both.
* Let's call such an entity a "base object". In most cases this is one and the
* same with the addressable object that the vref designates, but in the case of
* a faceted object it is the faceted object as a whole (represented in memory,
* though not on disk, as the cohort array) rather than any particular
* individual facet (the faceted object per se is never exposed directly to code
* running within the vat; only its facets are).
*
* XXX TODO: The previous comment suggests some renaming is warranted:
*
* `slotToVal` maps a baseRef to a base object (actually to a weakRef that
* points to a base object)
* `getValForSlot` maps a baseRef to a base object, or to undefined if it is not
* resident in memory
* `convertSlotToVal` maps a vref to to an addressable object, loading it from
* disk if necessary
*
* `valToSlot` maps an addressable object to a vref
* `getSlotForVal` maps an addressable object to a vref
* `convertValToSlot` maps an addressable object to a vref, generating a new
* vref if necessary
*
* @param {string} vref The string to be parsed, as described above.
*
* @returns {*} a vref components descriptor corresponding to the vref string
* parameter, assuming it is syntactically well formed.
*
* @throws if the given vref string is syntactically incorrect.
*/
export function parseVatSlot(s) {
assert.typeof(s, 'string');
const parts = s.split(':');
assert(parts.length === 1 || parts.length === 2, X`invalid vatSlot ${s}`);
const [slot, facetStr] = parts;
export function parseVatSlot(vref) {
assert.typeof(vref, 'string');
const parts = vref.split(':');
assert(parts.length === 1 || parts.length === 2, X`invalid vref ${vref}`);
const [baseRef, facetStr] = parts;
let type;
let allocatedByVat;
const typechar = slot[0];
const allocchar = slot[1];
const idSuffix = slot.slice(2);
const typechar = baseRef[0];
const allocchar = baseRef[1];
const idSuffix = baseRef.slice(2);

if (typechar === 'o') {
type = 'object';
Expand All @@ -87,15 +114,15 @@ export function parseVatSlot(s) {
} else if (typechar === 'p') {
type = 'promise';
} else {
assert.fail(X`invalid vatSlot ${s}`);
assert.fail(X`invalid vref ${vref}`);
}

if (allocchar === '+') {
allocatedByVat = true;
} else if (allocchar === '-') {
allocatedByVat = false;
} else {
assert.fail(X`invalid vatSlot ${s}`);
assert.fail(X`invalid vref ${vref}`);
}

const delim = idSuffix.indexOf('/');
Expand All @@ -104,7 +131,7 @@ export function parseVatSlot(s) {
let facet;
let virtual = false;
if (delim > 0) {
assert(type === 'object' && allocatedByVat, X`invalid vatSlot ${s}`);
assert(type === 'object' && allocatedByVat, X`invalid vref ${vref}`);
virtual = true;
id = Nat(BigInt(idSuffix.substr(0, delim)));
subid = Nat(BigInt(idSuffix.slice(delim + 1)));
Expand All @@ -115,7 +142,7 @@ export function parseVatSlot(s) {
facet = Nat(BigInt(facetStr));
}

return { type, allocatedByVat, virtual, id, subid, slot, facet };
return { type, allocatedByVat, virtual, id, subid, baseRef, facet };
}

/**
Expand Down
Loading

0 comments on commit 00604bd

Please sign in to comment.