Skip to content

Commit

Permalink
refactor(kmarshal): simplify makeStandinPromise (#9475)
Browse files Browse the repository at this point in the history
closes: #9434 
refs: #XXXX

## Description

This removes a kludge needed to accommodate an ancient version of endo. The kludge should no longer be needed, and the remaining code can be simpler.

However, we cannot actually merge this PR to master until we know we do not need to worry about this ancient version of endo.

- [ ] identify what version of endo fixed the problem that the kludge addressed
- [ ] figure out whether that should still inhibit merging this simplification.

Altogether, the kludge is small and cheap, so there's nothing urgent about merging this PR. We should wait until we're confident about the compat risk.

### Security Considerations

none
### Scaling Considerations

none
### Documentation Considerations

none
### Testing Considerations

none
### Upgrade Considerations

none
  • Loading branch information
erights authored Jul 3, 2024
1 parent a9680dd commit 00afafb
Showing 1 changed file with 3 additions and 66 deletions.
69 changes: 3 additions & 66 deletions packages/kmarshal/src/kmarshal.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Far, passStyleOf } from '@endo/far';
import { makeMarshal } from '@endo/marshal';

/**
* @import { ERef } from '@endo/far';
* @import {ConvertSlotToVal} from '@endo/marshal';
*/

Expand All @@ -19,7 +18,7 @@ import { makeMarshal } from '@endo/marshal';

const { toStringTag } = Symbol;

const makeStringStandinPromise = kref => {
const makeStandinPromise = kref => {
const p = Promise.resolve(`${kref} stand in`);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Object.defineProperty(p, toStringTag, {
Expand All @@ -28,78 +27,16 @@ const makeStringStandinPromise = kref => {
});
return harden(p);
};
harden(makeStandinPromise);

const getStringStandinPromiseTag = p => {
const getStandinPromiseTag = p => {
const desc = Object.getOwnPropertyDescriptor(p, toStringTag);
assert(desc !== undefined, 'promise lacks own @@toStringTag property');
const kref = desc.value;
assert.typeof(kref, 'string');
return kref;
};

const makeAccessorStandinPromise = kref => {
// TODO This Bizarro world hack is only for the version of Endo that
// agoric-sdk currently depends on, and is already inconsistent with
// the "current" endo. Once agoric-sdk depends only on the next endo,
// we should delete this code, and rename `makeStringStandinPromise`
// above to `makeStandinPromise`.
//
// Bizarro World hack for attaching a string property to a Promise, courtesy
// of MarkM. Even though the @@toStringTag property nominally *is* a
// string, some unfortunate stuff in our hardened JS safety checks blows up
// if it actually is. Eventually that will be fixed and we'll be able to
// use the @@toStringTag property directly, but for now we need to use this
// weird construct employing a sneaky getter function. Note that this is
// only necessary in the first place because smallcaps encodes promise
// references differently from remotable object references, and the current
// version of the smallcaps decoder annoyingly insists that if the encoded
// body string says a slot is a promise, then convertSlotToVal had better by
// damn return an actual Promise, even if, as in the intended use case here,
// we neither want nor need a promise nor are capable of making any use of
// the fact that it is one.
const p = Promise.resolve(`${kref} stand in`);
// Bizarro World makes eslint hallucinate
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Object.defineProperty(p, toStringTag, {
get: reveal => (reveal ? kref : NaN),
enumerable: false,
});
return harden(p);
};

const getAccessorStandinPromiseTag = p => {
// Other half of Bizarro World hack for handling promises. Note the
// peculiar way the @@toStringTag getter is used.
const desc = Object.getOwnPropertyDescriptor(p, toStringTag);
assert(desc !== undefined, 'promise lacks toStringTag getter');

const getter = desc.get;
assert.typeof(getter, 'function', 'toStringTag getter is not a function');
// @ts-expect-error violates the norm that getters have zero parameters
const kref = getter(true);
assert.typeof(kref, 'string');
return kref;
};

const [makeStandinPromise, getStandinPromiseTag] = (() => {
// Use whatever works
try {
const p = makeStringStandinPromise('string mascot');
assert(passStyleOf(p) === 'promise');
return [makeStringStandinPromise, getStringStandinPromiseTag];
} catch (_1) {
try {
const p = makeAccessorStandinPromise('accessor mascot');
assert(passStyleOf(p) === 'promise');
return [makeAccessorStandinPromise, getAccessorStandinPromiseTag];
} catch (_2) {
throw Error('One of the promise tagging schemes should have worked');
}
}
})();
export { makeStandinPromise };
harden(makeStandinPromise);

/**
* @type {ConvertSlotToVal<string>}
*/
Expand Down

0 comments on commit 00afafb

Please sign in to comment.