Skip to content

Commit b8b5709

Browse files
committed
fix: prepare for symbol flip
1 parent 1f93cea commit b8b5709

File tree

25 files changed

+385
-237
lines changed

25 files changed

+385
-237
lines changed

package.json

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,40 @@
4242
"resolutions": {
4343
"**/protobufjs": "^7.2.6",
4444
"**/@types/estree": "^1.0.0",
45-
"@endo/eslint-plugin/typescript-eslint": "^8.31.0"
45+
"@endo/eslint-plugin/typescript-eslint": "^8.31.0",
46+
"**/@endo/base64": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/base64/endo-base64-v1.0.9-e26aa4bbfc1648962912233c4662b3d766048751.tgz",
47+
"**/@endo/bundle-source": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/bundle-source/endo-bundle-source-v4.0.0-04e6a272c4acdc1d68899f2d2efae2233bd81a58.tgz",
48+
"**/@endo/captp": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/captp/endo-captp-v4.4.5-a2788c80dd253c4ef480abc4e2d87883182f1daf.tgz",
49+
"**/@endo/check-bundle": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/check-bundle/endo-check-bundle-v1.0.14-f89647f5f5b3906df7218872561f37ff1f8eec94.tgz",
50+
"**/@endo/cjs-module-analyzer": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/cjs-module-analyzer/endo-cjs-module-analyzer-v1.0.9-2de795e14e7aa39b54f00adf6f8e93d2d1196af3.tgz",
51+
"**/@endo/common": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/common/endo-common-v1.2.10-c5fe99fac1129e51d2beacfc7e410ed06490391d.tgz",
52+
"**/@endo/compartment-mapper": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/compartment-mapper/endo-compartment-mapper-v1.6.0-3a3b2e29adb50ba4dd6f69fec516728aa3cc197b.tgz",
53+
"**/@endo/env-options": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/env-options/endo-env-options-v1.1.8-e7695ab0eb7c84d86f908afacea2389ee6f3741d.tgz",
54+
"**/@endo/errors": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/errors/endo-errors-v1.2.10-927ed2c44e387eac3bf92d24a52038de532193b9.tgz",
55+
"**/@endo/eslint-plugin": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/eslint-plugin/endo-eslint-plugin-v2.3.0-9fe4cae97ff010fe808ca3099839fa6bc1646160.tgz",
56+
"**/@endo/evasive-transform": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/evasive-transform/endo-evasive-transform-v1.4.0-fa6c29d607bcd379ea44e6f49338e09f2913ae68.tgz",
57+
"**/@endo/eventual-send": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/eventual-send/endo-eventual-send-v1.3.1-7fdb18153424f8c43c657ec6a33e020ed43d9cff.tgz",
58+
"**/@endo/exo": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/exo/endo-exo-v1.5.9-314be6a2fc87079ad91dc457a54ef65efeb6b54b.tgz",
59+
"**/@endo/far": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/far/endo-far-v1.1.11-bb7624c90eaade01314814d4be5c4a1dae551cca.tgz",
60+
"**/@endo/import-bundle": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/import-bundle/endo-import-bundle-v1.4.0-e829fe16445bcc2614ebe3a2de32519545e58272.tgz",
61+
"**/@endo/init": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/init/endo-init-v1.1.9-4f74fe4fddf0cf7007251e0ead7f019b93914e69.tgz",
62+
"**/@endo/lockdown": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/lockdown/endo-lockdown-v1.0.15-9f8e9b1f6104ed87702e06113a14804edba391f4.tgz",
63+
"**/@endo/lp32": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/lp32/endo-lp32-v1.1.10-0513b5e165b46d8ef329f9f333af191c35d5d25b.tgz",
64+
"**/@endo/marshal": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/marshal/endo-marshal-v1.6.4-86590e81928f519b8d9939fec1a339c8d3f743b4.tgz",
65+
"**/@endo/memoize": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/memoize/endo-memoize-v1.1.10-18d8de7c84d08c473f42a9ae6c5a7ff94470ec38.tgz",
66+
"**/@endo/module-source": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/module-source/endo-module-source-v1.3.0-9f0803bc8fe4f6de3c07c0eab12d2b7b13aa2d74.tgz",
67+
"**/@endo/nat": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/nat/endo-nat-v5.1.0-d9c2518739677e6f1f2db13f717b7264d18f36e1.tgz",
68+
"**/@endo/netstring": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/netstring/endo-netstring-v1.0.15-f52cbf2e63199310bd49c68911f8bde3baa293ee.tgz",
69+
"**/@endo/pass-style": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/pass-style/endo-pass-style-v1.5.0-bc9eba020fc1539dd9435f0933975c741c8511f4.tgz",
70+
"**/@endo/patterns": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/patterns/endo-patterns-v1.5.0-ad8ad75d073ba816fda9620840a4c4932c08b829.tgz",
71+
"**/@endo/promise-kit": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/promise-kit/endo-promise-kit-v1.1.10-98a2d71c1ebb7f90407017879bede33113a21889.tgz",
72+
"**/@endo/ses-ava": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/ses-ava/endo-ses-ava-v1.2.10-8657afed4d81715d9d748aeec8ede44b1f840a2c.tgz",
73+
"**/@endo/stream": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/stream/endo-stream-v1.2.10-d5ab40529af8dae283ce0237db7f003eb7d7db2f.tgz",
74+
"**/@endo/stream-node": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/stream-node/endo-stream-node-v1.1.10-596f83c10d7b973fc39859e9005feb061f4ad6b3.tgz",
75+
"**/@endo/trampoline": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/trampoline/endo-trampoline-v1.0.3-5c71361c31df46075baec608a4bfd148fb4b456f.tgz",
76+
"**/@endo/where": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/where/endo-where-v1.0.9-ce045881698fb212c011438382d30996ca585bd8.tgz",
77+
"**/@endo/zip": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/zip/endo-zip-v1.0.9-302a93648d33179d9f93999878badb36db2ac763.tgz",
78+
"**/ses": "file:/Users/markmiller/src/ongithub/endojs/endo/packages/ses/ses-v1.12.0-a7972133af5cced0a4d5d72725043e8d52aacd6c.tgz"
4679
},
4780
"engines": {
4881
"node": "^18.12 || ^20.9"

packages/SwingSet/test/promises.test.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// @ts-nocheck
2+
// eslint-disable-next-line import/order
23
import { test } from '../tools/prepare-test-env-ava.js';
34

4-
// eslint-disable-next-line import/order
5+
import { passableSymbolForName } from '@agoric/internal';
6+
import { testFullOrderEQ } from '@agoric/internal/tools/ava-full-order-eq.js';
57
import { kser, kslot, kunser } from '@agoric/kmarshal';
68
import {
79
buildVatController,
@@ -259,7 +261,7 @@ test('local promises are rejected by vat upgrade', async t => {
259261
return awaitRun(kpid);
260262
};
261263

262-
const S = Symbol.for('passable');
264+
const S = passableSymbolForName('passable');
263265
const watcher = await messageToVat('bootstrap', 'createVat', {
264266
name: 'watcher',
265267
bundleCapName: 'watcher',
@@ -268,7 +270,7 @@ test('local promises are rejected by vat upgrade', async t => {
268270
await messageToObject(watcher, 'watchLocalPromise', 'fulfilled', S);
269271
await messageToObject(watcher, 'watchLocalPromise', 'rejected', undefined, S);
270272
const v1Settlements = await messageToObject(watcher, 'getSettlements');
271-
t.deepEqual(v1Settlements, {
273+
testFullOrderEQ(t, v1Settlements, {
272274
fulfilled: { status: 'fulfilled', value: S },
273275
rejected: { status: 'rejected', reason: S },
274276
});
@@ -277,7 +279,7 @@ test('local promises are rejected by vat upgrade', async t => {
277279
bundleCapName: 'watcher',
278280
});
279281
const v2Settlements = await messageToObject(watcher, 'getSettlements');
280-
t.deepEqual(v2Settlements, {
282+
testFullOrderEQ(t, v2Settlements, {
281283
fulfilled: { status: 'fulfilled', value: S },
282284
rejected: { status: 'rejected', reason: S },
283285
orphaned: {

packages/cosmic-swingset/src/helpers/bufferedStorage.js

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { assert, Fail } from '@endo/errors';
2+
import { unpassableSymbolForName } from '@agoric/internal';
23

34
// XXX Do these "StorageAPI" functions belong in their own package?
45

@@ -302,8 +303,8 @@ export function makeBufferedStorage(kvStore, listeners = {}) {
302303
export const makeReadCachingStorage = kvStore => {
303304
// In addition to the wrapping write buffer, keep a simple cache of
304305
// read values for has and get.
305-
const deleted = Symbol('deleted');
306-
const undef = Symbol('undefined');
306+
const deleted = unpassableSymbolForName('deleted');
307+
const undef = unpassableSymbolForName('undefined');
307308
/** @typedef {(typeof deleted) | (typeof undef)} ReadCacheSentinel */
308309
/** @type {Map<string, T | ReadCacheSentinel>} */
309310
let cache;
@@ -312,50 +313,51 @@ export const makeReadCachingStorage = kvStore => {
312313
}
313314
resetCache();
314315

315-
/** @type {KVStore<T>} */
316-
const storage = harden({
317-
has(key) {
318-
const value = cache.get(key);
319-
if (value !== undefined) {
320-
return value !== deleted;
321-
} else {
322-
const ret = kvStore.has(key);
323-
if (!ret) {
324-
cache.set(key, deleted);
316+
const storage = /** @type {KVStore<T>} */ (
317+
harden({
318+
has(key) {
319+
const value = cache.get(key);
320+
if (value !== undefined) {
321+
return value !== deleted;
322+
} else {
323+
const ret = kvStore.has(key);
324+
if (!ret) {
325+
cache.set(key, deleted);
326+
}
327+
return ret;
328+
}
329+
},
330+
get(key) {
331+
let value = cache.get(key);
332+
if (value !== undefined) {
333+
return value === deleted || value === undef ? undefined : value;
325334
}
326-
return ret;
327-
}
328-
},
329-
get(key) {
330-
let value = cache.get(key);
331-
if (value !== undefined) {
332-
return value === deleted || value === undef ? undefined : value;
333-
}
334335

335-
// Fetch the value and cache it until the next commit or abort.
336-
value = kvStore.get(key);
337-
cache.set(key, value === undefined ? undef : value);
338-
return value;
339-
},
340-
set(key, value) {
341-
// Set the value and cache it until the next commit or abort (which is
342-
// expected immediately, since the buffered wrapper only calls set
343-
// *during* a commit).
344-
// `undefined` is a valid value technically different than deletion,
345-
// depending on how the underlying store does its serialization
346-
cache.set(key, value === undefined ? undef : value);
347-
kvStore.set(key, value);
348-
},
349-
delete(key) {
350-
// Delete the value and cache the deletion until next commit or abort.
351-
// Deletion results in `undefined` on `get`, but `false` on `has`
352-
cache.set(key, deleted);
353-
kvStore.delete(key);
354-
},
355-
getNextKey(_previousKey) {
356-
throw Error('not implemented');
357-
},
358-
});
336+
// Fetch the value and cache it until the next commit or abort.
337+
value = kvStore.get(key);
338+
cache.set(key, value === undefined ? undef : value);
339+
return value;
340+
},
341+
set(key, value) {
342+
// Set the value and cache it until the next commit or abort (which is
343+
// expected immediately, since the buffered wrapper only calls set
344+
// *during* a commit).
345+
// `undefined` is a valid value technically different than deletion,
346+
// depending on how the underlying store does its serialization
347+
cache.set(key, value === undefined ? undef : value);
348+
kvStore.set(key, value);
349+
},
350+
delete(key) {
351+
// Delete the value and cache the deletion until next commit or abort.
352+
// Deletion results in `undefined` on `get`, but `false` on `has`
353+
cache.set(key, deleted);
354+
kvStore.delete(key);
355+
},
356+
getNextKey(_previousKey) {
357+
throw Error('not implemented');
358+
},
359+
})
360+
);
359361
const {
360362
kvStore: buffered,
361363
commit,

packages/cosmic-swingset/test/export-storage.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import type { TestFn } from 'ava';
22
import anyTest from 'ava';
3+
4+
import { unpassableSymbolForName } from '@agoric/internal';
35
import { exportStorage } from '../src/export-storage.js';
46

57
const test = anyTest as TestFn;
68

79
// Export this binding when used by other modules.
8-
const TestDataKey = Symbol('TestDataKey');
10+
const TestDataKey = unpassableSymbolForName('TestDataKey');
911

1012
// Create a local alias, then
1113
// - regex replace '\._\b' with '[_]'

packages/import-manager/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
"url": "https://github.com/Agoric/agoric-sdk/issues"
3030
},
3131
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
32+
"dependencies": {
33+
"@agoric/internal": "^0.3.2"
34+
},
3235
"devDependencies": {
3336
"@agoric/swingset-vat": "^0.32.2",
3437
"ava": "^5.3.0",

packages/import-manager/test/unitTests/badImports.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// Copyright (C) 2019 Agoric, under Apache License 2.0
22

3+
import { unpassableSymbolForName } from '@agoric/internal';
34
import { importManager } from '../../src/importManager.js';
45
import { listIsEmpty, numIsEmpty } from './valueOps.js';
56

67
function makeBadImportManager() {
78
const mgr = importManager();
89
const obj = { numIsEmpty };
9-
const fooSym = Symbol('foo');
10+
const fooSym = unpassableSymbolForName('foo');
1011
obj[fooSym] = listIsEmpty;
1112
return mgr.addExports(obj);
1213
}

packages/inter-protocol/test/vaultFactory/driver.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { AmountMath, makeIssuerKit } from '@agoric/ertp';
2-
import { allValues, makeTracer, NonNullish, objectMap } from '@agoric/internal';
2+
import {
3+
allValues,
4+
makeTracer,
5+
NonNullish,
6+
objectMap,
7+
unpassableSymbolForName,
8+
} from '@agoric/internal';
39
import { makeNotifierFromSubscriber } from '@agoric/notifier';
410
import { unsafeMakeBundleCache } from '@agoric/swingset-vat/tools/bundleTool.js';
511
import {
@@ -38,7 +44,11 @@ import {
3844

3945
const trace = makeTracer('VFDriver');
4046

41-
export const AT_NEXT = Symbol('AT_NEXT');
47+
// TODO What does it mean to type something to the typeof itself?
48+
// That was the inferred type when the right hand side was `Symbol('AT_NEXT')`
49+
export const AT_NEXT = /** @type {typeof AT_NEXT} */ (
50+
unpassableSymbolForName('AT_NEXT')
51+
);
4252

4353
export const BASIS_POINTS = 10000n;
4454

packages/internal/src/ses-utils.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { objectMap } from '@endo/common/object-map.js';
99
import { objectMetaMap } from '@endo/common/object-meta-map.js';
1010
import { fromUniqueEntries } from '@endo/common/from-unique-entries.js';
1111
import { q, Fail, makeError, annotateError, X } from '@endo/errors';
12+
import { passableSymbolForName as psfn } from '@endo/pass-style';
1213
import { deeplyFulfilled, isObject } from '@endo/marshal';
1314
import { makePromiseKit } from '@endo/promise-kit';
1415
import { makeQueue } from '@endo/stream';
@@ -420,3 +421,29 @@ export const synchronizedTee = (sourceStream, readerCount) => {
420421
void pullNext();
421422
return readers;
422423
};
424+
425+
/**
426+
* An adapter to help transition to flip which symbols are passable. In the endo
427+
* release that's current as of this writing, the real `passableSymbolForName`
428+
* returns `symbol|undefined`.
429+
*
430+
* @param {string} name
431+
* @returns {symbol}
432+
*/
433+
export const passableSymbolForName = name => /** @type {symbol} */ (psfn(name));
434+
435+
const areRegisteredSymbolsPassable =
436+
// TODO Symbol should not be a restricted global for @agoric/internal
437+
// eslint-disable-next-line no-restricted-globals
438+
Symbol.keyFor(passableSymbolForName('x')) === 'x';
439+
440+
/**
441+
* An adapter to help transition to flip which symbols are passable.
442+
*
443+
* @param {string} name
444+
* @returns {symbol}
445+
*/
446+
export const unpassableSymbolForName = name =>
447+
// TODO Symbol should not be a restricted global for @agoric/internal
448+
// eslint-disable-next-line no-restricted-globals
449+
areRegisteredSymbolsPassable ? Symbol(name) : Symbol.for(name);

packages/internal/test/callback.test.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import test from 'ava';
44
import { Far } from '@endo/far';
55
import { makeHeapZone } from '@agoric/base-zone/heap.js';
66
import * as cb from '../src/callback.js';
7+
import {
8+
passableSymbolForName,
9+
unpassableSymbolForName,
10+
} from '../src/ses-utils.js';
711

812
/** @import {Callback, SyncCallback} from '../src/types.js' */
913

@@ -50,7 +54,11 @@ test('near function callbacks', t => {
5054
});
5155

5256
test('near method callbacks', t => {
53-
const m2 = Symbol.for('m2');
57+
const m2 = passableSymbolForName('m2');
58+
// TODO This currently has a symbol-named method. If it passes, it is only
59+
// because `o` was not made remotable. Should this test case me deleted,
60+
// or should `m2` and its uses be deleted, or should `m2` be converted to
61+
// `'m2'`?
5462
const o = {
5563
/**
5664
* @param {number} a
@@ -121,7 +129,6 @@ test('near method callbacks', t => {
121129
});
122130

123131
test('far method callbacks', async t => {
124-
const m2 = Symbol.for('m2');
125132
const o = Far('MyObject', {
126133
/**
127134
* @param {number} a
@@ -139,7 +146,7 @@ test('far method callbacks', async t => {
139146
* @param {string} c
140147
* @returns {Promise<string>}
141148
*/
142-
[m2]: async (a, b, c) => {
149+
m2: async (a, b, c) => {
143150
return `${a + b}${c}`;
144151
},
145152
});
@@ -153,8 +160,8 @@ test('far method callbacks', async t => {
153160
t.is(await p2r, '19go');
154161

155162
/** @type {Callback<(c: string) => Promise<string>>} */
156-
const cbp3 = cb.makeMethodCallback(Promise.resolve(o), m2, 9, 10);
157-
t.like(cbp3, { methodName: m2, bound: [9, 10] });
163+
const cbp3 = cb.makeMethodCallback(Promise.resolve(o), 'm2', 9, 10);
164+
t.like(cbp3, { methodName: 'm2', bound: [9, 10] });
158165
t.assert(cbp3.target instanceof Promise);
159166
const p3r = cb.callE(cbp3, 'go');
160167
t.assert(p3r instanceof Promise);
@@ -236,7 +243,13 @@ test('isCallback', t => {
236243
'manual method',
237244
);
238245
t.true(
239-
cb.isCallback({ target: {}, methodName: Symbol.for('foo'), bound: [] }),
246+
cb.isCallback({
247+
target: {},
248+
// TODO if this passes with a symbol-named method, it is because
249+
// some relevant object was not made into a remotable.
250+
methodName: passableSymbolForName('foo'),
251+
bound: [],
252+
}),
240253
'manual symbol-keyed method',
241254
);
242255

@@ -249,7 +262,11 @@ test('isCallback', t => {
249262
'non-object target',
250263
);
251264
t.false(
252-
cb.isCallback({ target: {}, methodName: Symbol('foo'), bound: [] }),
265+
cb.isCallback({
266+
target: {},
267+
methodName: unpassableSymbolForName('foo'),
268+
bound: [],
269+
}),
253270
'unique symbol method name',
254271
);
255272
t.false(cb.isCallback({ target: {}, bound: {} }), 'non-array bound args');

packages/internal/test/snapshots/exports.test.js.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ Generated by [AVA](https://avajs.dev).
5252
'objectMap',
5353
'objectMapMutable',
5454
'objectMetaMap',
55+
'passableSymbolForName',
5556
'provideLazyMap',
5657
'pureDataMarshaller',
5758
'synchronizedTee',
5859
'typedEntries',
5960
'typedMap',
61+
'unpassableSymbolForName',
6062
'unprefixedProperties',
6163
'untilTrue',
6264
'whileTrue',
Binary file not shown.

0 commit comments

Comments
 (0)