Skip to content
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

spike(pass-style)! remove passable symbols to see what breaks #2452

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions packages/exo/src/exo-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
getAwaitArgGuardPayload,
getMethodGuardPayload,
getInterfaceGuardPayload,
getCopyMapEntries,
} from '@endo/patterns';
import { listDifference } from '@endo/common/list-difference.js';
import { objectMap } from '@endo/common/object-map.js';
Expand All @@ -22,7 +21,7 @@ import { GET_INTERFACE_GUARD } from './get-interface.js';
*/

const { apply, ownKeys } = Reflect;
const { defineProperties, fromEntries } = Object;
const { defineProperties } = Object;

/**
* A method guard, for inclusion in an interface guard, that does not
Expand Down Expand Up @@ -381,14 +380,11 @@ export const defendPrototype = (
const {
interfaceName,
methodGuards: mg,
symbolMethodGuards,
sloppy,
defaultGuards: dg = sloppy ? 'passable' : defaultGuards,
} = getInterfaceGuardPayload(interfaceGuard);
methodGuards = harden({
...mg,
...(symbolMethodGuards &&
fromEntries(getCopyMapEntries(symbolMethodGuards))),
});
defaultGuards = dg;
{
Expand Down
10 changes: 1 addition & 9 deletions packages/exo/test/heap-classes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,15 @@ test('test defineExoClass', t => {
t.deepEqual(upCounter[GET_INTERFACE_GUARD]?.(), UpCounterI);
t.deepEqual(getInterfaceMethodKeys(UpCounterI), ['incr']);

const symbolic = Symbol.for('symbolic');
const FooI = M.interface('Foo', {
m: M.call().returns(),
[symbolic]: M.call(M.boolean()).returns(),
});
t.deepEqual(getInterfaceMethodKeys(FooI), ['m', Symbol.for('symbolic')]);
t.deepEqual(getInterfaceMethodKeys(FooI), ['m']);
const makeFoo = defineExoClass('Foo', FooI, () => ({}), {
m() {},
[symbolic]() {},
});
const foo = makeFoo();
t.deepEqual(foo[GET_INTERFACE_GUARD]?.(), FooI);
// @ts-expect-error intentional for test
t.throws(() => foo[symbolic]('invalid arg'), {
message:
'In "[Symbol(symbolic)]" method of (Foo): arg 0: string "invalid arg" - Must be a boolean',
});
});

test('test defineExoClassKit', t => {
Expand Down
9 changes: 1 addition & 8 deletions packages/exo/test/non-enumerable-methods.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,18 @@ test('test defineExoClass', t => {
t.deepEqual(upCounter[GET_INTERFACE_GUARD](), UpCounterI);
t.deepEqual(getInterfaceMethodKeys(UpCounterI), ['incr']);

const symbolic = Symbol.for('symbolic');
const FooI = M.interface('Foo', {
m: M.call().returns(),
[symbolic]: M.call(M.boolean()).returns(),
});
t.deepEqual(getInterfaceMethodKeys(FooI), ['m', Symbol.for('symbolic')]);
t.deepEqual(getInterfaceMethodKeys(FooI), ['m']);
const makeFoo = defineExoClass(
'Foo',
FooI,
() => ({}),
denumerate({
m() {},
[symbolic]() {},
}),
);
const foo = makeFoo();
t.deepEqual(foo[GET_INTERFACE_GUARD](), FooI);
t.throws(() => foo[symbolic]('invalid arg'), {
message:
'In "[Symbol(symbolic)]" method of (Foo): arg 0: string "invalid arg" - Must be a boolean',
});
});
14 changes: 0 additions & 14 deletions packages/marshal/src/encodePassable.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import {
passStyleOf,
assertRecord,
isErrorLike,
nameForPassableSymbol,
passableSymbolForName,
} from '@endo/pass-style';

/**
Expand Down Expand Up @@ -617,12 +615,6 @@ const makeInnerEncode = (encodeStringSuffix, encodeArray, options) => {
case 'promise': {
return encodePromise(passable, innerEncode);
}
case 'symbol': {
// Strings and symbols share encoding logic.
const name = nameForPassableSymbol(passable);
assert.typeof(name, 'string');
return `y${encodeStringSuffix(name)}`;
}
case 'copyArray': {
return encodeArray(passable, innerEncode);
}
Expand Down Expand Up @@ -709,11 +701,6 @@ const makeInnerDecode = (decodeStringSuffix, decodeArray, options) => {
case '!': {
return decodeError(getSuffix(encoded, skip), innerDecode);
}
case 'y': {
// Strings and symbols share decoding logic.
const name = decodeStringSuffix(getSuffix(encoded, skip + 1));
return passableSymbolForName(name);
}
case '[':
case '^': {
// @ts-expect-error Type 'unknown[]' is not Passable
Expand Down Expand Up @@ -876,7 +863,6 @@ export const passStylePrefixes = {
remotable: 'r',
string: 's',
null: 'v',
symbol: 'y',
// Because Array.prototype.sort puts undefined values at the end without
// passing them to a comparison function, undefined MUST be the last
// category.
Expand Down
22 changes: 0 additions & 22 deletions packages/marshal/src/encodeToCapData.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import {
isObject,
getTag,
hasOwnPropertyOf,
assertPassableSymbol,
nameForPassableSymbol,
passableSymbolForName,
} from '@endo/pass-style';
import { X, Fail, q } from '@endo/errors';

Expand Down Expand Up @@ -155,14 +152,6 @@ export const makeEncodeToCapData = (encodeOptions = {}) => {
digits: String(passable),
};
}
case 'symbol': {
assertPassableSymbol(passable);
const name = /** @type {string} */ (nameForPassableSymbol(passable));
return {
[QCLASS]: 'symbol',
name,
};
}
case 'copyRecord': {
if (hasOwnPropertyOf(passable, QCLASS)) {
// Hilbert hotel
Expand Down Expand Up @@ -349,17 +338,6 @@ export const makeDecodeFromCapData = (decodeOptions = {}) => {
Fail`invalid digits typeof ${q(typeof digits)}`;
return BigInt(digits);
}
case '@@asyncIterator': {
// Deprecated qclass. TODO make conditional
// on environment variable. Eventually remove, but after confident
// that there are no more supported senders.
//
return Symbol.asyncIterator;
}
case 'symbol': {
const { name } = jsonEncoded;
return passableSymbolForName(name);
}
case 'tagged': {
const { tag, payload } = jsonEncoded;
return makeTagged(tag, decodeFromCapData(payload));
Expand Down
11 changes: 0 additions & 11 deletions packages/marshal/src/encodeToSmallcaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ import {
makeTagged,
getTag,
hasOwnPropertyOf,
assertPassableSymbol,
nameForPassableSymbol,
passableSymbolForName,
} from '@endo/pass-style';
import { X, Fail, q } from '@endo/errors';

Expand Down Expand Up @@ -209,11 +206,6 @@ export const makeEncodeToSmallcaps = (encodeOptions = {}) => {
const str = String(passable);
return /** @type {bigint} */ (passable) < 0n ? str : `+${str}`;
}
case 'symbol': {
assertPassableSymbol(passable);
const name = /** @type {string} */ (nameForPassableSymbol(passable));
return `%${name}`;
}
case 'copyRecord': {
// Currently copyRecord allows only string keys so this will
// work. If we allow sortable symbol keys, this will need to
Expand Down Expand Up @@ -353,9 +345,6 @@ export const makeDecodeFromSmallcaps = (decodeOptions = {}) => {
// un-hilbert-ify the string
return encoding.slice(1);
}
case '%': {
return passableSymbolForName(encoding.slice(1));
}
case '#': {
switch (encoding) {
case '#undefined': {
Expand Down
29 changes: 1 addition & 28 deletions packages/marshal/src/marshal-justin.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
/// <reference types="ses"/>

import { Nat } from '@endo/nat';
import {
getErrorConstructor,
isObject,
passableSymbolForName,
} from '@endo/pass-style';
import { getErrorConstructor, isObject } from '@endo/pass-style';
import { q, X, Fail } from '@endo/errors';
import { QCLASS } from './encodeToCapData.js';

Expand Down Expand Up @@ -165,13 +161,6 @@ const decodeToJustin = (encoding, shouldIndent = false, slots = []) => {
case '@@asyncIterator': {
return;
}
case 'symbol': {
const { name } = rawTree;
assert.typeof(name, 'string');
const sym = passableSymbolForName(name);
assert.typeof(sym, 'symbol');
return;
}
case 'tagged': {
const { tag, payload } = rawTree;
assert.typeof(tag, 'string');
Expand Down Expand Up @@ -318,22 +307,6 @@ const decodeToJustin = (encoding, shouldIndent = false, slots = []) => {
// TODO deprecated. Eventually remove.
return out.next('Symbol.asyncIterator');
}
case 'symbol': {
const { name } = rawTree;
assert.typeof(name, 'string');
const sym = passableSymbolForName(name);
assert.typeof(sym, 'symbol');
const registeredName = Symbol.keyFor(sym);
if (registeredName === undefined) {
const match = AtAtPrefixPattern.exec(name);
assert(match !== null);
const suffix = match[1];
assert(Symbol[suffix] === sym);
assert(identPattern.test(suffix));
return out.next(`Symbol.${suffix}`);
}
return out.next(`Symbol.for(${quote(registeredName)})`);
}
case 'tagged': {
const { tag, payload } = rawTree;
out.next(`makeTagged(${quote(tag)},`);
Expand Down
8 changes: 1 addition & 7 deletions packages/marshal/src/rankOrder.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getTag, passStyleOf, nameForPassableSymbol } from '@endo/pass-style';
import { getTag, passStyleOf } from '@endo/pass-style';
import { Fail, q } from '@endo/errors';
import {
passStylePrefixes,
Expand Down Expand Up @@ -150,12 +150,6 @@ export const makeComparatorKit = (compareRemotables = (_x, _y) => NaN) => {
return 1;
}
}
case 'symbol': {
return comparator(
nameForPassableSymbol(left),
nameForPassableSymbol(right),
);
}
case 'number': {
// `NaN`'s rank is after all other numbers.
if (Number.isNaN(left)) {
Expand Down
5 changes: 2 additions & 3 deletions packages/marshal/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ export {};
* EncodingClass<'Infinity'> |
* EncodingClass<'-Infinity'> |
* EncodingClass<'bigint'> & { digits: string } |
* EncodingClass<'@@asyncIterator'> |
* EncodingClass<'symbol'> & { name: string } |
* EncodingClass<'error'> & { name: string,
* message: string,
* errorId?: string,
Expand All @@ -50,7 +48,8 @@ export {};
* }
* } EncodingUnion
*
* Note that the '@@asyncIterator' encoding is deprecated. Use 'symbol' instead.
* Note that the '@@asyncIterator' and 'symbol' encodings are no longer
* supported.
*
* The 'hilbert' encoding is a reference to the Hilbert Hotel
* of https://www.ias.edu/ideas/2016/pires-hilbert-hotel .
Expand Down
20 changes: 0 additions & 20 deletions packages/marshal/test/_marshal-test-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ export const roundTripPairs = harden([
// Does not fit into a number
[9007199254740993n, { '@qclass': 'bigint', digits: '9007199254740993' }],

// Well known symbols
[Symbol.asyncIterator, { '@qclass': 'symbol', name: '@@asyncIterator' }],
[Symbol.match, { '@qclass': 'symbol', name: '@@match' }],
// Registered symbols
[Symbol.for('foo'), { '@qclass': 'symbol', name: 'foo' }],
// Registered symbol hilbert hotel
[Symbol.for('@@foo'), { '@qclass': 'symbol', name: '@@@@foo' }],

// Normal json reviver cannot make properties with undefined values
[[undefined], [{ '@qclass': 'undefined' }]],
[{ foo: undefined }, { foo: { '@qclass': 'undefined' } }],
Expand Down Expand Up @@ -181,10 +173,6 @@ export const jsonJustinPairs = harden([
['{"@qclass":"-Infinity"}', '-Infinity'],
['{"@qclass":"bigint","digits":"4"}', '4n'],
['{"@qclass":"bigint","digits":"9007199254740993"}', '9007199254740993n'],
['{"@qclass":"symbol","name":"@@asyncIterator"}', 'Symbol.asyncIterator'],
['{"@qclass":"symbol","name":"@@match"}', 'Symbol.match'],
['{"@qclass":"symbol","name":"foo"}', 'Symbol.for("foo")'],
['{"@qclass":"symbol","name":"@@@@foo"}', 'Symbol.for("@@foo")'],

// Arrays and objects
['[{"@qclass":"undefined"}]', '[undefined]'],
Expand Down Expand Up @@ -264,11 +252,8 @@ export const unsortedSample = harden([
[5],
exampleAlice,
[],
Symbol.for('foo'),
Error('not erroneous'),
Symbol.for('@@foo'),
[5, { bar: 5 }],
Symbol.for(''),
false,
exampleCarol,
[exampleCarol, 'm'],
Expand All @@ -291,7 +276,6 @@ export const unsortedSample = harden([
['b', 3],
]),
Infinity,
Symbol.isConcatSpreadable,
[5, { foo: 4, bar: undefined }],
Promise.resolve('fulfillment'),
[5, { foo: 4 }],
Expand Down Expand Up @@ -385,10 +369,6 @@ export const sortedSample = harden([
'foo',

null,
Symbol.for(''),
Symbol.for('@@foo'),
Symbol.isConcatSpreadable,
Symbol.for('foo'),

undefined,
undefined,
Expand Down
4 changes: 2 additions & 2 deletions packages/marshal/test/marshal-capdata.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ test('serialize static data', t => {
t.deepEqual(ser(-0), ser(0));
// unregistered symbols
t.throws(() => ser(Symbol('sym2')), {
// An anonymous symbol is not Passable
message: /Only registered symbols or well-known symbols are passable:/,
// A symbol is not Passable
message: 'Unrecognized typeof "symbol"',
});

const cd = ser(harden([1, 2]));
Expand Down
16 changes: 2 additions & 14 deletions packages/marshal/test/marshal-smallcaps.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ test('smallcaps serialize static data', t => {
t.deepEqual(ser(0), { body: '#0', slots: [] });
t.deepEqual(ser(-0), { body: '#0', slots: [] });
t.deepEqual(ser(-0), ser(0));
// unregistered symbols
// symbols
t.throws(() => ser(Symbol('sym2')), {
// An anonymous symbol is not Passable
message: /Only registered symbols or well-known symbols are passable:/,
message: 'Unrecognized typeof "symbol"',
});

const cd = ser(harden([1, 2]));
Expand Down Expand Up @@ -324,7 +323,6 @@ test('smallcaps records', t => {
* * `+` - non-negative bigint
* * `-` - negative bigint
* * `#` - manifest constant
* * `%` - symbol
* * `$` - remotable
* * `&` - promise
*/
Expand Down Expand Up @@ -366,16 +364,6 @@ test('smallcaps encoding examples', t => {
assertRoundTrip('-escaped', `#"!-escaped"`, [], 'escaped -');
assertRoundTrip('%escaped', `#"!%escaped"`, [], 'escaped %');

// Symbols
assertRoundTrip(Symbol.iterator, '#"%@@iterator"', [], 'well known symbol');
assertRoundTrip(Symbol.for('foo'), '#"%foo"', [], 'reg symbol');
assertRoundTrip(
Symbol.for('@@foo'),
'#"%@@@@foo"',
[],
'reg symbol that looks well known',
);

// Remotables
const foo = Far('foo', {});
const bar = Far('bar', {
Expand Down
Loading
Loading