@agoric/swingset-liveslots 0.10.3-dev-7cc5def.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 -45
  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-7cc5def.0+7cc5def",
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-7cc5def.0+7cc5def",
21
- "@agoric/internal": "0.3.3-dev-7cc5def.0+7cc5def",
22
- "@agoric/store": "0.9.3-dev-7cc5def.0+7cc5def",
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": "7cc5defcf5c6d126fe39c94be4953afd11105a5c"
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
@@ -251,10 +251,13 @@ function build(
251
251
  const importsToRetire = new Set();
252
252
  const exportsToRetire = new Set();
253
253
  let doMore;
254
- await null;
255
254
  do {
256
255
  doMore = false;
257
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
258
261
  await gcTools.gcAndFinalize();
259
262
 
260
263
  // possiblyDeadSet contains a baseref for everything (Presences,
@@ -497,6 +500,54 @@ function build(
497
500
  return Remotable(iface);
498
501
  }
499
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
+
500
551
  // TODO: fix awkward non-orthogonality: allocateExportID() returns a number,
501
552
  // allocatePromiseID() returns a slot, registerPromise() uses the slot from
502
553
  // allocatePromiseID(), exportPassByPresence() generates a slot itself using
@@ -505,18 +556,15 @@ function build(
505
556
  // use a slot from the corresponding allocateX
506
557
 
507
558
  function allocateExportID() {
508
- // eslint-disable-next-line no-use-before-define
509
- return vrm.allocateNextID('exportID');
559
+ return allocateNextID('exportID');
510
560
  }
511
561
 
512
562
  function allocateCollectionID() {
513
- // eslint-disable-next-line no-use-before-define
514
- return vrm.allocateNextID('collectionID');
563
+ return allocateNextID('collectionID');
515
564
  }
516
565
 
517
566
  function allocatePromiseID() {
518
- // eslint-disable-next-line no-use-before-define
519
- const promiseID = vrm.allocateNextID('promiseID');
567
+ const promiseID = allocateNextID('promiseID');
520
568
  return makeVatSlot('promise', true, promiseID);
521
569
  }
522
570
 
@@ -711,9 +759,9 @@ function build(
711
759
  Fail`registerValue(${baseRef} should not receive individual facets`;
712
760
  slotToVal.set(baseRef, new WeakRef(val));
713
761
  if (valIsCohort) {
714
- for (const [index, name] of vrm.getFacetNames(id).entries()) {
762
+ vrm.getFacetNames(id).forEach((name, index) => {
715
763
  valToSlot.set(val[name], `${baseRef}:${index}`);
716
- }
764
+ });
717
765
  } else {
718
766
  valToSlot.set(val, baseRef);
719
767
  }
@@ -935,20 +983,12 @@ function build(
935
983
  return null;
936
984
  }
937
985
  syscall.resolve(resolutions);
938
- for (const resolution of resolutions) {
939
- const [_xvpid, _isReject, resolutionCD] = resolution;
940
- for (const vref of resolutionCD.slots) {
941
- maybeNewVPIDs.add(vref);
942
- }
943
- }
944
- for (const resolution of resolutions) {
945
- const [xvpid] = resolution;
946
- maybeNewVPIDs.delete(xvpid);
947
- }
948
- }
949
- for (const newVPID of Array.from(maybeNewVPIDs).sort()) {
950
- maybeExportPromise(newVPID);
986
+ resolutions.forEach(([_xvpid, _isReject, resolutionCD]) => {
987
+ resolutionCD.slots.forEach(vref => maybeNewVPIDs.add(vref));
988
+ });
989
+ resolutions.forEach(([xvpid]) => maybeNewVPIDs.delete(xvpid));
951
990
  }
991
+ Array.from(maybeNewVPIDs).sort().forEach(maybeExportPromise);
952
992
 
953
993
  // ideally we'd wait until .then is called on p before subscribing, but
954
994
  // the current Promise API doesn't give us a way to discover this, so we
@@ -1150,21 +1190,13 @@ function build(
1150
1190
 
1151
1191
  const maybeNewVPIDs = new Set();
1152
1192
  // if we mention a vpid, we might need to track it
1153
- for (const resolution of resolutions) {
1154
- const [_xvpid, _isReject, resolutionCD] = resolution;
1155
- for (const vref of resolutionCD.slots) {
1156
- maybeNewVPIDs.add(vref);
1157
- }
1158
- }
1193
+ resolutions.forEach(([_xvpid, _isReject, resolutionCD]) => {
1194
+ resolutionCD.slots.forEach(vref => maybeNewVPIDs.add(vref));
1195
+ });
1159
1196
  // but not if we just resolved it (including the primary)
1160
- for (const resolution of resolutions) {
1161
- const [xvpid] = resolution;
1162
- maybeNewVPIDs.delete(xvpid);
1163
- }
1197
+ resolutions.forEach(([xvpid]) => maybeNewVPIDs.delete(xvpid));
1164
1198
  // track everything that's left
1165
- for (const newVPID of Array.from(maybeNewVPIDs).sort()) {
1166
- maybeExportPromise(newVPID);
1167
- }
1199
+ Array.from(maybeNewVPIDs).sort().forEach(maybeExportPromise);
1168
1200
 
1169
1201
  // only the primary can possibly be newly resolved
1170
1202
  unregisterUnreferencedVPID(vpid);
@@ -1222,11 +1254,11 @@ function build(
1222
1254
  // 'imports' is an exclusively-owned Set that holds all new
1223
1255
  // promise vpids, both resolved and unresolved
1224
1256
  const imports = finishCollectingPromiseImports();
1225
- for (const vpid of retiredVPIDs) {
1257
+ retiredVPIDs.forEach(vpid => {
1226
1258
  unregisterUnreferencedVPID(vpid); // unregisters if not in vdata
1227
1259
  importedVPIDs.delete(vpid);
1228
1260
  imports.delete(vpid); // resolved, so don't subscribe()
1229
- }
1261
+ });
1230
1262
  for (const vpid of Array.from(imports).sort()) {
1231
1263
  syscall.subscribe(vpid);
1232
1264
  }
@@ -1266,18 +1298,14 @@ function build(
1266
1298
 
1267
1299
  function retireExports(vrefs) {
1268
1300
  assert(Array.isArray(vrefs));
1269
- for (const vref of vrefs) {
1270
- retireOneExport(vref);
1271
- }
1301
+ vrefs.forEach(retireOneExport);
1272
1302
  }
1273
1303
 
1274
1304
  function retireImports(vrefs) {
1275
1305
  assert(Array.isArray(vrefs));
1276
1306
  vrefs.map(vref => insistVatType('object', vref));
1277
1307
  vrefs.map(vref => assert(!parseVatSlot(vref).allocatedByVat));
1278
- for (const vref of vrefs) {
1279
- vrm.ceaseRecognition(vref);
1280
- }
1308
+ vrefs.forEach(vrm.ceaseRecognition);
1281
1309
  }
1282
1310
 
1283
1311
  // TODO: when we add notifyForward, guard against cycles
@@ -1422,7 +1450,7 @@ function build(
1422
1450
  }
1423
1451
  harden(vpow);
1424
1452
 
1425
- vrm.initializeIDCounters();
1453
+ initializeIDCounters();
1426
1454
  vom.initializeKindHandleKind();
1427
1455
  collectionManager.initializeStoreKindInfo();
1428
1456
 
@@ -1545,7 +1573,7 @@ function build(
1545
1573
  * dispatch has completed and user code has relinquished agency.
1546
1574
  */
1547
1575
  function afterDispatchActions() {
1548
- vrm.flushIDCounters();
1576
+ flushIDCounters();
1549
1577
  collectionManager.flushSchemaCache();
1550
1578
  vom.flushStateCache();
1551
1579
  }