-
Notifications
You must be signed in to change notification settings - Fork 212
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
Implement the latest version of the defineKind
API
#4962
Conversation
Note: I've marked this as DRAFT because it will not pass CI, because there are a couple of uses of |
Does this also add the crosslinks and |
Yes. Two separate commits, one for the API overhaul and one for the anti-GC-observability stuff. |
I'm assigned as an owner of #4962 , but I don't see much reason for that. I think the `*` line at the top was intended to match things that don't match other lines, but I don't think it works that way. I think it tags me as an owner of every PR.
e3d5627
to
688718a
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.
I defer to other reviewers.
@@ -411,6 +449,27 @@ export function makeVirtualObjectManager( | |||
} | |||
} | |||
|
|||
function copyMethods(behaviorTemplate) { | |||
const obj = {}; | |||
for (const [name, func] of Object.entries(behaviorTemplate)) { |
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.
This enables Symbol-named methods, yeah? I think we want that, at least in the long run, and anyways Far
should be the judge of what keys are allowed, so I think Object.entries
is exactly right.
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 wish. Two factors combine to make this not work well:
Object.entries
omits non-enumerable properties- Object literals with symbol-named properties initialize those properties to be non-enumerable.
> x = {[Symbol.asyncIterator]: () => null}
{ [Symbol(Symbol.asyncIterator)]: [Function: [Symbol.asyncIterator]] }
> Object.entries(x)
[]
> Object.getOwnPropertyDescriptors(x)
{
[Symbol(Symbol.asyncIterator)]: {
value: [Function: [Symbol.asyncIterator]],
writable: true,
enumerable: true,
configurable: true
}
}
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.
No, forget what I just said. The session I captured above shows that my second bullet is false. The new property is enumerable. But Object.entries
omitted it anyway. Which corrected my dim memory: Object.entries
only includes string-named properties.
In any case, I agree that Far
should know what it accepts and others should make minimal assumptions about what that is. Use Reflect.ownKeys
or Object.getOwnPropertyDescriptors
in order to minimize such assumptions.
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.
So are we going to explicitly allow symbol-named methods here and leave it to Far
to reject them?
What about symbol-named facets?
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.
Thinking about this further, symbol-named facets aren't straightforward, because I need to put them in order and sorting Symbols is a pain. In any event, I don't think there's a use case for this aside from obsessive generality, so let's take the idea of symbol-named facets off the table for now.
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.
On deeper analysis, symbol-named methods are kind of PITA too, though if we think it's worth the effort I can do it. But I really don't think it's worth the effort.
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.
Definitely no symbol-named facets. The record naming facets is a copyRecord, and the properties of a copyRecord must be string-named own enumerable properties, so they're exempt from all these painful differences between ways to enumerate own properties. So this restriction is architectural, not expedient.
symbol-named methods here and leave it to
Far
to reject them?
Far
does not reject symbol-named methods. Nor does it reject methods named by non-enumerable properties.
But we currently have only one case we need, @@asyncIterator
, which we could continue to special case for now. If postponing general support for symbol-named methods gets us to MN1 faster, I'm all for postponing. But I think our distributed computational model should eventually support symbol-named methods in general.
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.
If I can put in symbol-named methods in less than, say, an hour's work I'll do it. I suspect I probably can.
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.
A weird thought occurred to me as I was pondering implementation: as long as we do not support symbol-named methods in our over-the-wire message encoding, someone can use symbol-named methods as a kind of private-to-the-local-vat scoping technique. I'm not saying this is a good idea, but I can imagine people doing it. Then, when we turn that feature on, we break their imagined security perimeter. (Even once we support symbols in the method selector portion of a message, I presume they would still be able to use non-registered, non-well-known symbols for this purpose.) This makes me wonder if we should hold off implementing symbol-named methods until we are also implementing symbols as method selectors in messages.
I think this is now ready for final review. Note to @michaelfig @Chris-Hibbert @turadg: would you please take a look at |
586ac9b
to
4dad8be
Compare
Thanks for the ping. I don't see any change in semantics, which is good. I see a separation of
/**
* @typedef {{
* state: ImmutableState & MutableState,
* facets: {
* self: import('@agoric/vat-data/src/types').FunctionsMinusContext<typeof selfBehavior>,
* helper: import('@agoric/vat-data/src/types').FunctionsMinusContext<typeof helperBehavior>,
* },
* }} MethodContext
*/
Not all the above has to be solved in this PR. My blocking requests are to:
|
const collateralBrand = manager.getCollateralBrand(); | ||
const debtBrand = manager.getDebtBrand(); | ||
// #region Computed constants | ||
const collateralBrand = ({ state }) => state.manager.getCollateralBrand(); |
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.
please move the behavior functions within the object that will hold them
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 unclear what you mean by "the behavior functions". Did you mean inline all the behavior functions or just the two that you highlighted in this comment? Because they weren't all inlined before, by any means.
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 did mean all of them. They weren't all inlined in object creation but they were all nested and that's a property that I want to maintain. They also all had JSDoc before and the new object construction breaks that unless they're inlined.
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.
Done! Please give it a look.
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.
Perfect, thank you.
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.
Two small changes to make, plus the xsnap-native
submodule change needs to not be in this PR. Rebasing onto trunk might clear that out, but if not grab me and we can figure it out.
unweakable.add(state); | ||
if (facetNames === null) { | ||
const context = { state }; | ||
unweakable.add(context); |
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.
because I just wondered about it again, and it took me a minute to convince myself it was ok, let's add a one-line comment here
# 'context' does not need a linkToCohort because it's held by the bound methods
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.
oh, crud, I got the comment backwards, and it's going to confuse me in its current state
please replace with:
'context' does not need a linkToCohort because it holds the facets (which hold the cohort)
sorry
How do I expunge the |
4dad8be
to
5065fa9
Compare
c6d08ff
to
6b728a3
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.
r+ module that one extra comment change
unweakable.add(state); | ||
if (facetNames === null) { | ||
const context = { state }; | ||
unweakable.add(context); |
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.
oh, crud, I got the comment backwards, and it's going to confuse me in its current state
please replace with:
'context' does not need a linkToCohort because it holds the facets (which hold the cohort)
sorry
OK, but I think your prior attempt at the comment was also correct. |
6b728a3
to
1d3d756
Compare
1d3d756
to
43df7ec
Compare
43df7ec
to
3e02d42
Compare
This implements the newest version of the
defineKind
API, as laid out in #4905.Closes #4905