-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(swingset): support raw devices #4419
Conversation
f93f537
to
42cb11e
Compare
7bdeadd
to
abc7408
Compare
42cb11e
to
85c2881
Compare
abc7408
to
0e8da51
Compare
85c2881
to
8de185f
Compare
17a7b58
to
954c24c
Compare
3165b61
to
67cc5a4
Compare
954c24c
to
fcecb70
Compare
67cc5a4
to
52a96e2
Compare
fcecb70
to
3ed5ba9
Compare
3ed5ba9
to
6724c36
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine, modulo the concern I raised in my first comment which is a bigger question than is worth confronting in a PR.
This mode makes it possible to create new device nodes as part of the normal | ||
API, because the code can learn the raw device ref (dref) of the target | ||
device node on each inbound invocation, without needing a pre-registered | ||
table of JavaScript `Object` instances for every export. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if an alternate model would be to implement devices using deviceSlots but treat the root object of a (more sophisticated kind of) device rather the way we treat the root object of a vat: the contact point for bootstrapping further interactions with whatever services it provides. As part of the API provided by deviceSlots, devices would have access to a createDeviceNode
power that would create a device node that could be returned when a method is invoked on the root object. In essence, device node 0 would be qualitatively different: a privileged control device that hands out function-specific device nodes, in contrast to the function-specific device nodes themselves which would provide whatever services the "device" is being created to support.
Obviously this would require a somewhat different model than we have now of what it means to be the client of a device, since this controller vs. service distinction would have to be reflected in whatever vat(s) are using the device.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I think a more unified model (which would fully satisfy the goals of #1346) would probably allow the export of both objects and device nodes, and then the root could be a plain object, from which you must ask for device nodes via E()
calls. maybe.
vatstoreGet: key => { | ||
const dso = harden(['vatstoreGet', key]); | ||
return deviceSyscallHandler(dso); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choosing not to support vatstoreGetAfter
or just not gotten around to it? I could argue the desirability of support this syscall either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not gotten around to it: my use case doesn't need it yet, and I didn't want to put the energy into figuring out the protective get-during-iterate invalidation logic we went through for vats. I'm happy to allow devices to use vatstoreGetAfter
some day.
"Raw devices" bypass the deviceSlots layer and allow device code direct access to `syscall`, and the arguments arriving through the `dispatch` object it must produce. This makes some patterns much easier to implement, such as producing new device nodes as part of the device's API (e.g. one device node per code bundle). It also provides vatstoreGet/Set/Delete, so the device code can manage one piece of state at a time, instead of doing an expensive read-modify-write cycle on a single large aggregate state object. A helper library named deviceTools.js was added to make it slightly easier to write a raw device. In the longer run (see #1346), we'd like these devices to support Promises and plain object references. This change doesn't go that far. The remaining limitations are: * the deviceTools.js library refuses to handle exported objects, imported foreign device nodes, or promises of any sort * the outbound translator (deviceKeeper.js `mapDeviceSlotToKernelSlot`) refuses to handle exported objects and exported promises * the vat outbound translator (vatTranslator.js `translateCallNow`) refuses to handle promises * liveslots rejects promises in `D()` arguments refs #1346
6724c36
to
e74cf17
Compare
"Raw devices" bypass the deviceSlots layer and allow device code direct
access to
syscall
, and the arguments arriving through thedispatch
objectit must produce. This makes some patterns much easier to implement, such as
producing new device nodes as part of the device's API (e.g. one device node
per code bundle).
It also provides vatstoreGet/Set/Delete, so the device code can manage one
piece of state at a time, instead of doing an expensive read-modify-write
cycle on a single large aggregate state object.
A helper library named deviceTools.js was added to make it slightly easier to
write a raw device.
In the longer run (see #1346), we'd like these devices to support Promises
and plain object references. This change doesn't go that far. The remaining
limitations are:
foreign device nodes, or promises of any sort
mapDeviceSlotToKernelSlot
)refuses to handle exported objects and exported promises
translateCallNow
) refusesto handle promises
D()
argumentsrefs #1346