@agoric/swingset-liveslots 0.10.3-dev-eb7e9eb.0 → 0.10.3-u11.0

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/package.json +19 -18
  3. package/src/collectionManager.js +41 -112
  4. package/src/index.js +1 -2
  5. package/src/liveslots.js +73 -46
  6. package/src/virtualObjectManager.js +13 -22
  7. package/src/virtualReferences.js +0 -51
  8. package/test/liveslots-helpers.js +4 -4
  9. package/test/mock-gc.js +0 -1
  10. package/test/storeGC/test-lifecycle.js +0 -1
  11. package/test/test-collection-upgrade.js +1 -0
  12. package/test/test-collections.js +13 -103
  13. package/test/test-durabilityChecks.js +2 -2
  14. package/test/test-facetiousness.js +1 -1
  15. package/test/test-gc-sensitivity.js +0 -1
  16. package/test/test-handled-promises.js +5 -4
  17. package/test/test-initial-vrefs.js +1 -1
  18. package/test/test-liveslots-mock-gc.js +0 -1
  19. package/test/test-liveslots-real-gc.js +0 -1
  20. package/test/test-liveslots.js +12 -12
  21. package/test/test-vpid-liveslots.js +1 -1
  22. package/test/util.js +1 -1
  23. package/test/virtual-objects/test-cease-recognition.js +1 -2
  24. package/test/virtual-objects/test-cross-facet.js +1 -1
  25. package/test/virtual-objects/test-empty-data.js +1 -1
  26. package/test/virtual-objects/test-facets.js +1 -1
  27. package/test/virtual-objects/test-kind-changes.js +0 -1
  28. package/test/virtual-objects/test-reachable-vrefs.js +1 -2
  29. package/test/virtual-objects/test-rep-tostring.js +2 -2
  30. package/test/virtual-objects/test-retain-remotable.js +0 -1
  31. package/test/virtual-objects/test-state-shape.js +0 -1
  32. package/test/virtual-objects/test-virtualObjectGC.js +0 -1
  33. package/test/virtual-objects/test-virtualObjectManager.js +0 -5
  34. package/test/virtual-objects/test-vo-real-gc.js +0 -1
  35. package/test/virtual-objects/test-weakcollections-vref-handling.js +1 -1
  36. package/src/vatDataTypes.d.ts +0 -206
  37. package/src/vatDataTypes.js +0 -2
  38. package/tools/fakeCollectionManager.js +0 -44
  39. package/tools/fakeVirtualObjectManager.js +0 -60
  40. package/tools/fakeVirtualSupport.js +0 -375
  41. package/tools/prepare-test-env.js +0 -14
  42. package/tools/setup-vat-data.js +0 -54
  43. package/tools/vo-test-harness.js +0 -143
package/CHANGELOG.md ADDED
@@ -0,0 +1,61 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ### [0.10.3-u11.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/swingset-liveslots@0.10.2...@agoric/swingset-liveslots@0.10.3-u11.0) (2023-08-24)
7
+
8
+ **Note:** Version bump only for package @agoric/swingset-liveslots
9
+
10
+
11
+
12
+
13
+
14
+ ### [0.10.2](https://github.com/Agoric/agoric-sdk/compare/@agoric/swingset-liveslots@0.10.1...@agoric/swingset-liveslots@0.10.2) (2023-06-02)
15
+
16
+ **Note:** Version bump only for package @agoric/swingset-liveslots
17
+
18
+
19
+
20
+
21
+
22
+ ### [0.10.1](https://github.com/Agoric/agoric-sdk/compare/@agoric/swingset-liveslots@0.10.0...@agoric/swingset-liveslots@0.10.1) (2023-05-24)
23
+
24
+ **Note:** Version bump only for package @agoric/swingset-liveslots
25
+
26
+
27
+
28
+
29
+
30
+ ## 0.10.0 (2023-05-19)
31
+
32
+
33
+ ### Features
34
+
35
+ * better diagnostic for failed reanimate ([c0c9c94](https://github.com/Agoric/agoric-sdk/commit/c0c9c9433648d520aa2bcdbadbbfe877831567c7)), closes [Error#1](https://github.com/Agoric/Error/issues/1)
36
+ * **swingset-liveslots:** label virtual instances ([4191eb6](https://github.com/Agoric/agoric-sdk/commit/4191eb62d0e64048c3c715e5f71a53a747267350))
37
+ * add APIs for tracking/debugging undesired object retention (aka "leaks") ([0a7221b](https://github.com/Agoric/agoric-sdk/commit/0a7221b3c04f3b2894c30346fa2ea6fb0130c046)), closes [#7318](https://github.com/Agoric/agoric-sdk/issues/7318)
38
+ * move liveslots and specific tests to a new package ([0921a89](https://github.com/Agoric/agoric-sdk/commit/0921a8903b72cfefdf05a5906bcfb826cac1cc2f)), closes [#6596](https://github.com/Agoric/agoric-sdk/issues/6596)
39
+
40
+
41
+ ### Bug Fixes
42
+
43
+ * **liveslots:** allow new Kind upgrade to add new facets ([6bc6694](https://github.com/Agoric/agoric-sdk/commit/6bc6694968e6d2f529e7c91ec1efb11fdff2e2d3)), closes [#7437](https://github.com/Agoric/agoric-sdk/issues/7437)
44
+ * **liveslots:** retain WeakRefs to voAware collections ([3935723](https://github.com/Agoric/agoric-sdk/commit/393572396781afd17691e1366abeba696228a24e)), closes [#7371](https://github.com/Agoric/agoric-sdk/issues/7371)
45
+ * **swingset-liveslots:** prevent VOM infinite loop if `globalThis.WeakSet` etc are replaced ([d7b35e2](https://github.com/Agoric/agoric-sdk/commit/d7b35e28715a715ef510f2717e0040fa017caab4))
46
+ * adding dup entries to virtual sets is OK ([c81d367](https://github.com/Agoric/agoric-sdk/commit/c81d3677d8085eb4debe5baa416816ff94d582cf)), closes [#7234](https://github.com/Agoric/agoric-sdk/issues/7234)
47
+ * code updates for new marshal ([292f971](https://github.com/Agoric/agoric-sdk/commit/292f971769db69e61782f96638c2f687c3f95ac2))
48
+ * **SwingSet:** Don't send stopVat during upgrade ([5cc47d2](https://github.com/Agoric/agoric-sdk/commit/5cc47d2d8892690f8c1653630b41dd64cc42d73b)), closes [#6650](https://github.com/Agoric/agoric-sdk/issues/6650)
49
+ * **types:** return value of deleter ([457f576](https://github.com/Agoric/agoric-sdk/commit/457f5765b9fc0a693e6eb5e6644ddf4af3b791db))
50
+ * move many type definitions from swingset to liveslots ([727143d](https://github.com/Agoric/agoric-sdk/commit/727143d5562498e2e3013c34304f229b4dd11da5))
51
+ * move rejectAllPromises from stopVat to kernels-side upgradeVat ([d79623f](https://github.com/Agoric/agoric-sdk/commit/d79623f3fb3b87653dba1c71eb1153711c9d962c)), closes [#6694](https://github.com/Agoric/agoric-sdk/issues/6694)
52
+ * Move upgrade-time abandonExports responsibility into the kernel ([66ac657](https://github.com/Agoric/agoric-sdk/commit/66ac657d51d3d1be61ee4a6e9a621a664086ee57)), closes [#6696](https://github.com/Agoric/agoric-sdk/issues/6696)
53
+ * only the exo api change ([5cf3bf1](https://github.com/Agoric/agoric-sdk/commit/5cf3bf10a71dd02094365a66e87032e5d17d004f))
54
+ * **liveslots:** use Map for vrefStatus, not object ([1456e2a](https://github.com/Agoric/agoric-sdk/commit/1456e2ae006bb1c702383cedda5e5c407968840e))
55
+ * **swingset:** move a bunch of types from swingset to swingset-liveslots ([14f9bb0](https://github.com/Agoric/agoric-sdk/commit/14f9bb00c82c085dc647f23b6c90b26e6a0a6dfd))
56
+ * **swingset-liveslots:** Move promise rejection responsibility into the kernel ([dd29ff3](https://github.com/Agoric/agoric-sdk/commit/dd29ff35c5dc72efbbf7087849182aa7f04b2bb1)), closes [#6694](https://github.com/Agoric/agoric-sdk/issues/6694)
57
+ * add 'v'/'d' virtual/durable annotations to vrefs ([b859e92](https://github.com/Agoric/agoric-sdk/commit/b859e92fe041415d6e34250f672a10ad927aa33e)), closes [#6695](https://github.com/Agoric/agoric-sdk/issues/6695)
58
+ * update description of "FINALIZED" state ([809f366](https://github.com/Agoric/agoric-sdk/commit/809f3660c083467e76deb1487015cb24205a801d))
59
+ * without assertKeyPattern ([#7035](https://github.com/Agoric/agoric-sdk/issues/7035)) ([c9fcd7f](https://github.com/Agoric/agoric-sdk/commit/c9fcd7f82757732435cd96f3377e4fbfb6586ce7))
60
+ * **swingset-liveslots:** copy helper files to new liveslots package ([be7229f](https://github.com/Agoric/agoric-sdk/commit/be7229f7217c1ecc523069a57945a372f4a1e00e))
61
+ * **swingset-liveslots:** update imports of helper files ([0b4b38a](https://github.com/Agoric/agoric-sdk/commit/0b4b38a1f9efbb3e1e860172b0b802548d18ae2e))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/swingset-liveslots",
3
- "version": "0.10.3-dev-eb7e9eb.0+eb7e9eb",
3
+ "version": "0.10.3-u11.0",
4
4
  "description": "SwingSet ocap support layer",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -13,31 +13,32 @@
13
13
  "test:xs": "exit 0",
14
14
  "lint-fix": "yarn lint:eslint --fix",
15
15
  "lint": "run-s --continue-on-error lint:*",
16
- "lint:types": "tsc",
16
+ "lint:types": "tsc -p jsconfig.json",
17
17
  "lint:eslint": "eslint ."
18
18
  },
19
19
  "dependencies": {
20
- "@agoric/assert": "0.6.1-dev-eb7e9eb.0+eb7e9eb",
21
- "@agoric/internal": "0.3.3-dev-eb7e9eb.0+eb7e9eb",
22
- "@agoric/store": "0.9.3-dev-eb7e9eb.0+eb7e9eb",
23
- "@endo/eventual-send": "^0.17.3",
24
- "@endo/exo": "^0.2.3",
25
- "@endo/far": "^0.2.19",
26
- "@endo/init": "^0.5.57",
27
- "@endo/marshal": "^0.8.6",
28
- "@endo/nat": "^4.1.28",
29
- "@endo/pass-style": "^0.1.4",
30
- "@endo/patterns": "^0.2.3",
31
- "@endo/promise-kit": "^0.2.57"
20
+ "@agoric/assert": "^0.6.0",
21
+ "@agoric/internal": "^0.3.3-u11.0",
22
+ "@agoric/store": "^0.9.3-u11.0",
23
+ "@agoric/vat-data": "^0.5.3-u11.0",
24
+ "@endo/eventual-send": "^0.17.2",
25
+ "@endo/exo": "^0.2.2",
26
+ "@endo/init": "^0.5.56",
27
+ "@endo/marshal": "^0.8.5",
28
+ "@endo/nat": "^4.1.27",
29
+ "@endo/pass-style": "^0.1.3",
30
+ "@endo/patterns": "^0.2.2",
31
+ "@endo/promise-kit": "^0.2.56"
32
32
  },
33
- "devDependencies": {
34
- "ava": "^5.3.0"
33
+ "peerDependencies": {
34
+ "@endo/far": "^0.2.18",
35
+ "@endo/ses-ava": "^0.2.40",
36
+ "ava": "^5.2.0"
35
37
  },
36
38
  "files": [
37
39
  "src/**/*.js",
38
40
  "src/**/*.d.ts",
39
41
  "test/**/*.js",
40
- "tools",
41
42
  "exported.js"
42
43
  ],
43
44
  "repository": {
@@ -60,5 +61,5 @@
60
61
  "publishConfig": {
61
62
  "access": "public"
62
63
  },
63
- "gitHead": "eb7e9ebe52e78052e5ded601b6658896d257cab4"
64
+ "gitHead": "92b6cd72484079b0349d8ccfa4510aeb820e8d67"
64
65
  }
@@ -15,10 +15,7 @@ import {
15
15
  makeCopySet,
16
16
  makeCopyMap,
17
17
  getRankCover,
18
- getCopyMapEntries,
19
- getCopySetKeys,
20
18
  } from '@endo/patterns';
21
- import { isCopyMap, isCopySet } from '@agoric/store';
22
19
  import { makeBaseRef, parseVatSlot } from './parseVatSlots.js';
23
20
  import {
24
21
  enumerateKeysStartEnd,
@@ -380,11 +377,11 @@ export function makeCollectionManager(
380
377
  currentGenerationNumber += 1;
381
378
  assertAcceptableSyscallCapdataSize([serializedValue]);
382
379
  if (durable) {
383
- for (const [slotIndex, vref] of serializedValue.slots.entries()) {
380
+ serializedValue.slots.forEach((vref, slotIndex) => {
384
381
  if (!vrm.isDurable(vref)) {
385
382
  throwNotDurable(value, slotIndex, serializedValue);
386
383
  }
387
- }
384
+ });
388
385
  }
389
386
  if (passStyleOf(key) === 'remotable') {
390
387
  /** @type {string} */
@@ -400,9 +397,7 @@ export function makeCollectionManager(
400
397
  vrm.addReachableVref(vref);
401
398
  }
402
399
  }
403
- for (const vref of serializedValue.slots) {
404
- vrm.addReachableVref(vref);
405
- }
400
+ serializedValue.slots.forEach(vrm.addReachableVref);
406
401
  syscall.vatstoreSet(keyToDBKey(key), JSON.stringify(serializedValue));
407
402
  updateEntryCount(1);
408
403
  };
@@ -421,11 +416,11 @@ export function makeCollectionManager(
421
416
  const after = serializeValue(harden(value));
422
417
  assertAcceptableSyscallCapdataSize([after]);
423
418
  if (durable) {
424
- for (const [i, vref] of after.slots.entries()) {
419
+ after.slots.forEach((vref, i) => {
425
420
  if (!vrm.isDurable(vref)) {
426
421
  throwNotDurable(value, i, after);
427
422
  }
428
- }
423
+ });
429
424
  }
430
425
  const dbKey = keyToDBKey(key);
431
426
  const rawBefore = syscall.vatstoreGet(dbKey);
@@ -629,36 +624,6 @@ export function makeCollectionManager(
629
624
  const snapshotMap = (keyPatt, valuePatt) =>
630
625
  makeCopyMap(entries(keyPatt, valuePatt));
631
626
 
632
- const addAllToSet = elems => {
633
- if (typeof elems[Symbol.iterator] !== 'function') {
634
- if (Object.isFrozen(elems) && isCopySet(elems)) {
635
- elems = getCopySetKeys(elems);
636
- } else {
637
- Fail`provided data source is not iterable: ${elems}`;
638
- }
639
- }
640
- for (const elem of elems) {
641
- addToSet(elem);
642
- }
643
- };
644
-
645
- const addAllToMap = mapEntries => {
646
- if (typeof mapEntries[Symbol.iterator] !== 'function') {
647
- if (Object.isFrozen(mapEntries) && isCopyMap(mapEntries)) {
648
- mapEntries = getCopyMapEntries(mapEntries);
649
- } else {
650
- Fail`provided data source is not iterable: ${mapEntries}`;
651
- }
652
- }
653
- for (const [key, value] of mapEntries) {
654
- if (has(key)) {
655
- set(key, value);
656
- } else {
657
- doInit(key, value, true);
658
- }
659
- }
660
- };
661
-
662
627
  return {
663
628
  has,
664
629
  get,
@@ -670,8 +635,6 @@ export function makeCollectionManager(
670
635
  keys,
671
636
  values,
672
637
  entries,
673
- addAllToSet,
674
- addAllToMap,
675
638
  snapshotSet,
676
639
  snapshotMap,
677
640
  sizeInternal,
@@ -684,23 +647,12 @@ export function makeCollectionManager(
684
647
  const hasWeakKeys = storeKindInfo[kindName].hasWeakKeys;
685
648
  const raw = summonCollectionInternal(initial, collectionID, kindName);
686
649
 
687
- const {
688
- has,
689
- get,
690
- init,
691
- addToSet,
692
- addAllToMap,
693
- addAllToSet,
694
- set,
695
- delete: del,
696
- } = raw;
650
+ const { has, get, init, addToSet, set, delete: del } = raw;
697
651
  const weakMethods = {
698
652
  has,
699
653
  get,
700
654
  init,
701
655
  addToSet,
702
- addAllToSet,
703
- addAllToMap,
704
656
  set,
705
657
  delete: del,
706
658
  };
@@ -795,15 +747,13 @@ export function makeCollectionManager(
795
747
  }
796
748
  const schemataCapData = serialize(harden(schemata));
797
749
  if (isDurable) {
798
- for (const [slotIndex, vref] of schemataCapData.slots.entries()) {
750
+ schemataCapData.slots.forEach((vref, slotIndex) => {
799
751
  if (!vrm.isDurable(vref)) {
800
752
  throwNotDurable(vref, slotIndex, schemataCapData);
801
753
  }
802
- }
803
- }
804
- for (const vref of schemataCapData.slots) {
805
- vrm.addReachableVref(vref);
754
+ });
806
755
  }
756
+ schemataCapData.slots.forEach(vrm.addReachableVref);
807
757
 
808
758
  schemaCache.set(
809
759
  collectionID,
@@ -814,48 +764,12 @@ export function makeCollectionManager(
814
764
  }
815
765
 
816
766
  function collectionToMapStore(collection) {
817
- const {
818
- has,
819
- get,
820
- init,
821
- set,
822
- delete: del,
823
- addAllToMap,
824
- keys,
825
- values,
826
- entries,
827
- snapshotMap,
828
- getSize,
829
- clear,
830
- } = collection;
831
- const mapStore = {
832
- has,
833
- get,
834
- init,
835
- set,
836
- delete: del,
837
- addAll: addAllToMap,
838
- keys,
839
- values,
840
- entries,
841
- snapshot: snapshotMap,
842
- getSize,
843
- clear,
844
- };
845
- return Far('mapStore', mapStore);
767
+ const { snapshotSet: _, snapshotMap, ...rest } = collection;
768
+ return Far('mapStore', { snapshot: snapshotMap, ...rest });
846
769
  }
847
770
 
848
771
  function collectionToWeakMapStore(collection) {
849
- const { has, get, init, set, delete: del, addAllToMap } = collection;
850
- const weakMapStore = {
851
- has,
852
- get,
853
- init,
854
- set,
855
- delete: del,
856
- addAll: addAllToMap,
857
- };
858
- return Far('weakMapStore', weakMapStore);
772
+ return Far('weakMapStore', collection);
859
773
  }
860
774
 
861
775
  function collectionToSetStore(collection) {
@@ -863,35 +777,50 @@ export function makeCollectionManager(
863
777
  has,
864
778
  addToSet,
865
779
  delete: del,
866
- addAllToSet,
867
780
  keys,
868
- snapshotSet,
869
781
  getSize,
782
+ snapshotSet,
870
783
  clear,
871
784
  } = collection;
785
+ function* entries(patt) {
786
+ for (const k of keys(patt)) {
787
+ yield [k, k];
788
+ }
789
+ }
790
+ function addAll(elems) {
791
+ for (const elem of elems) {
792
+ addToSet(elem, null);
793
+ }
794
+ }
872
795
 
873
796
  const setStore = {
874
797
  has,
875
798
  add: addToSet,
799
+ addAll,
876
800
  delete: del,
877
- addAll: addAllToSet,
878
801
  keys: patt => keys(patt),
879
802
  values: patt => keys(patt),
880
- snapshot: snapshotSet,
803
+ entries,
881
804
  getSize: patt => getSize(patt),
805
+ snapshot: snapshotSet,
882
806
  clear,
883
807
  };
884
808
  return Far('setStore', setStore);
885
809
  }
886
810
 
887
811
  function collectionToWeakSetStore(collection) {
888
- const { has, addToSet, delete: del, addAllToSet } = collection;
812
+ const { has, addToSet, delete: del } = collection;
813
+ function addAll(elems) {
814
+ for (const elem of elems) {
815
+ addToSet(elem);
816
+ }
817
+ }
889
818
 
890
819
  const weakSetStore = {
891
820
  has,
892
821
  add: addToSet,
822
+ addAll,
893
823
  delete: del,
894
- addAll: addAllToSet,
895
824
  };
896
825
  return Far('weakSetStore', weakSetStore);
897
826
  }
@@ -900,7 +829,7 @@ export function makeCollectionManager(
900
829
  * Produce a big map.
901
830
  *
902
831
  * @template K,V
903
- * @param {string} [label] - diagnostic label for the store
832
+ * @param {string} [label='map'] - diagnostic label for the store
904
833
  * @param {StoreOptions} [options]
905
834
  * @returns {MapStore<K,V>}
906
835
  */
@@ -944,7 +873,7 @@ export function makeCollectionManager(
944
873
  * Produce a weak big map.
945
874
  *
946
875
  * @template K,V
947
- * @param {string} [label] - diagnostic label for the store
876
+ * @param {string} [label='weakMap'] - diagnostic label for the store
948
877
  * @param {StoreOptions} [options]
949
878
  * @returns {WeakMapStore<K,V>}
950
879
  */
@@ -973,7 +902,7 @@ export function makeCollectionManager(
973
902
  * Produce a big set.
974
903
  *
975
904
  * @template K
976
- * @param {string} [label] - diagnostic label for the store
905
+ * @param {string} [label='set'] - diagnostic label for the store
977
906
  * @param {StoreOptions} [options]
978
907
  * @returns {SetStore<K>}
979
908
  */
@@ -1000,7 +929,7 @@ export function makeCollectionManager(
1000
929
  * Produce a weak big set.
1001
930
  *
1002
931
  * @template K
1003
- * @param {string} [label] - diagnostic label for the store
932
+ * @param {string} [label='weakSet'] - diagnostic label for the store
1004
933
  * @param {StoreOptions} [options]
1005
934
  * @returns {WeakSetStore<K>}
1006
935
  */
@@ -1077,7 +1006,7 @@ export function makeCollectionManager(
1077
1006
  * remotables.
1078
1007
  *
1079
1008
  * @template K,V
1080
- * @param {string} [label] - diagnostic label for the store
1009
+ * @param {string} [label='map'] - diagnostic label for the store
1081
1010
  * @param {StoreOptions} [options]
1082
1011
  * @returns {MapStore<K,V>}
1083
1012
  */
@@ -1089,7 +1018,7 @@ export function makeCollectionManager(
1089
1018
  * primitives, or remotables.
1090
1019
  *
1091
1020
  * @template K,V
1092
- * @param {string} [label] - diagnostic label for the store
1021
+ * @param {string} [label='weakMap'] - diagnostic label for the store
1093
1022
  * @param {StoreOptions} [options]
1094
1023
  * @returns {WeakMapStore<K,V>}
1095
1024
  */
@@ -1101,7 +1030,7 @@ export function makeCollectionManager(
1101
1030
  * remotables.
1102
1031
  *
1103
1032
  * @template K
1104
- * @param {string} [label] - diagnostic label for the store
1033
+ * @param {string} [label='set'] - diagnostic label for the store
1105
1034
  * @param {StoreOptions} [options]
1106
1035
  * @returns {SetStore<K>}
1107
1036
  */
@@ -1113,7 +1042,7 @@ export function makeCollectionManager(
1113
1042
  * primitives, or remotables.
1114
1043
  *
1115
1044
  * @template K
1116
- * @param {string} [label] - diagnostic label for the store
1045
+ * @param {string} [label='weakSet'] - diagnostic label for the store
1117
1046
  * @param {StoreOptions} [options]
1118
1047
  * @returns {WeakSetStore<K>}
1119
1048
  */
package/src/index.js CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint-disable import/export -- types files have no named runtime exports */
2
1
  export { makeLiveSlots, makeMarshaller } from './liveslots.js';
3
2
 
4
3
  export {
@@ -9,5 +8,5 @@ export {
9
8
  insistVatSyscallResult,
10
9
  } from './message.js';
11
10
 
11
+ // eslint-disable-next-line import/export -- no named exports
12
12
  export * from './types.js';
13
- export * from './vatDataTypes.js';
package/src/liveslots.js CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint @typescript-eslint/no-floating-promises: "warn" */
2
1
  import {
3
2
  Remotable,
4
3
  passStyleOf,
@@ -252,10 +251,13 @@ function build(
252
251
  const importsToRetire = new Set();
253
252
  const exportsToRetire = new Set();
254
253
  let doMore;
255
- await null;
256
254
  do {
257
255
  doMore = false;
258
256
 
257
+ // Yes, we know this is an await inside a loop. Too bad. (Also, it's a
258
+ // `do {} while` loop, which means there's no conditional bypass of the
259
+ // await.)
260
+ // eslint-disable-next-line no-await-in-loop, @jessie.js/no-nested-await
259
261
  await gcTools.gcAndFinalize();
260
262
 
261
263
  // possiblyDeadSet contains a baseref for everything (Presences,
@@ -498,6 +500,54 @@ function build(
498
500
  return Remotable(iface);
499
501
  }
500
502
 
503
+ /**
504
+ * Counters to track the next number for various categories of allocation.
505
+ * `exportID` starts at 1 because 'o+0' is always automatically
506
+ * pre-assigned to the root object.
507
+ * `promiseID` starts at 5 as a very minor aid to debugging: when puzzling
508
+ * over trace logs and the like, it helps for the numbers in various species
509
+ * of IDs that are jumbled together to be a little out of sync and thus a
510
+ * little less similar to each other.
511
+ */
512
+ const initialIDCounters = { exportID: 1, collectionID: 1, promiseID: 5 };
513
+ /** @type {Record<string, number>} */
514
+ let idCounters;
515
+ let idCountersAreDirty = false;
516
+
517
+ function initializeIDCounters() {
518
+ if (!idCounters) {
519
+ // the saved value might be missing, or from an older liveslots
520
+ // (with fewer counters), so merge it with our initial values
521
+ const saved = JSON.parse(syscall.vatstoreGet('idCounters') || '{}');
522
+ idCounters = { ...initialIDCounters, ...saved };
523
+ idCountersAreDirty = true;
524
+ }
525
+ }
526
+
527
+ function allocateNextID(name) {
528
+ if (!idCounters) {
529
+ // Normally `initializeIDCounters` would be called from startVat, but some
530
+ // tests bypass that so this is a backstop. Note that the invocation from
531
+ // startVat is there to make vatStore access patterns a bit more
532
+ // consistent from one vat to another, principally as a confusion
533
+ // reduction measure in service of debugging; it is not a correctness
534
+ // issue.
535
+ initializeIDCounters();
536
+ }
537
+ const result = idCounters[name];
538
+ result !== undefined || Fail`unknown idCounters[${name}]`;
539
+ idCounters[name] += 1;
540
+ idCountersAreDirty = true;
541
+ return result;
542
+ }
543
+
544
+ function flushIDCounters() {
545
+ if (idCountersAreDirty) {
546
+ syscall.vatstoreSet('idCounters', JSON.stringify(idCounters));
547
+ idCountersAreDirty = false;
548
+ }
549
+ }
550
+
501
551
  // TODO: fix awkward non-orthogonality: allocateExportID() returns a number,
502
552
  // allocatePromiseID() returns a slot, registerPromise() uses the slot from
503
553
  // allocatePromiseID(), exportPassByPresence() generates a slot itself using
@@ -506,18 +556,15 @@ function build(
506
556
  // use a slot from the corresponding allocateX
507
557
 
508
558
  function allocateExportID() {
509
- // eslint-disable-next-line no-use-before-define
510
- return vrm.allocateNextID('exportID');
559
+ return allocateNextID('exportID');
511
560
  }
512
561
 
513
562
  function allocateCollectionID() {
514
- // eslint-disable-next-line no-use-before-define
515
- return vrm.allocateNextID('collectionID');
563
+ return allocateNextID('collectionID');
516
564
  }
517
565
 
518
566
  function allocatePromiseID() {
519
- // eslint-disable-next-line no-use-before-define
520
- const promiseID = vrm.allocateNextID('promiseID');
567
+ const promiseID = allocateNextID('promiseID');
521
568
  return makeVatSlot('promise', true, promiseID);
522
569
  }
523
570
 
@@ -712,9 +759,9 @@ function build(
712
759
  Fail`registerValue(${baseRef} should not receive individual facets`;
713
760
  slotToVal.set(baseRef, new WeakRef(val));
714
761
  if (valIsCohort) {
715
- for (const [index, name] of vrm.getFacetNames(id).entries()) {
762
+ vrm.getFacetNames(id).forEach((name, index) => {
716
763
  valToSlot.set(val[name], `${baseRef}:${index}`);
717
- }
764
+ });
718
765
  } else {
719
766
  valToSlot.set(val, baseRef);
720
767
  }
@@ -936,20 +983,12 @@ function build(
936
983
  return null;
937
984
  }
938
985
  syscall.resolve(resolutions);
939
- for (const resolution of resolutions) {
940
- const [_xvpid, _isReject, resolutionCD] = resolution;
941
- for (const vref of resolutionCD.slots) {
942
- maybeNewVPIDs.add(vref);
943
- }
944
- }
945
- for (const resolution of resolutions) {
946
- const [xvpid] = resolution;
947
- maybeNewVPIDs.delete(xvpid);
948
- }
949
- }
950
- for (const newVPID of Array.from(maybeNewVPIDs).sort()) {
951
- maybeExportPromise(newVPID);
986
+ resolutions.forEach(([_xvpid, _isReject, resolutionCD]) => {
987
+ resolutionCD.slots.forEach(vref => maybeNewVPIDs.add(vref));
988
+ });
989
+ resolutions.forEach(([xvpid]) => maybeNewVPIDs.delete(xvpid));
952
990
  }
991
+ Array.from(maybeNewVPIDs).sort().forEach(maybeExportPromise);
953
992
 
954
993
  // ideally we'd wait until .then is called on p before subscribing, but
955
994
  // the current Promise API doesn't give us a way to discover this, so we
@@ -1151,21 +1190,13 @@ function build(
1151
1190
 
1152
1191
  const maybeNewVPIDs = new Set();
1153
1192
  // if we mention a vpid, we might need to track it
1154
- for (const resolution of resolutions) {
1155
- const [_xvpid, _isReject, resolutionCD] = resolution;
1156
- for (const vref of resolutionCD.slots) {
1157
- maybeNewVPIDs.add(vref);
1158
- }
1159
- }
1193
+ resolutions.forEach(([_xvpid, _isReject, resolutionCD]) => {
1194
+ resolutionCD.slots.forEach(vref => maybeNewVPIDs.add(vref));
1195
+ });
1160
1196
  // but not if we just resolved it (including the primary)
1161
- for (const resolution of resolutions) {
1162
- const [xvpid] = resolution;
1163
- maybeNewVPIDs.delete(xvpid);
1164
- }
1197
+ resolutions.forEach(([xvpid]) => maybeNewVPIDs.delete(xvpid));
1165
1198
  // track everything that's left
1166
- for (const newVPID of Array.from(maybeNewVPIDs).sort()) {
1167
- maybeExportPromise(newVPID);
1168
- }
1199
+ Array.from(maybeNewVPIDs).sort().forEach(maybeExportPromise);
1169
1200
 
1170
1201
  // only the primary can possibly be newly resolved
1171
1202
  unregisterUnreferencedVPID(vpid);
@@ -1223,11 +1254,11 @@ function build(
1223
1254
  // 'imports' is an exclusively-owned Set that holds all new
1224
1255
  // promise vpids, both resolved and unresolved
1225
1256
  const imports = finishCollectingPromiseImports();
1226
- for (const vpid of retiredVPIDs) {
1257
+ retiredVPIDs.forEach(vpid => {
1227
1258
  unregisterUnreferencedVPID(vpid); // unregisters if not in vdata
1228
1259
  importedVPIDs.delete(vpid);
1229
1260
  imports.delete(vpid); // resolved, so don't subscribe()
1230
- }
1261
+ });
1231
1262
  for (const vpid of Array.from(imports).sort()) {
1232
1263
  syscall.subscribe(vpid);
1233
1264
  }
@@ -1267,18 +1298,14 @@ function build(
1267
1298
 
1268
1299
  function retireExports(vrefs) {
1269
1300
  assert(Array.isArray(vrefs));
1270
- for (const vref of vrefs) {
1271
- retireOneExport(vref);
1272
- }
1301
+ vrefs.forEach(retireOneExport);
1273
1302
  }
1274
1303
 
1275
1304
  function retireImports(vrefs) {
1276
1305
  assert(Array.isArray(vrefs));
1277
1306
  vrefs.map(vref => insistVatType('object', vref));
1278
1307
  vrefs.map(vref => assert(!parseVatSlot(vref).allocatedByVat));
1279
- for (const vref of vrefs) {
1280
- vrm.ceaseRecognition(vref);
1281
- }
1308
+ vrefs.forEach(vrm.ceaseRecognition);
1282
1309
  }
1283
1310
 
1284
1311
  // TODO: when we add notifyForward, guard against cycles
@@ -1423,7 +1450,7 @@ function build(
1423
1450
  }
1424
1451
  harden(vpow);
1425
1452
 
1426
- vrm.initializeIDCounters();
1453
+ initializeIDCounters();
1427
1454
  vom.initializeKindHandleKind();
1428
1455
  collectionManager.initializeStoreKindInfo();
1429
1456
 
@@ -1546,7 +1573,7 @@ function build(
1546
1573
  * dispatch has completed and user code has relinquished agency.
1547
1574
  */
1548
1575
  function afterDispatchActions() {
1549
- vrm.flushIDCounters();
1576
+ flushIDCounters();
1550
1577
  collectionManager.flushSchemaCache();
1551
1578
  vom.flushStateCache();
1552
1579
  }