@agoric/swingset-liveslots 0.10.3-other-dev-1f26562.0 → 0.10.3-other-dev-3eb1a1d.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 (77) hide show
  1. package/README.md +2 -0
  2. package/package.json +27 -19
  3. package/src/boyd-gc.js +598 -0
  4. package/src/cache.js +3 -2
  5. package/src/capdata.js +1 -2
  6. package/src/collectionManager.js +219 -103
  7. package/src/facetiousness.js +1 -1
  8. package/src/index.js +4 -2
  9. package/src/liveslots.js +131 -301
  10. package/src/message.js +5 -5
  11. package/src/parseVatSlots.js +1 -1
  12. package/src/types-index.d.ts +4 -0
  13. package/src/types-index.js +2 -0
  14. package/src/types.js +8 -2
  15. package/src/vatstore-iterators.js +2 -0
  16. package/src/virtualObjectManager.js +185 -71
  17. package/src/virtualReferences.js +135 -26
  18. package/src/watchedPromises.js +67 -17
  19. package/test/{test-baggage.js → baggage.test.js} +1 -2
  20. package/test/{test-cache.js → cache.test.js} +0 -1
  21. package/test/clear-collection.test.js +586 -0
  22. package/test/{test-collection-schema-refcount.js → collection-schema-refcount.test.js} +1 -2
  23. package/test/{test-collection-upgrade.js → collection-upgrade.test.js} +1 -3
  24. package/test/{test-collections.js → collections.test.js} +158 -14
  25. package/test/{test-dropped-collection-weakrefs.js → dropped-collection-weakrefs.test.js} +1 -2
  26. package/test/dropped-weakset-9939.test.js +80 -0
  27. package/test/dummyMeterControl.js +1 -1
  28. package/test/{test-durabilityChecks.js → durabilityChecks.test.js} +4 -4
  29. package/test/exo-utils.js +70 -0
  30. package/test/{test-facetiousness.js → facetiousness.test.js} +1 -2
  31. package/test/gc-and-finalize.js +30 -1
  32. package/test/gc-before-finalizer.test.js +230 -0
  33. package/test/gc-helpers.js +2 -3
  34. package/test/{test-gc-sensitivity.js → gc-sensitivity.test.js} +2 -2
  35. package/test/handled-promises.test.js +506 -0
  36. package/test/{test-initial-vrefs.js → initial-vrefs.test.js} +2 -3
  37. package/test/liveslots-helpers.js +12 -7
  38. package/test/{test-liveslots-mock-gc.js → liveslots-mock-gc.test.js} +101 -2
  39. package/test/{test-liveslots-real-gc.js → liveslots-real-gc.test.js} +62 -37
  40. package/test/{test-liveslots.js → liveslots.test.js} +14 -15
  41. package/test/mock-gc.js +1 -0
  42. package/test/storeGC/{test-lifecycle.js → lifecycle.test.js} +2 -2
  43. package/test/storeGC/{test-refcount-management.js → refcount-management.test.js} +1 -2
  44. package/test/storeGC/{test-scalar-store-kind.js → scalar-store-kind.test.js} +0 -1
  45. package/test/storeGC/{test-weak-key.js → weak-key.test.js} +1 -2
  46. package/test/strict-test-env-upgrade.test.js +94 -0
  47. package/test/util.js +2 -2
  48. package/test/vat-environment.test.js +65 -0
  49. package/test/vat-util.js +2 -2
  50. package/test/virtual-objects/{test-cease-recognition.js → cease-recognition.test.js} +2 -2
  51. package/test/virtual-objects/{test-cross-facet.js → cross-facet.test.js} +5 -4
  52. package/test/virtual-objects/{test-empty-data.js → empty-data.test.js} +1 -2
  53. package/test/virtual-objects/{test-facets.js → facets.test.js} +1 -2
  54. package/test/virtual-objects/{test-kind-changes.js → kind-changes.test.js} +2 -2
  55. package/test/virtual-objects/{test-reachable-vrefs.js → reachable-vrefs.test.js} +2 -2
  56. package/test/virtual-objects/{test-rep-tostring.js → rep-tostring.test.js} +3 -5
  57. package/test/virtual-objects/{test-retain-remotable.js → retain-remotable.test.js} +25 -24
  58. package/test/virtual-objects/set-debug-label-instances.js +1 -1
  59. package/test/virtual-objects/{test-state-shape.js → state-shape.test.js} +2 -2
  60. package/test/virtual-objects/{test-virtualObjectGC.js → virtualObjectGC.test.js} +2 -2
  61. package/test/virtual-objects/{test-virtualObjectManager.js → virtualObjectManager.test.js} +126 -8
  62. package/test/virtual-objects/{test-vo-real-gc.js → vo-real-gc.test.js} +8 -8
  63. package/test/virtual-objects/{test-weakcollections-vref-handling.js → weakcollections-vref-handling.test.js} +1 -2
  64. package/test/{test-vo-test-harness.js → vo-test-harness.test.js} +0 -1
  65. package/test/{test-vpid-liveslots.js → vpid-liveslots.test.js} +105 -5
  66. package/test/waitUntilQuiescent.js +2 -1
  67. package/test/weakset-dropped-remotable.test.js +50 -0
  68. package/tools/fakeCollectionManager.js +44 -0
  69. package/tools/fakeVirtualObjectManager.js +62 -0
  70. package/tools/fakeVirtualSupport.js +389 -0
  71. package/tools/prepare-strict-test-env.js +124 -0
  72. package/tools/prepare-test-env.js +13 -0
  73. package/tools/setup-vat-data.js +96 -0
  74. package/tools/vo-test-harness.js +143 -0
  75. package/CHANGELOG.md +0 -61
  76. package/test/kmarshal.js +0 -79
  77. package/test/test-handled-promises.js +0 -360
@@ -1,12 +1,12 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
 
4
+ import { kser, kslot } from '@agoric/kmarshal';
4
5
  import {
5
6
  makeFakeVirtualObjectManager,
6
7
  makeFakeVirtualStuff,
7
8
  } from '../../tools/fakeVirtualSupport.js';
8
9
 
9
- import { kser, kslot } from '../kmarshal.js';
10
10
  import { vstr } from '../util.js';
11
11
 
12
12
  function initThing(label = 'thing', counter = 0) {
@@ -127,6 +127,7 @@ test('multifaceted virtual objects', t => {
127
127
 
128
128
  flushStateCache();
129
129
  t.deepEqual(log.splice(0), [
130
+ `get idCounters => undefined`,
130
131
  `get kindIDID => undefined`,
131
132
  `set kindIDID 1`,
132
133
  `set vom.vkind.2.descriptor {"kindID":"2","tag":"multithing"}`,
@@ -202,6 +203,7 @@ test('virtual object operations', t => {
202
203
  // t3-0: 'thing-3' 200 0
203
204
  const thing4 = makeThing('thing-4', 300); // [t4-0* t3-0* t2-0* t1-0*]
204
205
  // t4-0: 'thing-4' 300 0
206
+ t.is(log.shift(), `get idCounters => undefined`);
205
207
  t.is(log.shift(), `get kindIDID => undefined`);
206
208
  t.is(log.shift(), `set kindIDID 1`);
207
209
  t.is(log.shift(), `set vom.vkind.2.descriptor {"kindID":"2","tag":"thing"}`);
@@ -466,6 +468,7 @@ test('symbol named methods', t => {
466
468
  // t1-0: 'thing-1' 0 0
467
469
  const thing2 = makeThing('thing-2', 100); // [t1-0* t2-0*]
468
470
  // t2-0: 'thing-2' 100 0
471
+ t.is(log.shift(), `get idCounters => undefined`);
469
472
  t.is(log.shift(), `get kindIDID => undefined`);
470
473
  t.is(log.shift(), `set kindIDID 1`);
471
474
  t.is(
@@ -587,12 +590,12 @@ test('durable kind IDs can be reanimated', t => {
587
590
 
588
591
  // Store it in the store without having used it
589
592
  placeToPutIt.init('savedKindID', kindHandle);
590
- t.is(log.shift(), 'get vc.1.ssavedKindID => undefined');
593
+ t.is(log.shift(), 'get vc.4.ssavedKindID => undefined');
591
594
  t.is(log.shift(), `get vom.rc.${khid} => undefined`);
592
595
  t.is(log.shift(), `set vom.rc.${khid} 1`);
593
- t.is(log.shift(), `set vc.1.ssavedKindID ${vstr(kind)}`);
594
- t.is(log.shift(), 'get vc.1.|entryCount => 0');
595
- t.is(log.shift(), 'set vc.1.|entryCount 1');
596
+ t.is(log.shift(), `set vc.4.ssavedKindID ${vstr(kind)}`);
597
+ t.is(log.shift(), 'get vc.4.|entryCount => 0');
598
+ t.is(log.shift(), 'set vc.4.|entryCount 1');
596
599
  t.deepEqual(log, []);
597
600
 
598
601
  // Forget its Representative
@@ -606,7 +609,7 @@ test('durable kind IDs can be reanimated', t => {
606
609
 
607
610
  // Fetch it from the store, which should reanimate it
608
611
  const fetchedKindID = placeToPutIt.get('savedKindID');
609
- t.is(log.shift(), `get vc.1.ssavedKindID => ${vstr(kind)}`);
612
+ t.is(log.shift(), `get vc.4.ssavedKindID => ${vstr(kind)}`);
610
613
  t.is(
611
614
  log.shift(),
612
615
  'get vom.dkind.10.descriptor => {"kindID":"10","tag":"testkind"}',
@@ -646,6 +649,7 @@ test('virtual object gc', t => {
646
649
  },
647
650
  });
648
651
 
652
+ t.is(log.shift(), `get idCounters => undefined`);
649
653
  t.is(log.shift(), `get kindIDID => undefined`);
650
654
  t.is(log.shift(), `set kindIDID 1`);
651
655
  const skit = [
@@ -654,9 +658,23 @@ test('virtual object gc', t => {
654
658
  ];
655
659
  t.is(log.shift(), `get storeKindIDTable => undefined`);
656
660
  t.is(log.shift(), `set ${skit[0]} ${skit[1]}`);
661
+ t.is(log.shift(), 'set vc.1.|nextOrdinal 1');
662
+ t.is(log.shift(), 'set vc.1.|entryCount 0');
663
+ t.is(log.shift(), 'get watcherTableID => undefined');
664
+ t.is(log.shift(), 'set vc.2.|nextOrdinal 1');
665
+ t.is(log.shift(), 'set vc.2.|entryCount 0');
666
+ t.is(log.shift(), 'set watcherTableID o+d6/2');
667
+ t.is(log.shift(), 'get vom.rc.o+d6/2 => undefined');
668
+ t.is(log.shift(), 'set vom.rc.o+d6/2 1');
669
+ t.is(log.shift(), 'get watchedPromiseTableID => undefined');
670
+ t.is(log.shift(), 'set vc.3.|nextOrdinal 1');
671
+ t.is(log.shift(), 'set vc.3.|entryCount 0');
672
+ t.is(log.shift(), 'set watchedPromiseTableID o+d6/3');
673
+ t.is(log.shift(), 'get vom.rc.o+d6/3 => undefined');
674
+ t.is(log.shift(), 'set vom.rc.o+d6/3 1');
657
675
  t.is(
658
676
  log.shift(),
659
- `set vom.vkind.10.descriptor {"kindID":"10","tag":"thing"}`,
677
+ 'set vom.vkind.10.descriptor {"kindID":"10","tag":"thing"}',
660
678
  );
661
679
  t.is(log.shift(), `set vom.vkind.11.descriptor {"kindID":"11","tag":"ref"}`);
662
680
  t.deepEqual(log, []);
@@ -682,6 +700,12 @@ test('virtual object gc', t => {
682
700
  t.deepEqual(dumpStore(), [
683
701
  ['kindIDID', '1'],
684
702
  skit,
703
+ ['vc.1.|entryCount', '0'],
704
+ ['vc.1.|nextOrdinal', '1'],
705
+ ['vc.2.|entryCount', '0'],
706
+ ['vc.2.|nextOrdinal', '1'],
707
+ ['vc.3.|entryCount', '0'],
708
+ ['vc.3.|nextOrdinal', '1'],
685
709
  [`vom.${tbase}/1`, minThing('thing #1')],
686
710
  [`vom.${tbase}/2`, minThing('thing #2')],
687
711
  [`vom.${tbase}/3`, minThing('thing #3')],
@@ -691,8 +715,12 @@ test('virtual object gc', t => {
691
715
  [`vom.${tbase}/7`, minThing('thing #7')],
692
716
  [`vom.${tbase}/8`, minThing('thing #8')],
693
717
  [`vom.${tbase}/9`, minThing('thing #9')],
718
+ ['vom.rc.o+d6/2', '1'],
719
+ ['vom.rc.o+d6/3', '1'],
694
720
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
695
721
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
722
+ ['watchedPromiseTableID', 'o+d6/3'],
723
+ ['watcherTableID', 'o+d6/2'],
696
724
  ]);
697
725
 
698
726
  // This is what the finalizer would do if the local reference was dropped and GC'd
@@ -718,6 +746,12 @@ test('virtual object gc', t => {
718
746
  t.deepEqual(dumpStore(), [
719
747
  ['kindIDID', '1'],
720
748
  skit,
749
+ ['vc.1.|entryCount', '0'],
750
+ ['vc.1.|nextOrdinal', '1'],
751
+ ['vc.2.|entryCount', '0'],
752
+ ['vc.2.|nextOrdinal', '1'],
753
+ ['vc.3.|entryCount', '0'],
754
+ ['vc.3.|nextOrdinal', '1'],
721
755
  [`vom.es.${tbase}/1`, 'r'],
722
756
  [`vom.${tbase}/1`, minThing('thing #1')],
723
757
  [`vom.${tbase}/2`, minThing('thing #2')],
@@ -728,8 +762,12 @@ test('virtual object gc', t => {
728
762
  [`vom.${tbase}/7`, minThing('thing #7')],
729
763
  [`vom.${tbase}/8`, minThing('thing #8')],
730
764
  [`vom.${tbase}/9`, minThing('thing #9')],
765
+ ['vom.rc.o+d6/2', '1'],
766
+ ['vom.rc.o+d6/3', '1'],
731
767
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
732
768
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
769
+ ['watchedPromiseTableID', 'o+d6/3'],
770
+ ['watcherTableID', 'o+d6/2'],
733
771
  ]);
734
772
 
735
773
  // drop export -- should delete
@@ -759,6 +797,12 @@ test('virtual object gc', t => {
759
797
  t.deepEqual(dumpStore(), [
760
798
  ['kindIDID', '1'],
761
799
  skit,
800
+ ['vc.1.|entryCount', '0'],
801
+ ['vc.1.|nextOrdinal', '1'],
802
+ ['vc.2.|entryCount', '0'],
803
+ ['vc.2.|nextOrdinal', '1'],
804
+ ['vc.3.|entryCount', '0'],
805
+ ['vc.3.|nextOrdinal', '1'],
762
806
  [`vom.${tbase}/2`, minThing('thing #2')],
763
807
  [`vom.${tbase}/3`, minThing('thing #3')],
764
808
  [`vom.${tbase}/4`, minThing('thing #4')],
@@ -767,8 +811,12 @@ test('virtual object gc', t => {
767
811
  [`vom.${tbase}/7`, minThing('thing #7')],
768
812
  [`vom.${tbase}/8`, minThing('thing #8')],
769
813
  [`vom.${tbase}/9`, minThing('thing #9')],
814
+ ['vom.rc.o+d6/2', '1'],
815
+ ['vom.rc.o+d6/3', '1'],
770
816
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
771
817
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
818
+ ['watchedPromiseTableID', 'o+d6/3'],
819
+ ['watcherTableID', 'o+d6/2'],
772
820
  ]);
773
821
 
774
822
  // case 2: export, drop export, drop local ref
@@ -786,6 +834,12 @@ test('virtual object gc', t => {
786
834
  t.deepEqual(dumpStore(), [
787
835
  ['kindIDID', '1'],
788
836
  skit,
837
+ ['vc.1.|entryCount', '0'],
838
+ ['vc.1.|nextOrdinal', '1'],
839
+ ['vc.2.|entryCount', '0'],
840
+ ['vc.2.|nextOrdinal', '1'],
841
+ ['vc.3.|entryCount', '0'],
842
+ ['vc.3.|nextOrdinal', '1'],
789
843
  [`vom.es.${tbase}/2`, 's'],
790
844
  [`vom.${tbase}/2`, minThing('thing #2')],
791
845
  [`vom.${tbase}/3`, minThing('thing #3')],
@@ -795,8 +849,12 @@ test('virtual object gc', t => {
795
849
  [`vom.${tbase}/7`, minThing('thing #7')],
796
850
  [`vom.${tbase}/8`, minThing('thing #8')],
797
851
  [`vom.${tbase}/9`, minThing('thing #9')],
852
+ ['vom.rc.o+d6/2', '1'],
853
+ ['vom.rc.o+d6/3', '1'],
798
854
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
799
855
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
856
+ ['watchedPromiseTableID', 'o+d6/3'],
857
+ ['watcherTableID', 'o+d6/2'],
800
858
  ]);
801
859
 
802
860
  // drop local ref -- should delete
@@ -817,6 +875,12 @@ test('virtual object gc', t => {
817
875
  t.deepEqual(dumpStore(), [
818
876
  ['kindIDID', '1'],
819
877
  skit,
878
+ ['vc.1.|entryCount', '0'],
879
+ ['vc.1.|nextOrdinal', '1'],
880
+ ['vc.2.|entryCount', '0'],
881
+ ['vc.2.|nextOrdinal', '1'],
882
+ ['vc.3.|entryCount', '0'],
883
+ ['vc.3.|nextOrdinal', '1'],
820
884
  [`vom.${tbase}/3`, minThing('thing #3')],
821
885
  [`vom.${tbase}/4`, minThing('thing #4')],
822
886
  [`vom.${tbase}/5`, minThing('thing #5')],
@@ -824,8 +888,12 @@ test('virtual object gc', t => {
824
888
  [`vom.${tbase}/7`, minThing('thing #7')],
825
889
  [`vom.${tbase}/8`, minThing('thing #8')],
826
890
  [`vom.${tbase}/9`, minThing('thing #9')],
891
+ ['vom.rc.o+d6/2', '1'],
892
+ ['vom.rc.o+d6/3', '1'],
827
893
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
828
894
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
895
+ ['watchedPromiseTableID', 'o+d6/3'],
896
+ ['watcherTableID', 'o+d6/2'],
829
897
  ]);
830
898
 
831
899
  // case 3: drop local ref with no prior export
@@ -847,14 +915,24 @@ test('virtual object gc', t => {
847
915
  t.deepEqual(dumpStore(), [
848
916
  ['kindIDID', '1'],
849
917
  skit,
918
+ ['vc.1.|entryCount', '0'],
919
+ ['vc.1.|nextOrdinal', '1'],
920
+ ['vc.2.|entryCount', '0'],
921
+ ['vc.2.|nextOrdinal', '1'],
922
+ ['vc.3.|entryCount', '0'],
923
+ ['vc.3.|nextOrdinal', '1'],
850
924
  [`vom.${tbase}/4`, minThing('thing #4')],
851
925
  [`vom.${tbase}/5`, minThing('thing #5')],
852
926
  [`vom.${tbase}/6`, minThing('thing #6')],
853
927
  [`vom.${tbase}/7`, minThing('thing #7')],
854
928
  [`vom.${tbase}/8`, minThing('thing #8')],
855
929
  [`vom.${tbase}/9`, minThing('thing #9')],
930
+ ['vom.rc.o+d6/2', '1'],
931
+ ['vom.rc.o+d6/3', '1'],
856
932
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
857
933
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
934
+ ['watchedPromiseTableID', 'o+d6/3'],
935
+ ['watcherTableID', 'o+d6/2'],
858
936
  ]);
859
937
 
860
938
  // case 4: ref virtually, export, drop local ref, drop export
@@ -867,15 +945,25 @@ test('virtual object gc', t => {
867
945
  t.deepEqual(dumpStore(), [
868
946
  ['kindIDID', '1'],
869
947
  skit,
948
+ ['vc.1.|entryCount', '0'],
949
+ ['vc.1.|nextOrdinal', '1'],
950
+ ['vc.2.|entryCount', '0'],
951
+ ['vc.2.|nextOrdinal', '1'],
952
+ ['vc.3.|entryCount', '0'],
953
+ ['vc.3.|nextOrdinal', '1'],
870
954
  [`vom.${tbase}/4`, minThing('thing #4')],
871
955
  [`vom.${tbase}/5`, minThing('thing #5')],
872
956
  [`vom.${tbase}/6`, minThing('thing #6')],
873
957
  [`vom.${tbase}/7`, minThing('thing #7')],
874
958
  [`vom.${tbase}/8`, minThing('thing #8')],
875
959
  [`vom.${tbase}/9`, minThing('thing #9')],
960
+ ['vom.rc.o+d6/2', '1'],
961
+ ['vom.rc.o+d6/3', '1'],
876
962
  [`vom.rc.${tbase}/4`, '1'],
877
963
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
878
964
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
965
+ ['watchedPromiseTableID', 'o+d6/3'],
966
+ ['watcherTableID', 'o+d6/2'],
879
967
  ]);
880
968
  // export
881
969
  setExportStatus(`${tbase}/4`, 'reachable');
@@ -909,6 +997,12 @@ test('virtual object gc', t => {
909
997
  t.deepEqual(dumpStore(), [
910
998
  ['kindIDID', '1'],
911
999
  skit,
1000
+ ['vc.1.|entryCount', '0'],
1001
+ ['vc.1.|nextOrdinal', '1'],
1002
+ ['vc.2.|entryCount', '0'],
1003
+ ['vc.2.|nextOrdinal', '1'],
1004
+ ['vc.3.|entryCount', '0'],
1005
+ ['vc.3.|nextOrdinal', '1'],
912
1006
  [`vom.es.${tbase}/4`, 's'],
913
1007
  [`vom.es.${tbase}/5`, 'r'],
914
1008
  [`vom.${tbase}/4`, minThing('thing #4')],
@@ -917,10 +1011,14 @@ test('virtual object gc', t => {
917
1011
  [`vom.${tbase}/7`, minThing('thing #7')],
918
1012
  [`vom.${tbase}/8`, minThing('thing #8')],
919
1013
  [`vom.${tbase}/9`, minThing('thing #9')],
1014
+ ['vom.rc.o+d6/2', '1'],
1015
+ ['vom.rc.o+d6/3', '1'],
920
1016
  [`vom.rc.${tbase}/4`, '1'],
921
1017
  [`vom.rc.${tbase}/5`, '1'],
922
1018
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
923
1019
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
1020
+ ['watchedPromiseTableID', 'o+d6/3'],
1021
+ ['watcherTableID', 'o+d6/2'],
924
1022
  ]);
925
1023
  // drop local ref -- should not delete because ref'd virtually AND exported
926
1024
  pretendGC(`${tbase}/5`, false);
@@ -944,6 +1042,12 @@ test('virtual object gc', t => {
944
1042
  t.deepEqual(dumpStore(), [
945
1043
  ['kindIDID', '1'],
946
1044
  skit,
1045
+ ['vc.1.|entryCount', '0'],
1046
+ ['vc.1.|nextOrdinal', '1'],
1047
+ ['vc.2.|entryCount', '0'],
1048
+ ['vc.2.|nextOrdinal', '1'],
1049
+ ['vc.3.|entryCount', '0'],
1050
+ ['vc.3.|nextOrdinal', '1'],
947
1051
  [`vom.es.${tbase}/4`, 's'],
948
1052
  [`vom.es.${tbase}/5`, 's'],
949
1053
  [`vom.${tbase}/4`, minThing('thing #4')],
@@ -952,11 +1056,15 @@ test('virtual object gc', t => {
952
1056
  [`vom.${tbase}/7`, minThing('thing #7')],
953
1057
  [`vom.${tbase}/8`, minThing('thing #8')],
954
1058
  [`vom.${tbase}/9`, minThing('thing #9')],
1059
+ ['vom.rc.o+d6/2', '1'],
1060
+ ['vom.rc.o+d6/3', '1'],
955
1061
  [`vom.rc.${tbase}/4`, '1'],
956
1062
  [`vom.rc.${tbase}/5`, '1'],
957
1063
  [`vom.rc.${tbase}/6`, '1'],
958
1064
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
959
1065
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
1066
+ ['watchedPromiseTableID', 'o+d6/3'],
1067
+ ['watcherTableID', 'o+d6/2'],
960
1068
  ]);
961
1069
  // drop local ref -- should not delete because ref'd virtually
962
1070
  pretendGC(`${tbase}/6`, false);
@@ -966,6 +1074,12 @@ test('virtual object gc', t => {
966
1074
  t.deepEqual(dumpStore(), [
967
1075
  ['kindIDID', '1'],
968
1076
  skit,
1077
+ ['vc.1.|entryCount', '0'],
1078
+ ['vc.1.|nextOrdinal', '1'],
1079
+ ['vc.2.|entryCount', '0'],
1080
+ ['vc.2.|nextOrdinal', '1'],
1081
+ ['vc.3.|entryCount', '0'],
1082
+ ['vc.3.|nextOrdinal', '1'],
969
1083
  [`vom.es.${tbase}/4`, 's'],
970
1084
  [`vom.es.${tbase}/5`, 's'],
971
1085
  [`vom.${tbase}/4`, minThing('thing #4')],
@@ -974,11 +1088,15 @@ test('virtual object gc', t => {
974
1088
  [`vom.${tbase}/7`, minThing('thing #7')],
975
1089
  [`vom.${tbase}/8`, minThing('thing #8')],
976
1090
  [`vom.${tbase}/9`, minThing('thing #9')],
1091
+ ['vom.rc.o+d6/2', '1'],
1092
+ ['vom.rc.o+d6/3', '1'],
977
1093
  [`vom.rc.${tbase}/4`, '1'],
978
1094
  [`vom.rc.${tbase}/5`, '1'],
979
1095
  [`vom.rc.${tbase}/6`, '1'],
980
1096
  ['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
981
1097
  ['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
1098
+ ['watchedPromiseTableID', 'o+d6/3'],
1099
+ ['watcherTableID', 'o+d6/2'],
982
1100
  ]);
983
1101
  });
984
1102
 
@@ -1,13 +1,13 @@
1
- /* global WeakRef */
1
+ // @ts-nocheck
2
2
  import test from 'ava';
3
- import '@endo/init/debug.js';
4
3
 
5
4
  import { Far } from '@endo/marshal';
6
- import { kser, kunser } from '../kmarshal.js';
5
+ import { kser, kunser } from '@agoric/kmarshal';
7
6
  import { setupTestLiveslots } from '../liveslots-helpers.js';
7
+ import { watchCollected } from '../gc-and-finalize.js';
8
8
 
9
9
  test('virtual object state writes', async t => {
10
- let monitor;
10
+ let collected;
11
11
 
12
12
  const initData = { begin: 'ning' };
13
13
  const initStateData = { begin: kser(initData.begin) };
@@ -23,11 +23,11 @@ test('virtual object state writes', async t => {
23
23
  const root = Far('root', {
24
24
  make: () => {
25
25
  const thing = makeThing();
26
- monitor = new WeakRef(thing);
26
+ collected = watchCollected(thing);
27
27
  return thing;
28
28
  },
29
29
  ping: thing => {
30
- monitor = new WeakRef(thing);
30
+ collected = watchCollected(thing);
31
31
  return thing.ping();
32
32
  },
33
33
  });
@@ -56,7 +56,7 @@ test('virtual object state writes', async t => {
56
56
 
57
57
  // 'thing' is exported, but not held in RAM, so the Representative
58
58
  // should be dropped
59
- t.falsy(monitor.deref());
59
+ t.true(collected.result);
60
60
 
61
61
  // Invoking a method, on the other hand, *does* require creation of
62
62
  // "state" and "context", and creation of "state" requires reading
@@ -70,5 +70,5 @@ test('virtual object state writes', async t => {
70
70
 
71
71
  // 'thing' is again dropped by RAM, so it should be dropped. If
72
72
  // "context" were erroneously retained, it would stick around.
73
- t.falsy(monitor.deref());
73
+ t.true(collected.result);
74
74
  });
@@ -1,9 +1,8 @@
1
1
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
2
 
4
3
  import { makeFakeVirtualObjectManager } from '../../tools/fakeVirtualSupport.js';
5
4
 
6
- test('weakMap vref handling', async t => {
5
+ test('weakMap vref handling', t => {
7
6
  const log = [];
8
7
  const {
9
8
  VirtualObjectAwareWeakMap,
@@ -1,5 +1,4 @@
1
1
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
2
  import { runVOTest } from '../tools/vo-test-harness.js';
4
3
 
5
4
  async function voTestTest(t, mode) {
@@ -1,13 +1,13 @@
1
+ // @ts-nocheck
1
2
  import test from 'ava';
2
- import '@endo/init/debug.js';
3
3
 
4
+ import { Fail } from '@endo/errors';
4
5
  import { E } from '@endo/eventual-send';
5
6
  import { makePromiseKit } from '@endo/promise-kit';
6
- import { Fail } from '@agoric/assert';
7
7
  import { Far } from '@endo/marshal';
8
+ import { kser, kslot } from '@agoric/kmarshal';
8
9
  import { buildSyscall, makeDispatch } from './liveslots-helpers.js';
9
10
  import { makeMessage, makeResolve, makeReject } from './util.js';
10
- import { kser, kslot } from './kmarshal.js';
11
11
 
12
12
  function hush(p) {
13
13
  p.then(
@@ -293,7 +293,6 @@ async function doVatResolveCase23(t, which, mode, stalls) {
293
293
  // another few turns. We wait some number of turns before using p1
294
294
  // again, to exercise as many race conditions as possible.
295
295
  for (let i = 0; i < stalls; i += 1) {
296
- // eslint-disable-next-line no-await-in-loop
297
296
  await Promise.resolve();
298
297
  }
299
298
 
@@ -858,7 +857,7 @@ test('inter-vat circular promise references', async t => {
858
857
  let r;
859
858
  return Far('root', {
860
859
  genPromise() {
861
- [p, r] = makePR();
860
+ void ([p, r] = makePR());
862
861
  return p;
863
862
  },
864
863
  usePromise(pa) {
@@ -899,3 +898,104 @@ test('inter-vat circular promise references', async t => {
899
898
  // });
900
899
  // t.deepEqual(log, []);
901
900
  });
901
+
902
+ test('accept previously allocated promise', async t => {
903
+ function build(vatPowers, vatParameters) {
904
+ const { target } = vatParameters;
905
+ return Far('root', {
906
+ call() {
907
+ const promise = E(target).foo();
908
+ // wrap to avoid adoption
909
+ return { promise };
910
+ },
911
+ async waitFor(promise2) {
912
+ // if we're in the same incarnation as the `E(target).foo()`, this
913
+ // `promise2` will be the same JS Promise as the `promise` above
914
+ const v = await promise2;
915
+ return v;
916
+ },
917
+ });
918
+ }
919
+
920
+ let log;
921
+ let syscall;
922
+ let dispatch;
923
+
924
+ const kvStore = new Map();
925
+ ({ log, syscall } = buildSyscall({ kvStore }));
926
+
927
+ const target = 'o-1';
928
+ ({ dispatch } = await makeDispatch(
929
+ syscall,
930
+ build,
931
+ 'reimport-promise',
932
+ {},
933
+ { target: kslot(target) },
934
+ ));
935
+ log.length = 0; // assume pre-build vatstore operations are correct
936
+
937
+ const root = 'o+0';
938
+ const callResultP = 'p-1';
939
+ const waitForResultP = 'p-2';
940
+ const expectedP1 = 'p+5';
941
+
942
+ await dispatch(makeMessage(root, 'call', [], callResultP));
943
+
944
+ // The vat should send 'foo', subscribe to the result promise, and resolve with that promise
945
+ t.deepEqual(log.splice(0, 3), [
946
+ {
947
+ type: 'send',
948
+ targetSlot: target,
949
+ methargs: kser(['foo', []]),
950
+ resultSlot: expectedP1,
951
+ },
952
+ { type: 'subscribe', target: expectedP1 },
953
+ {
954
+ type: 'resolve',
955
+ resolutions: [[callResultP, false, kser({ promise: kslot(expectedP1) })]],
956
+ },
957
+ ]);
958
+ matchIDCounterSet(t, log);
959
+ t.deepEqual(log, []);
960
+
961
+ // snapshot the store at this point
962
+ const clonedStore = new Map(kvStore);
963
+
964
+ const verifyPromiseReImport = async shouldSubscribe => {
965
+ await dispatch(
966
+ makeMessage(root, 'waitFor', [kslot(expectedP1)], waitForResultP),
967
+ );
968
+
969
+ // The vat will only subscribe if it was upgraded; if the vat still
970
+ // remembers it, receiving the vref will merely look it up in slotToVal and
971
+ // not create a new Promise (and trigger a subscribe)
972
+ if (shouldSubscribe) {
973
+ t.deepEqual(log.shift(), { type: 'subscribe', target: expectedP1 });
974
+ }
975
+
976
+ // waitFor will suspend until promise is resolved
977
+ t.deepEqual(log, []);
978
+
979
+ // Resolution propagates the value to the waitFor result
980
+ await dispatch(makeResolve(expectedP1, kser('success')));
981
+ t.deepEqual(log.shift(), {
982
+ type: 'resolve',
983
+ resolutions: [[waitForResultP, false, kser('success')]],
984
+ });
985
+ t.deepEqual(log, []);
986
+ };
987
+
988
+ await verifyPromiseReImport(false);
989
+ ({ log, syscall } = buildSyscall({ kvStore: clonedStore }));
990
+ ({ dispatch } = await makeDispatch(
991
+ syscall,
992
+ build,
993
+ 'reimport-promise-v2',
994
+ {},
995
+ {},
996
+ ));
997
+ log.length = 0;
998
+
999
+ // verify this works the same in the restarted vat
1000
+ await verifyPromiseReImport(true);
1001
+ });
@@ -1,6 +1,7 @@
1
1
  /* global setImmediate */
2
2
  import { makePromiseKit } from '@endo/promise-kit';
3
- /** @template T @typedef {import('@endo/promise-kit').PromiseKit<T>} PromiseKit */
3
+
4
+ /** @import {PromiseKit} from '@endo/promise-kit' */
4
5
 
5
6
  // This can only be imported from the Start Compartment, where 'setImmediate'
6
7
  // is available.
@@ -0,0 +1,50 @@
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/9956
10
+
11
+ test('delete remotable key from weakset', async t => {
12
+ const { syscall, log } = buildSyscall();
13
+ const gcTools = makeMockGC();
14
+ const rem = Far('remotable', {});
15
+
16
+ function buildRootObject(vatPowers) {
17
+ const { VatData } = vatPowers;
18
+ const { makeScalarBigWeakMapStore } = VatData;
19
+ const wms = makeScalarBigWeakMapStore();
20
+ return Far('root', {
21
+ store: p => {
22
+ wms.init(rem, p);
23
+ gcTools.kill(p);
24
+ },
25
+ });
26
+ }
27
+
28
+ const makeNS = () => ({ buildRootObject });
29
+ const ls = makeLiveSlots(syscall, 'vatA', {}, {}, gcTools, undefined, makeNS);
30
+ const { dispatch } = ls;
31
+ await dispatch(makeStartVat(kser()));
32
+
33
+ await dispatch(makeMessage('o+0', 'store', [kslot('o-1')]));
34
+
35
+ // pretend the Remotable was dropped from RAM
36
+ log.length = 0;
37
+ gcTools.kill(rem);
38
+ gcTools.flushAllFRs();
39
+ await dispatch(makeBringOutYourDead());
40
+
41
+ // that ought to emit a drop and retire for the presence
42
+ const gcCalls = log.filter(
43
+ l => l.type === 'dropImports' || l.type === 'retireImports',
44
+ );
45
+ t.deepEqual(gcCalls, [
46
+ { type: 'dropImports', slots: ['o-1'] },
47
+ { type: 'retireImports', slots: ['o-1'] },
48
+ ]);
49
+ log.length = 0;
50
+ });
@@ -0,0 +1,44 @@
1
+ import { makeCollectionManager } from '../src/collectionManager.js';
2
+
3
+ export function makeFakeCollectionManager(vrm, fakeStuff, _options = {}) {
4
+ const {
5
+ makeScalarBigMapStore,
6
+ makeScalarBigWeakMapStore,
7
+ makeScalarBigSetStore,
8
+ makeScalarBigWeakSetStore,
9
+ provideBaggage,
10
+ initializeStoreKindInfo,
11
+ flushSchemaCache,
12
+ } = makeCollectionManager(
13
+ fakeStuff.syscall,
14
+ vrm,
15
+ fakeStuff.allocateExportID,
16
+ fakeStuff.allocateCollectionID,
17
+ fakeStuff.convertValToSlot,
18
+ fakeStuff.convertSlotToVal,
19
+ fakeStuff.registerEntry,
20
+ fakeStuff.marshal.serialize,
21
+ fakeStuff.marshal.unserialize,
22
+ fakeStuff.assertAcceptableSyscallCapdataSize,
23
+ );
24
+ initializeStoreKindInfo();
25
+
26
+ const normalCM = {
27
+ makeScalarBigMapStore,
28
+ makeScalarBigWeakMapStore,
29
+ makeScalarBigSetStore,
30
+ makeScalarBigWeakSetStore,
31
+ provideBaggage,
32
+ flushSchemaCache,
33
+ };
34
+
35
+ const debugTools = {
36
+ getValForSlot: fakeStuff.getValForSlot,
37
+ setValForSlot: fakeStuff.setValForSlot,
38
+ registerEntry: fakeStuff.registerEntry,
39
+ deleteEntry: fakeStuff.deleteEntry,
40
+ dumpStore: fakeStuff.dumpStore,
41
+ };
42
+
43
+ return harden({ ...normalCM, ...debugTools });
44
+ }