@@ -64,7 +64,14 @@ UnstableNode Pickler::buildTypesRecord(VM vm) {
64
64
4 );
65
65
}
66
66
67
- void Pickler::pickle (RichNode value) {
67
+ static void restoreNodes (VM vm, VMAllocatedList<NodeBackup>& list) {
68
+ for (auto & nodeBackup : list) {
69
+ nodeBackup.restore ();
70
+ }
71
+ list.clear (vm);
72
+ }
73
+
74
+ void Pickler::pickle (RichNode value, RichNode temporaryReplacement) {
68
75
auto typesRecord = RichNode (*vm->getPickleTypesRecord ()).as <Record>();
69
76
auto statelessTypes = RichNode (*typesRecord.getArity ()).as <Arity>();
70
77
@@ -78,6 +85,29 @@ void Pickler::pickle(RichNode value) {
78
85
VMAllocatedList<PickleNode> nodes;
79
86
UnstableNode resources = buildNil (vm);
80
87
88
+ // Apply temporary replacements.
89
+ VMAllocatedList<NodeBackup> nodeReplacementBackups;
90
+ {
91
+ VMAllocatedList<std::pair<RichNode, RichNode>> replacements;
92
+
93
+ ozListForEach (vm, temporaryReplacement, [&replacements, this ](RichNode pair) {
94
+ using namespace patternmatching ;
95
+ RichNode from, to;
96
+ if (matchesSharp (vm, pair, capture (from), capture (to))) {
97
+ replacements.push_front_new (vm, from, to);
98
+ } else {
99
+ raiseTypeError (vm, " Tuple of the form From#To" , pair);
100
+ }
101
+ }, " List of pairs" );
102
+
103
+ for (auto & replacement : replacements) {
104
+ nodeReplacementBackups.push_front (vm, replacement.first .makeBackup ());
105
+ replacement.first .reinit (vm, replacement.second );
106
+ }
107
+
108
+ replacements.clear (vm);
109
+ }
110
+
81
111
// Replace serialized nodes by Serialized(index)
82
112
// and add them to the nodes list
83
113
while (!cb.todoFrom .empty ()) {
@@ -111,11 +141,9 @@ void Pickler::pickle(RichNode value) {
111
141
}
112
142
113
143
// Restore nodes
114
- while (!nodeBackups.empty ()) {
115
- nodeBackups.front ().restore ();
116
- nodeBackups.remove_front (vm);
117
- }
144
+ restoreNodes (vm, nodeBackups);
118
145
146
+ // Ensure no remaining futures or resources.
119
147
if (futures) {
120
148
for (auto & pickleNode : nodes) {
121
149
if (isFuture (pickleNode.node )) {
@@ -127,11 +155,13 @@ void Pickler::pickle(RichNode value) {
127
155
if (isFuture (pickleNode.node )) {
128
156
RichNode future = pickleNode.node ;
129
157
nodes.clear (vm);
158
+ restoreNodes (vm, nodeReplacementBackups);
130
159
waitFor (vm, future);
131
160
}
132
161
}
133
162
} else if (!RichNode (resources).is <Atom>()) {
134
163
nodes.clear (vm);
164
+ restoreNodes (vm, nodeReplacementBackups);
135
165
136
166
raiseError (vm, " dp" ,
137
167
" generic" ,
@@ -161,6 +191,9 @@ void Pickler::pickle(RichNode value) {
161
191
162
192
nativeint eof = 0 ;
163
193
writeSize (eof);
194
+
195
+ nodes.clear (vm);
196
+ restoreNodes (vm, nodeReplacementBackups);
164
197
}
165
198
166
199
void Pickler::writeValues (VMAllocatedList<PickleNode>& nodes) {
0 commit comments