@agoric/swingset-liveslots 0.10.3-mainnet1B-dev-b0c1f78.0 → 0.10.3-orchestration-dev-096c4e8.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 (58) hide show
  1. package/README.md +2 -0
  2. package/package.json +25 -17
  3. package/src/cache.js +5 -3
  4. package/src/collectionManager.js +147 -69
  5. package/src/index.js +2 -1
  6. package/src/liveslots.js +52 -79
  7. package/src/message.js +4 -4
  8. package/src/types.js +8 -2
  9. package/src/vatDataTypes.d.ts +234 -0
  10. package/src/vatDataTypes.js +2 -0
  11. package/src/vatstore-iterators.js +2 -0
  12. package/src/virtualObjectManager.js +107 -63
  13. package/src/virtualReferences.js +51 -0
  14. package/src/watchedPromises.js +50 -15
  15. package/test/gc-and-finalize.js +30 -1
  16. package/test/gc-helpers.js +2 -1
  17. package/test/liveslots-helpers.js +6 -6
  18. package/test/mock-gc.js +1 -0
  19. package/test/storeGC/test-lifecycle.js +2 -2
  20. package/test/storeGC/test-refcount-management.js +1 -2
  21. package/test/storeGC/test-scalar-store-kind.js +0 -1
  22. package/test/storeGC/test-weak-key.js +1 -2
  23. package/test/test-baggage.js +1 -2
  24. package/test/test-cache.js +0 -1
  25. package/test/test-collection-schema-refcount.js +1 -2
  26. package/test/test-collection-upgrade.js +1 -3
  27. package/test/test-collections.js +117 -14
  28. package/test/test-dropped-collection-weakrefs.js +1 -2
  29. package/test/test-durabilityChecks.js +3 -3
  30. package/test/test-facetiousness.js +1 -2
  31. package/test/test-gc-sensitivity.js +2 -2
  32. package/test/test-handled-promises.js +5 -7
  33. package/test/test-initial-vrefs.js +2 -3
  34. package/test/test-liveslots-mock-gc.js +2 -2
  35. package/test/test-liveslots-real-gc.js +44 -35
  36. package/test/test-liveslots.js +13 -14
  37. package/test/test-vo-test-harness.js +0 -1
  38. package/test/test-vpid-liveslots.js +4 -5
  39. package/test/util.js +2 -2
  40. package/test/vat-util.js +1 -1
  41. package/test/virtual-objects/test-cease-recognition.js +2 -2
  42. package/test/virtual-objects/test-cross-facet.js +1 -2
  43. package/test/virtual-objects/test-empty-data.js +1 -2
  44. package/test/virtual-objects/test-facets.js +1 -2
  45. package/test/virtual-objects/test-kind-changes.js +2 -2
  46. package/test/virtual-objects/test-reachable-vrefs.js +2 -2
  47. package/test/virtual-objects/test-rep-tostring.js +2 -3
  48. package/test/virtual-objects/test-retain-remotable.js +25 -24
  49. package/test/virtual-objects/test-state-shape.js +2 -2
  50. package/test/virtual-objects/test-virtualObjectGC.js +2 -2
  51. package/test/virtual-objects/test-virtualObjectManager.js +126 -8
  52. package/test/virtual-objects/test-vo-real-gc.js +8 -8
  53. package/test/virtual-objects/test-weakcollections-vref-handling.js +1 -2
  54. package/tools/fakeVirtualSupport.js +48 -21
  55. package/tools/prepare-test-env.js +13 -0
  56. package/tools/setup-vat-data.js +62 -0
  57. package/CHANGELOG.md +0 -85
  58. package/test/kmarshal.js +0 -79
@@ -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) {
@@ -128,6 +128,7 @@ test('multifaceted virtual objects', t => {
128
128
  flushStateCache();
129
129
  t.deepEqual(log.splice(0), [
130
130
  `get kindIDID => undefined`,
131
+ `get idCounters => undefined`,
131
132
  `set kindIDID 1`,
132
133
  `set vom.vkind.2.descriptor {"kindID":"2","tag":"multithing"}`,
133
134
  `set vom.${kid}/1 ${multiThingVal('foo', 1)}`,
@@ -203,6 +204,7 @@ test('virtual object operations', t => {
203
204
  const thing4 = makeThing('thing-4', 300); // [t4-0* t3-0* t2-0* t1-0*]
204
205
  // t4-0: 'thing-4' 300 0
205
206
  t.is(log.shift(), `get kindIDID => undefined`);
207
+ t.is(log.shift(), `get idCounters => 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"}`);
208
210
  t.is(log.shift(), `set vom.vkind.3.descriptor {"kindID":"3","tag":"zot"}`);
@@ -467,6 +469,7 @@ test('symbol named methods', t => {
467
469
  const thing2 = makeThing('thing-2', 100); // [t1-0* t2-0*]
468
470
  // t2-0: 'thing-2' 100 0
469
471
  t.is(log.shift(), `get kindIDID => undefined`);
472
+ t.is(log.shift(), `get idCounters => undefined`);
470
473
  t.is(log.shift(), `set kindIDID 1`);
471
474
  t.is(
472
475
  log.shift(),
@@ -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"}',
@@ -647,6 +650,7 @@ test('virtual object gc', t => {
647
650
  });
648
651
 
649
652
  t.is(log.shift(), `get kindIDID => undefined`);
653
+ t.is(log.shift(), `get idCounters => undefined`);
650
654
  t.is(log.shift(), `set kindIDID 1`);
651
655
  const skit = [
652
656
  'storeKindIDTable',
@@ -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,14 +1,23 @@
1
- /* global WeakRef */
1
+ /* global globalThis */
2
2
  /* eslint-disable max-classes-per-file */
3
3
  import { makeMarshal } from '@endo/marshal';
4
4
  import { assert } from '@agoric/assert';
5
- import { parseVatSlot } from '../src/parseVatSlots.js';
5
+ import { isPromise } from '@endo/promise-kit';
6
6
 
7
+ import { parseVatSlot } from '../src/parseVatSlots.js';
7
8
  import { makeVirtualReferenceManager } from '../src/virtualReferences.js';
8
9
  import { makeWatchedPromiseManager } from '../src/watchedPromises.js';
9
10
  import { makeFakeVirtualObjectManager } from './fakeVirtualObjectManager.js';
10
11
  import { makeFakeCollectionManager } from './fakeCollectionManager.js';
11
12
 
13
+ const { Fail } = assert;
14
+
15
+ const {
16
+ WeakRef: RealWeakRef,
17
+ WeakMap: RealWeakMap,
18
+ WeakSet: RealWeakSet,
19
+ } = globalThis;
20
+
12
21
  class FakeFinalizationRegistry {
13
22
  // eslint-disable-next-line no-useless-constructor, no-empty-function
14
23
  constructor() {}
@@ -30,8 +39,6 @@ class FakeWeakRef {
30
39
  }
31
40
  }
32
41
 
33
- const RealWeakRef = WeakRef;
34
-
35
42
  export function makeFakeLiveSlotsStuff(options = {}) {
36
43
  let vrm;
37
44
  function setVrm(vrmToUse) {
@@ -45,6 +52,8 @@ export function makeFakeLiveSlotsStuff(options = {}) {
45
52
  log,
46
53
  FinalizationRegistry = FakeFinalizationRegistry,
47
54
  WeakRef = FakeWeakRef, // VRM uses this
55
+ WeakMap = RealWeakMap,
56
+ WeakSet = RealWeakSet,
48
57
  addToPossiblyDeadSet = () => {},
49
58
  addToPossiblyRetiredSet = () => {},
50
59
  } = options;
@@ -151,18 +160,16 @@ export function makeFakeLiveSlotsStuff(options = {}) {
151
160
  },
152
161
  };
153
162
 
154
- let nextExportID = 1;
155
163
  function allocateExportID() {
156
- const exportID = nextExportID;
157
- nextExportID += 1;
158
- return exportID;
164
+ return vrm.allocateNextID('exportID');
165
+ }
166
+
167
+ function allocatePromiseID() {
168
+ return vrm.allocateNextID('promiseID');
159
169
  }
160
170
 
161
- let nextCollectionID = 1;
162
171
  function allocateCollectionID() {
163
- const collectionID = nextCollectionID;
164
- nextCollectionID += 1;
165
- return collectionID;
172
+ return vrm.allocateNextID('collectionID');
166
173
  }
167
174
 
168
175
  // note: The real liveslots slotToVal() maps slots (vrefs) to a WeakRef,
@@ -193,7 +200,9 @@ export function makeFakeLiveSlotsStuff(options = {}) {
193
200
 
194
201
  function convertValToSlot(val) {
195
202
  if (!valToSlot.has(val)) {
196
- const slot = `o+${allocateExportID()}`;
203
+ const slot = isPromise(val)
204
+ ? `p+${allocatePromiseID()}`
205
+ : `o+${allocateExportID()}`;
197
206
  valToSlot.set(val, slot);
198
207
  setValForSlot(slot, val);
199
208
  }
@@ -212,17 +221,23 @@ export function makeFakeLiveSlotsStuff(options = {}) {
212
221
  }
213
222
  return val;
214
223
  }
224
+ let result;
215
225
  if (virtual || durable) {
216
226
  if (vrm) {
217
227
  val = vrm.reanimate(slot);
218
228
  if (facet !== undefined) {
219
- return vrm.getFacet(id, val, facet);
229
+ result = vrm.getFacet(id, val, facet);
220
230
  }
221
231
  } else {
222
232
  assert.fail('fake liveSlots stuff configured without vrm');
223
233
  }
224
234
  }
225
- return val;
235
+ // eslint-disable-next-line no-use-before-define
236
+ registerEntry(baseRef, val, facet !== undefined);
237
+ if (!result) {
238
+ result = val;
239
+ }
240
+ return result;
226
241
  }
227
242
 
228
243
  const marshal = makeMarshal(convertValToSlot, convertSlotToVal, {
@@ -230,12 +245,15 @@ export function makeFakeLiveSlotsStuff(options = {}) {
230
245
  });
231
246
 
232
247
  function registerEntry(baseRef, val, valIsCohort) {
248
+ const { facet } = parseVatSlot(baseRef);
249
+ !facet ||
250
+ Fail`registerEntry(${baseRef} should not receive individual facets`;
233
251
  setValForSlot(baseRef, val);
234
252
  if (valIsCohort) {
235
253
  const { id } = parseVatSlot(baseRef);
236
- vrm.getFacetNames(id).forEach((name, index) => {
254
+ for (const [index, name] of vrm.getFacetNames(id).entries()) {
237
255
  valToSlot.set(val[name], `${baseRef}:${index}`);
238
- });
256
+ }
239
257
  } else {
240
258
  valToSlot.set(val, baseRef);
241
259
  }
@@ -270,6 +288,8 @@ export function makeFakeLiveSlotsStuff(options = {}) {
270
288
  deleteEntry,
271
289
  FinalizationRegistry,
272
290
  WeakRef,
291
+ WeakMap,
292
+ WeakSet,
273
293
  addToPossiblyDeadSet,
274
294
  addToPossiblyRetiredSet,
275
295
  dumpStore,
@@ -311,12 +331,17 @@ export function makeFakeWatchedPromiseManager(
311
331
  maybeExportPromise: fakeStuff.maybeExportPromise,
312
332
  });
313
333
  }
334
+
314
335
  /**
315
336
  * Configure virtual stuff with relaxed durability rules and fake liveslots
316
337
  *
317
338
  * @param {object} [options]
318
- * @param {number} [options.cacheSize=3]
319
- * @param {boolean} [options.relaxDurabilityRules=true]
339
+ * @param {number} [options.cacheSize]
340
+ * @param {boolean} [options.relaxDurabilityRules]
341
+ * @param {Map<any, any>} [options.fakeStore]
342
+ * @param {WeakMapConstructor} [options.WeakMap]
343
+ * @param {WeakSetConstructor} [options.WeakSet]
344
+ * @param {boolean} [options.weak]
320
345
  */
321
346
  export function makeFakeVirtualStuff(options = {}) {
322
347
  const actualOptions = {
@@ -326,11 +351,12 @@ export function makeFakeVirtualStuff(options = {}) {
326
351
  const { relaxDurabilityRules } = actualOptions;
327
352
  const fakeStuff = makeFakeLiveSlotsStuff(actualOptions);
328
353
  const vrm = makeFakeVirtualReferenceManager(fakeStuff, relaxDurabilityRules);
354
+ fakeStuff.setVrm(vrm);
329
355
  const vom = makeFakeVirtualObjectManager(vrm, fakeStuff);
330
356
  vom.initializeKindHandleKind();
331
- fakeStuff.setVrm(vrm);
332
357
  const cm = makeFakeCollectionManager(vrm, fakeStuff, actualOptions);
333
358
  const wpm = makeFakeWatchedPromiseManager(vrm, vom, cm, fakeStuff);
359
+ wpm.preparePromiseWatcherTables();
334
360
  return { fakeStuff, vrm, vom, cm, wpm };
335
361
  }
336
362
 
@@ -338,9 +364,9 @@ export function makeStandaloneFakeVirtualObjectManager(options = {}) {
338
364
  const fakeStuff = makeFakeLiveSlotsStuff(options);
339
365
  const { relaxDurabilityRules = true } = options;
340
366
  const vrm = makeFakeVirtualReferenceManager(fakeStuff, relaxDurabilityRules);
367
+ fakeStuff.setVrm(vrm);
341
368
  const vom = makeFakeVirtualObjectManager(vrm, fakeStuff);
342
369
  vom.initializeKindHandleKind();
343
- fakeStuff.setVrm(vrm);
344
370
  return vom;
345
371
  }
346
372
 
@@ -348,6 +374,7 @@ export function makeStandaloneFakeCollectionManager(options = {}) {
348
374
  const fakeStuff = makeFakeLiveSlotsStuff(options);
349
375
  const { relaxDurabilityRules = true } = options;
350
376
  const vrm = makeFakeVirtualReferenceManager(fakeStuff, relaxDurabilityRules);
377
+ fakeStuff.setVrm(vrm);
351
378
  return makeFakeCollectionManager(vrm, fakeStuff, options);
352
379
  }
353
380
 
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Prepare Agoric SwingSet vat global environment for testing.
3
+ *
4
+ * Installs Hardened JS (and does lockdown), plus adds mocks for virtual objects
5
+ * and stores.
6
+ */
7
+
8
+ import '@agoric/internal/src/install-ses-debug.js';
9
+
10
+ import { reincarnate } from './setup-vat-data.js';
11
+
12
+ // Install the VatData globals.
13
+ reincarnate();
@@ -0,0 +1,62 @@
1
+ // @ts-check
2
+ /* global globalThis */
3
+ // This file produces the globalThis.VatData property outside of a running
4
+ // SwingSet so that it can be used by '@agoric/vat-data' (which only *consumes*
5
+ // `globalThis.VatData`) in code under test.
6
+ import { makeFakeVirtualStuff } from './fakeVirtualSupport.js';
7
+
8
+ const { WeakMap, WeakSet } = globalThis;
9
+
10
+ /** @type {ReturnType<makeFakeVirtualStuff>} */
11
+ let fakeVomKit;
12
+
13
+ globalThis.VatData = harden({
14
+ // @ts-expect-error spread argument for non-rest parameter
15
+ defineKind: (...args) => fakeVomKit.vom.defineKind(...args),
16
+ // @ts-expect-error spread argument for non-rest parameter
17
+ defineKindMulti: (...args) => fakeVomKit.vom.defineKindMulti(...args),
18
+ // @ts-expect-error spread argument for non-rest parameter
19
+ defineDurableKind: (...args) => fakeVomKit.vom.defineDurableKind(...args),
20
+ defineDurableKindMulti: (...args) =>
21
+ // @ts-expect-error spread argument for non-rest parameter
22
+ fakeVomKit.vom.defineDurableKindMulti(...args),
23
+ makeKindHandle: tag => fakeVomKit.vom.makeKindHandle(tag),
24
+ canBeDurable: (...args) => fakeVomKit.vom.canBeDurable(...args),
25
+ providePromiseWatcher: (...args) =>
26
+ // @ts-expect-error spread argument for non-rest parameter
27
+ fakeVomKit.wpm.providePromiseWatcher(...args),
28
+ watchPromise: (p, watcher, ...args) =>
29
+ fakeVomKit.wpm.watchPromise(p, watcher, ...args),
30
+ makeScalarBigMapStore: (...args) =>
31
+ fakeVomKit.cm.makeScalarBigMapStore(...args),
32
+ makeScalarBigWeakMapStore: (...args) =>
33
+ fakeVomKit.cm.makeScalarBigWeakMapStore(...args),
34
+ makeScalarBigSetStore: (...args) =>
35
+ fakeVomKit.cm.makeScalarBigSetStore(...args),
36
+ makeScalarBigWeakSetStore: (...args) =>
37
+ fakeVomKit.cm.makeScalarBigWeakSetStore(...args),
38
+ });
39
+
40
+ export const reincarnate = (options = {}) => {
41
+ const { fakeStore = new Map(), fakeVomKit: fvk } = options;
42
+
43
+ if (options.fakeVomKit) {
44
+ fvk.vom.flushStateCache();
45
+ fvk.cm.flushSchemaCache();
46
+ fvk.vrm.flushIDCounters();
47
+ }
48
+
49
+ fakeVomKit = makeFakeVirtualStuff({
50
+ ...options,
51
+ fakeStore,
52
+ WeakMap,
53
+ WeakSet,
54
+ });
55
+
56
+ // @ts-expect-error toStringTag set imperatively so it doesn't show up in the type
57
+ globalThis.WeakMap = fakeVomKit.vom.VirtualObjectAwareWeakMap;
58
+ // @ts-expect-error ditto
59
+ globalThis.WeakSet = fakeVomKit.vom.VirtualObjectAwareWeakSet;
60
+
61
+ return { ...options, fakeStore, fakeVomKit };
62
+ };