@agoric/swingset-liveslots 0.10.3-other-dev-8f8782b.0 → 0.10.3-other-dev-fbe72e7.0.fbe72e7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/package.json +34 -26
- package/src/boyd-gc.d.ts +12 -0
- package/src/boyd-gc.d.ts.map +1 -0
- package/src/boyd-gc.js +598 -0
- package/src/cache.d.ts +71 -0
- package/src/cache.d.ts.map +1 -0
- package/src/cache.js +3 -2
- package/src/capdata.d.ts +16 -0
- package/src/capdata.d.ts.map +1 -0
- package/src/capdata.js +17 -10
- package/src/collectionManager.d.ts +47 -0
- package/src/collectionManager.d.ts.map +1 -0
- package/src/collectionManager.js +220 -103
- package/src/facetiousness.d.ts +25 -0
- package/src/facetiousness.d.ts.map +1 -0
- package/src/facetiousness.js +1 -1
- package/src/index.d.ts +4 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +4 -2
- package/src/kdebug.d.ts +7 -0
- package/src/kdebug.d.ts.map +1 -0
- package/src/liveslots.d.ts +42 -0
- package/src/liveslots.d.ts.map +1 -0
- package/src/liveslots.js +137 -305
- package/src/message.d.ts +49 -0
- package/src/message.d.ts.map +1 -0
- package/src/message.js +9 -5
- package/src/parseVatSlots.d.ts +125 -0
- package/src/parseVatSlots.d.ts.map +1 -0
- package/src/parseVatSlots.js +1 -1
- package/src/types-index.d.ts +4 -0
- package/src/types-index.js +2 -0
- package/src/types.d.ts +81 -0
- package/src/types.d.ts.map +1 -0
- package/src/types.js +14 -7
- package/src/vatDataTypes.d.ts +170 -0
- package/src/vatDataTypes.d.ts.map +1 -0
- package/src/vatDataTypes.ts +272 -0
- package/src/vatstore-iterators.d.ts +4 -0
- package/src/vatstore-iterators.d.ts.map +1 -0
- package/src/vatstore-iterators.js +2 -0
- package/src/vatstore-usage.md +198 -0
- package/src/virtualObjectManager.d.ts +44 -0
- package/src/virtualObjectManager.d.ts.map +1 -0
- package/src/virtualObjectManager.js +254 -84
- package/src/virtualReferences.d.ts +61 -0
- package/src/virtualReferences.d.ts.map +1 -0
- package/src/virtualReferences.js +135 -26
- package/src/vpid-tracking.md +92 -0
- package/src/watchedPromises.d.ts +31 -0
- package/src/watchedPromises.d.ts.map +1 -0
- package/src/watchedPromises.js +81 -24
- package/test/{test-baggage.js → baggage.test.js} +1 -2
- package/test/{test-cache.js → cache.test.js} +0 -1
- package/test/clear-collection.test.js +586 -0
- package/test/{test-collection-schema-refcount.js → collection-schema-refcount.test.js} +1 -2
- package/test/{test-collection-upgrade.js → collection-upgrade.test.js} +1 -3
- package/test/{test-collections.js → collections.test.js} +183 -18
- package/test/{test-dropped-collection-weakrefs.js → dropped-collection-weakrefs.test.js} +1 -2
- package/test/dropped-weakset-9939.test.js +80 -0
- package/test/dummyMeterControl.d.ts +2 -0
- package/test/dummyMeterControl.d.ts.map +1 -0
- package/test/dummyMeterControl.js +1 -1
- package/test/{test-durabilityChecks.js → durabilityChecks.test.js} +4 -4
- package/test/engine-gc.d.ts +3 -0
- package/test/engine-gc.d.ts.map +1 -0
- package/test/exo-utils.js +70 -0
- package/test/{test-facetiousness.js → facetiousness.test.js} +1 -2
- package/test/gc-and-finalize.d.ts +5 -0
- package/test/gc-and-finalize.d.ts.map +1 -0
- package/test/gc-and-finalize.js +30 -1
- package/test/gc-before-finalizer.test.js +230 -0
- package/test/gc-helpers.js +4 -5
- package/test/{test-gc-sensitivity.js → gc-sensitivity.test.js} +2 -2
- package/test/handled-promises.test.js +872 -0
- package/test/{test-initial-vrefs.js → initial-vrefs.test.js} +13 -20
- package/test/liveslots-helpers.d.ts +64 -0
- package/test/liveslots-helpers.d.ts.map +1 -0
- package/test/liveslots-helpers.js +13 -7
- package/test/{test-liveslots-mock-gc.js → liveslots-mock-gc.test.js} +101 -2
- package/test/{test-liveslots-real-gc.js → liveslots-real-gc.test.js} +73 -46
- package/test/{test-liveslots.js → liveslots.test.js} +17 -18
- package/test/mock-gc.js +1 -0
- package/test/storeGC/{test-lifecycle.js → lifecycle.test.js} +15 -14
- package/test/storeGC/{test-refcount-management.js → refcount-management.test.js} +1 -2
- package/test/storeGC/{test-scalar-store-kind.js → scalar-store-kind.test.js} +0 -1
- package/test/storeGC/{test-weak-key.js → weak-key.test.js} +1 -2
- package/test/strict-test-env-upgrade.test.js +94 -0
- package/test/util.d.ts +25 -0
- package/test/util.d.ts.map +1 -0
- package/test/util.js +4 -4
- package/test/vat-environment.test.js +65 -0
- package/test/vat-util.d.ts +9 -0
- package/test/vat-util.d.ts.map +1 -0
- package/test/vat-util.js +2 -2
- package/test/virtual-objects/{test-cease-recognition.js → cease-recognition.test.js} +2 -2
- package/test/virtual-objects/{test-cross-facet.js → cross-facet.test.js} +5 -4
- package/test/virtual-objects/{test-empty-data.js → empty-data.test.js} +1 -2
- package/test/virtual-objects/{test-facets.js → facets.test.js} +1 -2
- package/test/virtual-objects/{test-kind-changes.js → kind-changes.test.js} +2 -2
- package/test/virtual-objects/{test-reachable-vrefs.js → reachable-vrefs.test.js} +2 -2
- package/test/virtual-objects/{test-rep-tostring.js → rep-tostring.test.js} +3 -5
- package/test/virtual-objects/{test-retain-remotable.js → retain-remotable.test.js} +25 -24
- package/test/virtual-objects/set-debug-label-instances.js +1 -1
- package/test/virtual-objects/state-shape.test.js +389 -0
- package/test/virtual-objects/{test-virtualObjectGC.js → virtualObjectGC.test.js} +39 -38
- package/test/virtual-objects/{test-virtualObjectManager.js → virtualObjectManager.test.js} +104 -8
- package/test/virtual-objects/{test-vo-real-gc.js → vo-real-gc.test.js} +8 -8
- package/test/virtual-objects/{test-weakcollections-vref-handling.js → weakcollections-vref-handling.test.js} +1 -2
- package/test/{test-vo-test-harness.js → vo-test-harness.test.js} +13 -10
- package/test/{test-vpid-liveslots.js → vpid-liveslots.test.js} +105 -5
- package/test/waitUntilQuiescent.d.ts +3 -0
- package/test/waitUntilQuiescent.d.ts.map +1 -0
- package/test/waitUntilQuiescent.js +2 -1
- package/test/weakset-dropped-remotable.test.js +50 -0
- package/tools/fakeCollectionManager.d.ts +14 -0
- package/tools/fakeCollectionManager.d.ts.map +1 -0
- package/tools/fakeCollectionManager.js +44 -0
- package/tools/fakeVirtualObjectManager.d.ts +32 -0
- package/tools/fakeVirtualObjectManager.d.ts.map +1 -0
- package/tools/fakeVirtualObjectManager.js +62 -0
- package/tools/fakeVirtualSupport.d.ts +278 -0
- package/tools/fakeVirtualSupport.d.ts.map +1 -0
- package/tools/fakeVirtualSupport.js +389 -0
- package/tools/prepare-strict-test-env.d.ts +37 -0
- package/tools/prepare-strict-test-env.d.ts.map +1 -0
- package/tools/prepare-strict-test-env.js +124 -0
- package/tools/prepare-test-env.d.ts +2 -0
- package/tools/prepare-test-env.d.ts.map +1 -0
- package/tools/prepare-test-env.js +13 -0
- package/tools/setup-vat-data.d.ts +9 -0
- package/tools/setup-vat-data.d.ts.map +1 -0
- package/tools/setup-vat-data.js +95 -0
- package/tools/vo-test-harness.d.ts +33 -0
- package/tools/vo-test-harness.d.ts.map +1 -0
- package/tools/vo-test-harness.js +164 -0
- package/CHANGELOG.md +0 -61
- package/test/kmarshal.js +0 -79
- package/test/test-handled-promises.js +0 -360
- package/test/virtual-objects/test-state-shape.js +0 -298
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
3
|
|
|
4
4
|
import { Far } from '@endo/marshal';
|
|
5
5
|
import { M } from '@agoric/store';
|
|
6
|
+
import { makeCopyMap, makeCopySet } from '@endo/patterns';
|
|
6
7
|
import { makeFakeCollectionManager } from '../tools/fakeVirtualSupport.js';
|
|
7
8
|
|
|
8
9
|
const {
|
|
@@ -100,6 +101,12 @@ function exerciseMapOperations(t, collectionName, testStore) {
|
|
|
100
101
|
() => testStore.set(86, 'not work'),
|
|
101
102
|
m(`key 86 not found in collection "${collectionName}"`),
|
|
102
103
|
);
|
|
104
|
+
t.throws(
|
|
105
|
+
() => testStore.set(somethingMissing, 'not work'),
|
|
106
|
+
m(
|
|
107
|
+
`key "[Alleged: something missing]" not found in collection "${collectionName}"`,
|
|
108
|
+
),
|
|
109
|
+
);
|
|
103
110
|
t.throws(
|
|
104
111
|
() => testStore.init(47, 'already there'),
|
|
105
112
|
m(`key 47 already registered in collection "${collectionName}"`),
|
|
@@ -117,11 +124,17 @@ function exerciseMapOperations(t, collectionName, testStore) {
|
|
|
117
124
|
t.is(testStore.get(somethingElse), something);
|
|
118
125
|
|
|
119
126
|
testStore.delete(47);
|
|
127
|
+
testStore.delete(something);
|
|
120
128
|
t.falsy(testStore.has(47));
|
|
129
|
+
t.falsy(testStore.has(something));
|
|
121
130
|
t.throws(
|
|
122
131
|
() => testStore.get(47),
|
|
123
132
|
m(`key 47 not found in collection "${collectionName}"`),
|
|
124
133
|
);
|
|
134
|
+
t.throws(
|
|
135
|
+
() => testStore.get(something),
|
|
136
|
+
m(`key "[Alleged: something]" not found in collection "${collectionName}"`),
|
|
137
|
+
);
|
|
125
138
|
t.throws(
|
|
126
139
|
() => testStore.delete(22),
|
|
127
140
|
m(`key 22 not found in collection "${collectionName}"`),
|
|
@@ -132,6 +145,14 @@ function exerciseMapOperations(t, collectionName, testStore) {
|
|
|
132
145
|
`key "[Alleged: something missing]" not found in collection "${collectionName}"`,
|
|
133
146
|
),
|
|
134
147
|
);
|
|
148
|
+
if (collectionName === 'map') {
|
|
149
|
+
// strong map, so we can .clear
|
|
150
|
+
testStore.clear();
|
|
151
|
+
for (const [key, _value] of stuff) {
|
|
152
|
+
t.false(testStore.has(key));
|
|
153
|
+
}
|
|
154
|
+
fillBasicMapStore(testStore);
|
|
155
|
+
}
|
|
135
156
|
}
|
|
136
157
|
|
|
137
158
|
function exerciseSetOperations(t, collectionName, testStore) {
|
|
@@ -146,7 +167,9 @@ function exerciseSetOperations(t, collectionName, testStore) {
|
|
|
146
167
|
t.notThrows(() => testStore.add(47));
|
|
147
168
|
|
|
148
169
|
testStore.delete(47);
|
|
170
|
+
testStore.delete(something);
|
|
149
171
|
t.falsy(testStore.has(47));
|
|
172
|
+
t.falsy(testStore.has(something));
|
|
150
173
|
t.throws(
|
|
151
174
|
() => testStore.delete(22),
|
|
152
175
|
m(`key 22 not found in collection "${collectionName}"`),
|
|
@@ -157,6 +180,14 @@ function exerciseSetOperations(t, collectionName, testStore) {
|
|
|
157
180
|
`key "[Alleged: something missing]" not found in collection "${collectionName}"`,
|
|
158
181
|
),
|
|
159
182
|
);
|
|
183
|
+
if (collectionName === 'set') {
|
|
184
|
+
// strong set, so we can .clear
|
|
185
|
+
testStore.clear();
|
|
186
|
+
for (const [key, _value] of stuff) {
|
|
187
|
+
t.false(testStore.has(key));
|
|
188
|
+
}
|
|
189
|
+
fillBasicSetStore(testStore);
|
|
190
|
+
}
|
|
160
191
|
}
|
|
161
192
|
|
|
162
193
|
test('basic map operations', t => {
|
|
@@ -191,6 +222,89 @@ test('basic weak set operations', t => {
|
|
|
191
222
|
);
|
|
192
223
|
});
|
|
193
224
|
|
|
225
|
+
function exerciseSetAddAll(t, weak, testStore) {
|
|
226
|
+
const allThatStuff = stuff.map(entry => entry[0]);
|
|
227
|
+
|
|
228
|
+
testStore.addAll(allThatStuff);
|
|
229
|
+
for (const elem of allThatStuff) {
|
|
230
|
+
t.truthy(testStore.has(elem));
|
|
231
|
+
testStore.delete(elem);
|
|
232
|
+
}
|
|
233
|
+
if (!weak) {
|
|
234
|
+
t.is(testStore.getSize(), 0);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
testStore.addAll(makeCopySet(allThatStuff));
|
|
238
|
+
for (const elem of allThatStuff) {
|
|
239
|
+
t.truthy(testStore.has(elem));
|
|
240
|
+
testStore.delete(elem);
|
|
241
|
+
}
|
|
242
|
+
if (!weak) {
|
|
243
|
+
t.is(testStore.getSize(), 0);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
t.throws(
|
|
247
|
+
() => testStore.addAll({ bogus: 47 }),
|
|
248
|
+
m(/provided data source is not iterable/),
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
test('set addAll', t => {
|
|
253
|
+
exerciseSetAddAll(t, false, makeScalarBigSetStore('test set'));
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
test('weak set addAll', t => {
|
|
257
|
+
exerciseSetAddAll(t, true, makeScalarBigWeakSetStore('test weak set'));
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
test('set snapshot', t => {
|
|
261
|
+
const testStore = makeScalarBigSetStore('test set');
|
|
262
|
+
const allThatStuff = stuff.map(entry => entry[0]);
|
|
263
|
+
testStore.addAll(allThatStuff);
|
|
264
|
+
t.deepEqual(testStore.snapshot(), makeCopySet(allThatStuff));
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
function exerciseMapAddAll(t, weak, testStore) {
|
|
268
|
+
testStore.addAll(stuff);
|
|
269
|
+
for (const [k, v] of stuff) {
|
|
270
|
+
t.truthy(testStore.has(k));
|
|
271
|
+
t.is(testStore.get(k), v);
|
|
272
|
+
testStore.delete(k);
|
|
273
|
+
}
|
|
274
|
+
if (!weak) {
|
|
275
|
+
t.is(testStore.getSize(), 0);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
testStore.addAll(makeCopyMap(stuff));
|
|
279
|
+
for (const [k, v] of stuff) {
|
|
280
|
+
t.truthy(testStore.has(k));
|
|
281
|
+
t.is(testStore.get(k), v);
|
|
282
|
+
testStore.delete(k);
|
|
283
|
+
}
|
|
284
|
+
if (!weak) {
|
|
285
|
+
t.is(testStore.getSize(), 0);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
t.throws(
|
|
289
|
+
() => testStore.addAll({ bogus: 47 }),
|
|
290
|
+
m(/provided data source is not iterable/),
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
test('map addAll', t => {
|
|
295
|
+
exerciseMapAddAll(t, false, makeScalarBigMapStore('test map'));
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
test('weak map addAll', t => {
|
|
299
|
+
exerciseMapAddAll(t, true, makeScalarBigWeakMapStore('test weak map'));
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test('map snapshot', t => {
|
|
303
|
+
const testStore = makeScalarBigMapStore('test map');
|
|
304
|
+
testStore.addAll(stuff);
|
|
305
|
+
t.deepEqual(testStore.snapshot(), makeCopyMap(stuff));
|
|
306
|
+
});
|
|
307
|
+
|
|
194
308
|
test('constrain map key shape', t => {
|
|
195
309
|
const stringsOnly = makeScalarBigMapStore('map key strings only', {
|
|
196
310
|
keyShape: M.string(),
|
|
@@ -212,7 +326,7 @@ test('constrain map key shape', t => {
|
|
|
212
326
|
t.throws(
|
|
213
327
|
() => noStrings.init('foo', 'string not ok?'),
|
|
214
328
|
m(
|
|
215
|
-
|
|
329
|
+
/^invalid key type for collection "map key no strings": "foo" - Must fail negated pattern: (.*)$/,
|
|
216
330
|
),
|
|
217
331
|
);
|
|
218
332
|
t.is(noStrings.get(47), 'number ok');
|
|
@@ -221,7 +335,14 @@ test('constrain map key shape', t => {
|
|
|
221
335
|
t.throws(
|
|
222
336
|
() => noStrings.get('foo'),
|
|
223
337
|
m(
|
|
224
|
-
|
|
338
|
+
// TODO https://github.com/Agoric/agoric-sdk/issues/11605
|
|
339
|
+
// This is a golden error message test. We're currently in transition
|
|
340
|
+
// from having pattern error messages quote nested patterns using
|
|
341
|
+
// `q` to quoting them using `qp`. In order to tolerate both during
|
|
342
|
+
// this transition at reasonable cost, this golden error message
|
|
343
|
+
// pattern accepts anything in the position of the quoted nested
|
|
344
|
+
// pattern.
|
|
345
|
+
/^invalid key type for collection "map key no strings": "foo" - Must fail negated pattern: (.*)$/,
|
|
225
346
|
),
|
|
226
347
|
);
|
|
227
348
|
|
|
@@ -283,7 +404,14 @@ test('constrain map value shape', t => {
|
|
|
283
404
|
t.throws(
|
|
284
405
|
() => noStrings.init('skey', 'string not ok?'),
|
|
285
406
|
m(
|
|
286
|
-
|
|
407
|
+
// TODO https://github.com/Agoric/agoric-sdk/issues/11605
|
|
408
|
+
// This is a golden error message test. We're currently in transition
|
|
409
|
+
// from having pattern error messages quote nested patterns using
|
|
410
|
+
// `q` to quoting them using `qp`. In order to tolerate both during
|
|
411
|
+
// this transition at reasonable cost, this golden error message
|
|
412
|
+
// pattern accepts anything in the position of the quoted nested
|
|
413
|
+
// pattern.
|
|
414
|
+
/^invalid value type for collection "map value no strings": "string not ok\?" - Must fail negated pattern: (.*)$/,
|
|
287
415
|
),
|
|
288
416
|
);
|
|
289
417
|
t.is(noStrings.get('nkey'), 47);
|
|
@@ -344,7 +472,14 @@ test('constrain set key shape', t => {
|
|
|
344
472
|
t.throws(
|
|
345
473
|
() => noStrings.add('foo?'),
|
|
346
474
|
m(
|
|
347
|
-
|
|
475
|
+
// TODO https://github.com/Agoric/agoric-sdk/issues/11605
|
|
476
|
+
// This is a golden error message test. We're currently in transition
|
|
477
|
+
// from having pattern error messages quote nested patterns using
|
|
478
|
+
// `q` to quoting them using `qp`. In order to tolerate both during
|
|
479
|
+
// this transition at reasonable cost, this golden error message
|
|
480
|
+
// pattern accepts anything in the position of the quoted nested
|
|
481
|
+
// pattern.
|
|
482
|
+
/^invalid key type for collection "no strings set": "foo\?" - Must fail negated pattern: (.*)$/,
|
|
348
483
|
),
|
|
349
484
|
);
|
|
350
485
|
t.truthy(noStrings.has(47));
|
|
@@ -389,6 +524,19 @@ test('map clear', t => {
|
|
|
389
524
|
t.is(testStore.getSize(), 0);
|
|
390
525
|
});
|
|
391
526
|
|
|
527
|
+
test('map clear with pattern', t => {
|
|
528
|
+
const testStore = makeScalarBigMapStore('cmap', { keyShape: M.any() });
|
|
529
|
+
testStore.init('a', 'ax');
|
|
530
|
+
testStore.init('b', 'bx');
|
|
531
|
+
testStore.init('c', 'cx');
|
|
532
|
+
console.log(`M is`, M);
|
|
533
|
+
testStore.clear(M.eq('c'));
|
|
534
|
+
t.true(testStore.has('a'));
|
|
535
|
+
t.true(testStore.has('b'));
|
|
536
|
+
t.false(testStore.has('c'));
|
|
537
|
+
t.is(testStore.getSize(), 2);
|
|
538
|
+
});
|
|
539
|
+
|
|
392
540
|
test('set clear', t => {
|
|
393
541
|
const testStore = makeScalarBigSetStore('cset', { keyShape: M.any() });
|
|
394
542
|
testStore.add('a');
|
|
@@ -401,11 +549,25 @@ test('set clear', t => {
|
|
|
401
549
|
t.is(testStore.getSize(), 0);
|
|
402
550
|
});
|
|
403
551
|
|
|
552
|
+
test('set clear with pattern', t => {
|
|
553
|
+
const testStore = makeScalarBigSetStore('cset', { keyShape: M.any() });
|
|
554
|
+
testStore.add('a');
|
|
555
|
+
testStore.add('b');
|
|
556
|
+
testStore.add('c');
|
|
557
|
+
testStore.clear(M.eq('c'));
|
|
558
|
+
t.true(testStore.has('a'));
|
|
559
|
+
t.true(testStore.has('b'));
|
|
560
|
+
t.false(testStore.has('c'));
|
|
561
|
+
t.is(testStore.getSize(), 2);
|
|
562
|
+
});
|
|
563
|
+
|
|
404
564
|
test('map fail on concurrent modification', t => {
|
|
405
565
|
const primeMap = makeScalarBigMapStore('fmap', {
|
|
406
566
|
keyShape: M.number(),
|
|
407
567
|
});
|
|
408
|
-
|
|
568
|
+
for (const [i, v] of primes.entries()) {
|
|
569
|
+
primeMap.init(v, `${v} is prime #${i + 1}`);
|
|
570
|
+
}
|
|
409
571
|
|
|
410
572
|
let iter = primeMap.keys()[Symbol.iterator]();
|
|
411
573
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
@@ -433,7 +595,9 @@ test('set fail on concurrent modification', t => {
|
|
|
433
595
|
const primeSet = makeScalarBigSetStore('fset', {
|
|
434
596
|
keyShape: M.number(),
|
|
435
597
|
});
|
|
436
|
-
|
|
598
|
+
for (const v of primes) {
|
|
599
|
+
primeSet.add(v);
|
|
600
|
+
}
|
|
437
601
|
|
|
438
602
|
let iter = primeSet.keys()[Symbol.iterator]();
|
|
439
603
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
@@ -461,7 +625,9 @@ test('map ok with concurrent deletion', t => {
|
|
|
461
625
|
const primeMap = makeScalarBigMapStore('fmap', {
|
|
462
626
|
keyShape: M.number(),
|
|
463
627
|
});
|
|
464
|
-
|
|
628
|
+
for (const [i, v] of primes.entries()) {
|
|
629
|
+
primeMap.init(v, `${v} is prime #${i + 1}`);
|
|
630
|
+
}
|
|
465
631
|
const iter = primeMap.keys()[Symbol.iterator]();
|
|
466
632
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
467
633
|
primeMap.delete(3);
|
|
@@ -476,7 +642,9 @@ test('set ok with concurrent deletion', t => {
|
|
|
476
642
|
const primeSet = makeScalarBigSetStore('fset', {
|
|
477
643
|
keyShape: M.number(),
|
|
478
644
|
});
|
|
479
|
-
|
|
645
|
+
for (const v of primes) {
|
|
646
|
+
primeSet.add(v);
|
|
647
|
+
}
|
|
480
648
|
|
|
481
649
|
const iter = primeSet.keys()[Symbol.iterator]();
|
|
482
650
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
@@ -766,13 +934,6 @@ test('set queries', t => {
|
|
|
766
934
|
symbolKrusty,
|
|
767
935
|
undefined,
|
|
768
936
|
]);
|
|
769
|
-
|
|
770
|
-
// @ts-expect-error our BigSetStore has .entries, but not the SetStore type
|
|
771
|
-
t.deepEqual(Array.from(testStore.entries(M.number())), [
|
|
772
|
-
[-29, -29],
|
|
773
|
-
[3, 3],
|
|
774
|
-
[47, 47],
|
|
775
|
-
]);
|
|
776
937
|
});
|
|
777
938
|
|
|
778
939
|
test('remotable sort order', t => {
|
|
@@ -798,7 +959,9 @@ test('complex map queries', t => {
|
|
|
798
959
|
const primeStore = makeScalarBigMapStore('prime map', {
|
|
799
960
|
keyShape: M.number(),
|
|
800
961
|
});
|
|
801
|
-
|
|
962
|
+
for (const [i, v] of primes.entries()) {
|
|
963
|
+
primeStore.init(v, `${v} is prime #${i + 1}`);
|
|
964
|
+
}
|
|
802
965
|
|
|
803
966
|
t.deepEqual(Array.from(primeStore.values()), [
|
|
804
967
|
'2 is prime #1',
|
|
@@ -973,7 +1136,9 @@ test('complex set queries', t => {
|
|
|
973
1136
|
const primeStore = makeScalarBigSetStore('prime set', {
|
|
974
1137
|
keyShape: M.number(),
|
|
975
1138
|
});
|
|
976
|
-
|
|
1139
|
+
for (const v of primes) {
|
|
1140
|
+
primeStore.add(v);
|
|
1141
|
+
}
|
|
977
1142
|
|
|
978
1143
|
t.deepEqual(
|
|
979
1144
|
Array.from(primeStore.values()),
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
2
|
import { Far } from '@endo/marshal';
|
|
3
|
+
import { kser } from '@agoric/kmarshal';
|
|
4
4
|
import { makeLiveSlots } from '../src/liveslots.js';
|
|
5
|
-
import { kser } from './kmarshal.js';
|
|
6
5
|
import { buildSyscall } from './liveslots-helpers.js';
|
|
7
6
|
import { makeStartVat } from './util.js';
|
|
8
7
|
import { makeMockGC } from './mock-gc.js';
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { Far } from '@endo/marshal';
|
|
3
|
+
import { kser, kslot } from '@agoric/kmarshal';
|
|
4
|
+
import { makeLiveSlots } from '../src/liveslots.js';
|
|
5
|
+
import { buildSyscall } from './liveslots-helpers.js';
|
|
6
|
+
import { makeStartVat, makeMessage, makeBringOutYourDead } from './util.js';
|
|
7
|
+
import { makeMockGC } from './mock-gc.js';
|
|
8
|
+
|
|
9
|
+
// Test for https://github.com/Agoric/agoric-sdk/issues/9939
|
|
10
|
+
|
|
11
|
+
test('weakset deletion vs retire', async t => {
|
|
12
|
+
const { syscall, log } = buildSyscall();
|
|
13
|
+
const gcTools = makeMockGC();
|
|
14
|
+
|
|
15
|
+
// #9939 was a bug in liveslots that caused a vat to emit
|
|
16
|
+
// syscall.retireImports despite not having done dropImports
|
|
17
|
+
// first. The setup is:
|
|
18
|
+
//
|
|
19
|
+
// * import a Presence (raising the RAM pillar)
|
|
20
|
+
// * store it in a virtual object (raising the vdata pillar)
|
|
21
|
+
// * use it as a key of a voAwareWeakMap or voAwareWeakSet
|
|
22
|
+
// * drop the Presence (dropping the RAM pillar)
|
|
23
|
+
// * do a BOYD
|
|
24
|
+
// * delete the voAwareWeakSet
|
|
25
|
+
// * do a BOYD
|
|
26
|
+
//
|
|
27
|
+
// When the voAwareWeakSet is collected, a finalizer callback named
|
|
28
|
+
// finalizeDroppedCollection is called, which clears the entries,
|
|
29
|
+
// and adds all its vref keys to possiblyRetiredSet. Later, during
|
|
30
|
+
// BOYD, a loop examines possiblyRetiredSet and adds qualified vrefs
|
|
31
|
+
// to importsToRetire, for the syscall.retireImports at the end.
|
|
32
|
+
//
|
|
33
|
+
// That qualification check was sufficient to prevent the retirement
|
|
34
|
+
// of vrefs that still have a RAM pillar, and also vrefs that were
|
|
35
|
+
// being dropped in this particular BOYD, but it was not sufficient
|
|
36
|
+
// to protect vrefs that still have a vdata pillar.
|
|
37
|
+
|
|
38
|
+
let myVOAwareWeakSet;
|
|
39
|
+
let myPresence;
|
|
40
|
+
function buildRootObject(vatPowers, _vatParameters, baggage) {
|
|
41
|
+
const { WeakSet } = vatPowers;
|
|
42
|
+
myVOAwareWeakSet = new WeakSet();
|
|
43
|
+
return Far('root', {
|
|
44
|
+
store: p => {
|
|
45
|
+
myPresence = p;
|
|
46
|
+
myVOAwareWeakSet.add(p);
|
|
47
|
+
baggage.init('presence', p);
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const makeNS = () => ({ buildRootObject });
|
|
53
|
+
const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS);
|
|
54
|
+
const { dispatch } = ls;
|
|
55
|
+
await dispatch(makeStartVat(kser()));
|
|
56
|
+
t.truthy(myVOAwareWeakSet);
|
|
57
|
+
|
|
58
|
+
await dispatch(makeMessage('o+0', 'store', [kslot('o-1')]));
|
|
59
|
+
t.truthy(myPresence);
|
|
60
|
+
|
|
61
|
+
log.length = 0;
|
|
62
|
+
gcTools.kill(myPresence);
|
|
63
|
+
gcTools.flushAllFRs();
|
|
64
|
+
await dispatch(makeBringOutYourDead());
|
|
65
|
+
|
|
66
|
+
log.length = 0;
|
|
67
|
+
gcTools.kill(myVOAwareWeakSet);
|
|
68
|
+
gcTools.flushAllFRs();
|
|
69
|
+
await dispatch(makeBringOutYourDead());
|
|
70
|
+
|
|
71
|
+
// The imported vref is still reachable by the 'baggage' durable
|
|
72
|
+
// store, so it must not be dropped or retired yet. The bug caused
|
|
73
|
+
// the vref to be retired without first doing a drop, which is a
|
|
74
|
+
// vat-fatal syscall error
|
|
75
|
+
const gcCalls = log.filter(
|
|
76
|
+
l => l.type === 'dropImports' || l.type === 'retireImports',
|
|
77
|
+
);
|
|
78
|
+
t.deepEqual(gcCalls, []);
|
|
79
|
+
log.length = 0;
|
|
80
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dummyMeterControl.d.ts","sourceRoot":"","sources":["dummyMeterControl.js"],"names":[],"mappings":"AAEA,gFAmDC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
2
|
|
|
4
3
|
import { Far } from '@endo/marshal';
|
|
5
4
|
import { makeFakeVirtualStuff } from '../tools/fakeVirtualSupport.js';
|
|
@@ -16,6 +15,7 @@ async function runDurabilityCheckTest(t, relaxDurabilityRules) {
|
|
|
16
15
|
|
|
17
16
|
const durableHolderKind = makeKindHandle('holder');
|
|
18
17
|
|
|
18
|
+
/** @param {any} held */
|
|
19
19
|
const initHolder = (held = null) => ({ held });
|
|
20
20
|
const holderBehavior = {
|
|
21
21
|
hold: ({ state }, value) => {
|
|
@@ -262,12 +262,12 @@ async function runDurabilityCheckTest(t, relaxDurabilityRules) {
|
|
|
262
262
|
passVal(() => virtualMap.init('non-scalar key', aNonScalarKey));
|
|
263
263
|
passVal(() => virtualMap.init('non-scalar non-key', aNonScalarNonKey));
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
failVal(() => durableMap.init('promise', aPassablePromise));
|
|
266
266
|
passVal(() => durableMap.init('error', aPassableError));
|
|
267
267
|
passVal(() => durableMap.init('non-scalar key', aNonScalarKey));
|
|
268
268
|
passVal(() => durableMap.init('non-scalar non-key', aNonScalarNonKey));
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
test('durability checks (strict)',
|
|
273
|
-
test('durability checks (relaxed)',
|
|
272
|
+
test('durability checks (strict)', runDurabilityCheckTest, false);
|
|
273
|
+
test('durability checks (relaxed)', runDurabilityCheckTest, true);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-gc.d.ts","sourceRoot":"","sources":["engine-gc.js"],"names":[],"mappings":";AAoBA,mCAAwB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { provideLazy as provide } from '@agoric/store';
|
|
2
|
+
|
|
3
|
+
// Partially duplicates @agoric/vat-data to avoid circular dependencies.
|
|
4
|
+
export const makeExoUtils = VatData => {
|
|
5
|
+
const { defineDurableKind, makeKindHandle, watchPromise } = VatData;
|
|
6
|
+
|
|
7
|
+
const provideKindHandle = (baggage, kindName) =>
|
|
8
|
+
provide(baggage, `${kindName}_kindHandle`, () => makeKindHandle(kindName));
|
|
9
|
+
|
|
10
|
+
const emptyRecord = harden({});
|
|
11
|
+
const initEmpty = () => emptyRecord;
|
|
12
|
+
|
|
13
|
+
const defineDurableExoClass = (
|
|
14
|
+
kindHandle,
|
|
15
|
+
interfaceGuard,
|
|
16
|
+
init,
|
|
17
|
+
methods,
|
|
18
|
+
options,
|
|
19
|
+
) =>
|
|
20
|
+
defineDurableKind(kindHandle, init, methods, {
|
|
21
|
+
...options,
|
|
22
|
+
thisfulMethods: true,
|
|
23
|
+
interfaceGuard,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const prepareExoClass = (
|
|
27
|
+
baggage,
|
|
28
|
+
kindName,
|
|
29
|
+
interfaceGuard,
|
|
30
|
+
init,
|
|
31
|
+
methods,
|
|
32
|
+
options = undefined,
|
|
33
|
+
) =>
|
|
34
|
+
defineDurableExoClass(
|
|
35
|
+
provideKindHandle(baggage, kindName),
|
|
36
|
+
interfaceGuard,
|
|
37
|
+
init,
|
|
38
|
+
methods,
|
|
39
|
+
options,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const prepareExo = (
|
|
43
|
+
baggage,
|
|
44
|
+
kindName,
|
|
45
|
+
interfaceGuard,
|
|
46
|
+
methods,
|
|
47
|
+
options = undefined,
|
|
48
|
+
) => {
|
|
49
|
+
const makeSingleton = prepareExoClass(
|
|
50
|
+
baggage,
|
|
51
|
+
kindName,
|
|
52
|
+
interfaceGuard,
|
|
53
|
+
initEmpty,
|
|
54
|
+
methods,
|
|
55
|
+
options,
|
|
56
|
+
);
|
|
57
|
+
return provide(baggage, `the_${kindName}`, () => makeSingleton());
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
defineDurableKind,
|
|
62
|
+
makeKindHandle,
|
|
63
|
+
watchPromise,
|
|
64
|
+
|
|
65
|
+
provideKindHandle,
|
|
66
|
+
defineDurableExoClass,
|
|
67
|
+
prepareExoClass,
|
|
68
|
+
prepareExo,
|
|
69
|
+
};
|
|
70
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import '@endo/init/debug.js';
|
|
2
1
|
import test from 'ava';
|
|
3
2
|
import {
|
|
4
3
|
assessFacetiousness,
|
|
@@ -126,7 +125,7 @@ test('checkAndUpdateFacetiousness', t => {
|
|
|
126
125
|
t.deepEqual(cauf({}, barfoo), barfoo);
|
|
127
126
|
|
|
128
127
|
// a single Kind can only be redefined as another single
|
|
129
|
-
t.
|
|
128
|
+
t.is(cauf(desc(), undefined), undefined);
|
|
130
129
|
t.throws(() => cauf(desc(), foo), {
|
|
131
130
|
message: 'defineDurableKindMulti called for unfaceted KindHandle "tag"',
|
|
132
131
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc-and-finalize.d.ts","sourceRoot":"","sources":["gc-and-finalize.js"],"names":[],"mappings":"AAkEA,qEAwBC;AAwBD;YAbsD,OAAO;EAkB5D"}
|
package/test/gc-and-finalize.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* global setImmediate */
|
|
1
|
+
/* global setImmediate, FinalizationRegistry */
|
|
2
2
|
|
|
3
3
|
/* A note on our GC terminology:
|
|
4
4
|
*
|
|
@@ -89,3 +89,32 @@ export function makeGcAndFinalize(gcPower) {
|
|
|
89
89
|
await new Promise(setImmediate);
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
|
+
|
|
93
|
+
const fr = new FinalizationRegistry(({ promise, resolve }) => {
|
|
94
|
+
promise.result = true;
|
|
95
|
+
resolve(true);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const makeCollectedResultKit = () => {
|
|
99
|
+
/** @type {(val: true) => void} */
|
|
100
|
+
let resolve;
|
|
101
|
+
|
|
102
|
+
const promise = /** @type {Promise<true> & {result: boolean}} */ (
|
|
103
|
+
new Promise(r => {
|
|
104
|
+
resolve = r;
|
|
105
|
+
})
|
|
106
|
+
);
|
|
107
|
+
promise.result = false;
|
|
108
|
+
return {
|
|
109
|
+
promise,
|
|
110
|
+
// @ts-expect-error
|
|
111
|
+
resolve,
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export function watchCollected(target) {
|
|
116
|
+
const kit = makeCollectedResultKit();
|
|
117
|
+
fr.register(target, kit);
|
|
118
|
+
|
|
119
|
+
return kit.promise;
|
|
120
|
+
}
|