mustardscript 0.1.0 → 0.1.1
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.
- package/README.md +62 -20
- package/SECURITY.md +1 -1
- package/dist/index.js +2 -0
- package/dist/lib/executor.js +16 -1
- package/dist/lib/policy.js +301 -22
- package/dist/lib/progress.js +499 -113
- package/dist/lib/runtime.js +109 -40
- package/dist/lib/structured.js +327 -11
- package/dist/native-loader.js +11 -12
- package/index.d.ts +54 -6
- package/mustard.d.ts +23 -1
- package/package.json +34 -25
- package/Cargo.lock +0 -1579
- package/Cargo.toml +0 -40
- package/crates/mustard/Cargo.toml +0 -31
- package/crates/mustard/src/cancellation.rs +0 -28
- package/crates/mustard/src/diagnostic.rs +0 -145
- package/crates/mustard/src/ir.rs +0 -435
- package/crates/mustard/src/lib.rs +0 -21
- package/crates/mustard/src/limits.rs +0 -22
- package/crates/mustard/src/parser/expressions.rs +0 -723
- package/crates/mustard/src/parser/mod.rs +0 -115
- package/crates/mustard/src/parser/operators.rs +0 -105
- package/crates/mustard/src/parser/patterns.rs +0 -123
- package/crates/mustard/src/parser/scope.rs +0 -107
- package/crates/mustard/src/parser/statements.rs +0 -298
- package/crates/mustard/src/parser/tests/acceptance.rs +0 -339
- package/crates/mustard/src/parser/tests/mod.rs +0 -2
- package/crates/mustard/src/parser/tests/rejections.rs +0 -107
- package/crates/mustard/src/runtime/accounting.rs +0 -613
- package/crates/mustard/src/runtime/api.rs +0 -192
- package/crates/mustard/src/runtime/async_runtime/mod.rs +0 -5
- package/crates/mustard/src/runtime/async_runtime/promises.rs +0 -246
- package/crates/mustard/src/runtime/async_runtime/reactions.rs +0 -400
- package/crates/mustard/src/runtime/async_runtime/scheduler.rs +0 -224
- package/crates/mustard/src/runtime/builtins/arrays.rs +0 -1205
- package/crates/mustard/src/runtime/builtins/collections.rs +0 -573
- package/crates/mustard/src/runtime/builtins/install.rs +0 -501
- package/crates/mustard/src/runtime/builtins/intl.rs +0 -553
- package/crates/mustard/src/runtime/builtins/mod.rs +0 -25
- package/crates/mustard/src/runtime/builtins/objects.rs +0 -405
- package/crates/mustard/src/runtime/builtins/primitives.rs +0 -859
- package/crates/mustard/src/runtime/builtins/promises.rs +0 -335
- package/crates/mustard/src/runtime/builtins/regexp.rs +0 -356
- package/crates/mustard/src/runtime/builtins/strings.rs +0 -803
- package/crates/mustard/src/runtime/builtins/support.rs +0 -561
- package/crates/mustard/src/runtime/bytecode.rs +0 -123
- package/crates/mustard/src/runtime/compiler/assignments.rs +0 -690
- package/crates/mustard/src/runtime/compiler/bindings.rs +0 -92
- package/crates/mustard/src/runtime/compiler/context.rs +0 -46
- package/crates/mustard/src/runtime/compiler/control.rs +0 -342
- package/crates/mustard/src/runtime/compiler/expressions.rs +0 -372
- package/crates/mustard/src/runtime/compiler/mod.rs +0 -173
- package/crates/mustard/src/runtime/compiler/statements.rs +0 -459
- package/crates/mustard/src/runtime/conversions/boundary.rs +0 -293
- package/crates/mustard/src/runtime/conversions/coercions.rs +0 -217
- package/crates/mustard/src/runtime/conversions/errors.rs +0 -118
- package/crates/mustard/src/runtime/conversions/mod.rs +0 -14
- package/crates/mustard/src/runtime/conversions/operators.rs +0 -334
- package/crates/mustard/src/runtime/env.rs +0 -355
- package/crates/mustard/src/runtime/exceptions.rs +0 -377
- package/crates/mustard/src/runtime/gc.rs +0 -595
- package/crates/mustard/src/runtime/mod.rs +0 -318
- package/crates/mustard/src/runtime/properties.rs +0 -1762
- package/crates/mustard/src/runtime/serialization.rs +0 -127
- package/crates/mustard/src/runtime/shared.rs +0 -108
- package/crates/mustard/src/runtime/snapshot_validation_tests.rs +0 -93
- package/crates/mustard/src/runtime/state.rs +0 -652
- package/crates/mustard/src/runtime/tests/async_host.rs +0 -104
- package/crates/mustard/src/runtime/tests/collections.rs +0 -50
- package/crates/mustard/src/runtime/tests/diagnostics.rs +0 -36
- package/crates/mustard/src/runtime/tests/exceptions.rs +0 -122
- package/crates/mustard/src/runtime/tests/execution.rs +0 -553
- package/crates/mustard/src/runtime/tests/gc.rs +0 -533
- package/crates/mustard/src/runtime/tests/mod.rs +0 -56
- package/crates/mustard/src/runtime/tests/serialization.rs +0 -170
- package/crates/mustard/src/runtime/validation/bytecode.rs +0 -484
- package/crates/mustard/src/runtime/validation/mod.rs +0 -14
- package/crates/mustard/src/runtime/validation/policy.rs +0 -94
- package/crates/mustard/src/runtime/validation/snapshot.rs +0 -406
- package/crates/mustard/src/runtime/validation/walk.rs +0 -206
- package/crates/mustard/src/runtime/vm.rs +0 -1016
- package/crates/mustard/src/span.rs +0 -22
- package/crates/mustard/src/structured.rs +0 -107
- package/crates/mustard-bridge/Cargo.toml +0 -17
- package/crates/mustard-bridge/src/codec.rs +0 -46
- package/crates/mustard-bridge/src/dto.rs +0 -99
- package/crates/mustard-bridge/src/lib.rs +0 -12
- package/crates/mustard-bridge/src/operations.rs +0 -142
- package/crates/mustard-node/Cargo.toml +0 -24
- package/crates/mustard-node/build.rs +0 -3
- package/crates/mustard-node/src/lib.rs +0 -236
- package/crates/mustard-sidecar/Cargo.toml +0 -21
- package/crates/mustard-sidecar/src/lib.rs +0 -134
- package/crates/mustard-sidecar/src/main.rs +0 -36
- package/dist/install.js +0 -117
|
@@ -1,595 +0,0 @@
|
|
|
1
|
-
use super::*;
|
|
2
|
-
|
|
3
|
-
impl Runtime {
|
|
4
|
-
pub(super) fn collect_garbage_before_instruction(
|
|
5
|
-
&mut self,
|
|
6
|
-
instruction: &Instruction,
|
|
7
|
-
) -> MustardResult<()> {
|
|
8
|
-
if instruction_may_allocate(instruction) {
|
|
9
|
-
self.collect_garbage()?;
|
|
10
|
-
}
|
|
11
|
-
Ok(())
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
pub(super) fn collect_garbage(&mut self) -> MustardResult<GarbageCollectionStats> {
|
|
15
|
-
let baseline_bytes = self.heap_bytes_used;
|
|
16
|
-
let baseline_allocations = self.allocation_count;
|
|
17
|
-
let marks = self.mark_reachable_heap()?;
|
|
18
|
-
|
|
19
|
-
self.sweep_unreachable_envs(&marks);
|
|
20
|
-
self.sweep_unreachable_cells(&marks);
|
|
21
|
-
self.sweep_unreachable_objects(&marks);
|
|
22
|
-
self.sweep_unreachable_arrays(&marks);
|
|
23
|
-
self.sweep_unreachable_maps(&marks);
|
|
24
|
-
self.sweep_unreachable_sets(&marks);
|
|
25
|
-
self.sweep_unreachable_iterators(&marks);
|
|
26
|
-
self.sweep_unreachable_closures(&marks);
|
|
27
|
-
self.sweep_unreachable_promises(&marks);
|
|
28
|
-
|
|
29
|
-
let (heap_bytes_used, allocation_count) = self
|
|
30
|
-
.recompute_accounting_totals()
|
|
31
|
-
.map_err(MustardError::runtime)?;
|
|
32
|
-
self.heap_bytes_used = heap_bytes_used;
|
|
33
|
-
self.allocation_count = allocation_count;
|
|
34
|
-
|
|
35
|
-
Ok(GarbageCollectionStats {
|
|
36
|
-
reclaimed_bytes: baseline_bytes.saturating_sub(heap_bytes_used),
|
|
37
|
-
reclaimed_allocations: baseline_allocations.saturating_sub(allocation_count),
|
|
38
|
-
})
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
pub(super) fn mark_reachable_heap(&self) -> MustardResult<GarbageCollectionMarks> {
|
|
42
|
-
let mut marks = GarbageCollectionMarks::default();
|
|
43
|
-
let mut worklist = GarbageCollectionWorklist::default();
|
|
44
|
-
|
|
45
|
-
self.mark_env(self.globals, &mut marks, &mut worklist);
|
|
46
|
-
for prototype in self.builtin_prototypes.values() {
|
|
47
|
-
self.mark_value(&Value::Object(*prototype), &mut marks, &mut worklist);
|
|
48
|
-
}
|
|
49
|
-
for object in self.builtin_function_objects.values() {
|
|
50
|
-
self.mark_value(&Value::Object(*object), &mut marks, &mut worklist);
|
|
51
|
-
}
|
|
52
|
-
for object in self.host_function_objects.values() {
|
|
53
|
-
self.mark_value(&Value::Object(*object), &mut marks, &mut worklist);
|
|
54
|
-
}
|
|
55
|
-
if let Some(root_result) = &self.root_result {
|
|
56
|
-
self.mark_value(root_result, &mut marks, &mut worklist);
|
|
57
|
-
}
|
|
58
|
-
for frame in &self.frames {
|
|
59
|
-
self.mark_frame_roots(frame, &mut marks, &mut worklist);
|
|
60
|
-
}
|
|
61
|
-
for job in &self.microtasks {
|
|
62
|
-
match job {
|
|
63
|
-
MicrotaskJob::ResumeAsync {
|
|
64
|
-
continuation,
|
|
65
|
-
outcome,
|
|
66
|
-
} => {
|
|
67
|
-
for frame in &continuation.frames {
|
|
68
|
-
self.mark_frame_roots(frame, &mut marks, &mut worklist);
|
|
69
|
-
}
|
|
70
|
-
match outcome {
|
|
71
|
-
PromiseOutcome::Fulfilled(value) => {
|
|
72
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
73
|
-
}
|
|
74
|
-
PromiseOutcome::Rejected(rejection) => {
|
|
75
|
-
self.mark_value(&rejection.value, &mut marks, &mut worklist);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
MicrotaskJob::PromiseReaction { reaction, outcome } => {
|
|
80
|
-
self.mark_promise(
|
|
81
|
-
self.promise_reaction_target(reaction),
|
|
82
|
-
&mut marks,
|
|
83
|
-
&mut worklist,
|
|
84
|
-
);
|
|
85
|
-
match reaction {
|
|
86
|
-
PromiseReaction::Then {
|
|
87
|
-
on_fulfilled,
|
|
88
|
-
on_rejected,
|
|
89
|
-
..
|
|
90
|
-
} => {
|
|
91
|
-
if let Some(handler) = on_fulfilled {
|
|
92
|
-
self.mark_value(handler, &mut marks, &mut worklist);
|
|
93
|
-
}
|
|
94
|
-
if let Some(handler) = on_rejected {
|
|
95
|
-
self.mark_value(handler, &mut marks, &mut worklist);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
PromiseReaction::Finally { callback, .. } => {
|
|
99
|
-
if let Some(callback) = callback {
|
|
100
|
-
self.mark_value(callback, &mut marks, &mut worklist);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
PromiseReaction::FinallyPassThrough {
|
|
104
|
-
original_outcome, ..
|
|
105
|
-
} => match original_outcome {
|
|
106
|
-
PromiseOutcome::Fulfilled(value) => {
|
|
107
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
108
|
-
}
|
|
109
|
-
PromiseOutcome::Rejected(rejection) => {
|
|
110
|
-
self.mark_value(&rejection.value, &mut marks, &mut worklist);
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
PromiseReaction::Combinator { .. } => {}
|
|
114
|
-
}
|
|
115
|
-
match outcome {
|
|
116
|
-
PromiseOutcome::Fulfilled(value) => {
|
|
117
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
118
|
-
}
|
|
119
|
-
PromiseOutcome::Rejected(rejection) => {
|
|
120
|
-
self.mark_value(&rejection.value, &mut marks, &mut worklist);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
for request in &self.pending_host_calls {
|
|
127
|
-
if let Some(promise) = request.promise {
|
|
128
|
-
self.mark_promise(promise, &mut marks, &mut worklist);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if let Some(request) = &self.suspended_host_call
|
|
132
|
-
&& let Some(promise) = request.promise
|
|
133
|
-
{
|
|
134
|
-
self.mark_promise(promise, &mut marks, &mut worklist);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
while !worklist.envs.is_empty()
|
|
138
|
-
|| !worklist.cells.is_empty()
|
|
139
|
-
|| !worklist.objects.is_empty()
|
|
140
|
-
|| !worklist.arrays.is_empty()
|
|
141
|
-
|| !worklist.maps.is_empty()
|
|
142
|
-
|| !worklist.sets.is_empty()
|
|
143
|
-
|| !worklist.iterators.is_empty()
|
|
144
|
-
|| !worklist.closures.is_empty()
|
|
145
|
-
|| !worklist.promises.is_empty()
|
|
146
|
-
{
|
|
147
|
-
while let Some(key) = worklist.envs.pop() {
|
|
148
|
-
let env = self
|
|
149
|
-
.envs
|
|
150
|
-
.get(key)
|
|
151
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing environment"))?;
|
|
152
|
-
if let Some(parent) = env.parent {
|
|
153
|
-
self.mark_env(parent, &mut marks, &mut worklist);
|
|
154
|
-
}
|
|
155
|
-
for cell in env.bindings.values() {
|
|
156
|
-
self.mark_cell(*cell, &mut marks, &mut worklist);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
while let Some(key) = worklist.cells.pop() {
|
|
161
|
-
let cell = self
|
|
162
|
-
.cells
|
|
163
|
-
.get(key)
|
|
164
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing binding cell"))?;
|
|
165
|
-
self.mark_value(&cell.value, &mut marks, &mut worklist);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
while let Some(key) = worklist.objects.pop() {
|
|
169
|
-
let object = self
|
|
170
|
-
.objects
|
|
171
|
-
.get(key)
|
|
172
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing object"))?;
|
|
173
|
-
if let ObjectKind::FunctionPrototype(constructor) = &object.kind {
|
|
174
|
-
self.mark_value(constructor, &mut marks, &mut worklist);
|
|
175
|
-
}
|
|
176
|
-
if let ObjectKind::BoundFunction(bound) = &object.kind {
|
|
177
|
-
self.mark_value(&bound.target, &mut marks, &mut worklist);
|
|
178
|
-
self.mark_value(&bound.this_value, &mut marks, &mut worklist);
|
|
179
|
-
for value in &bound.args {
|
|
180
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
for value in object.properties.values() {
|
|
184
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
while let Some(key) = worklist.arrays.pop() {
|
|
189
|
-
let array = self
|
|
190
|
-
.arrays
|
|
191
|
-
.get(key)
|
|
192
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing array"))?;
|
|
193
|
-
for value in array.elements.iter().flatten() {
|
|
194
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
195
|
-
}
|
|
196
|
-
for value in array.properties.values() {
|
|
197
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
while let Some(key) = worklist.maps.pop() {
|
|
202
|
-
let map = self
|
|
203
|
-
.maps
|
|
204
|
-
.get(key)
|
|
205
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing map"))?;
|
|
206
|
-
for entry in &map.entries {
|
|
207
|
-
self.mark_value(&entry.key, &mut marks, &mut worklist);
|
|
208
|
-
self.mark_value(&entry.value, &mut marks, &mut worklist);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
while let Some(key) = worklist.sets.pop() {
|
|
213
|
-
let set = self
|
|
214
|
-
.sets
|
|
215
|
-
.get(key)
|
|
216
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing set"))?;
|
|
217
|
-
for value in &set.entries {
|
|
218
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
while let Some(key) = worklist.iterators.pop() {
|
|
223
|
-
let iterator = self
|
|
224
|
-
.iterators
|
|
225
|
-
.get(key)
|
|
226
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing iterator"))?;
|
|
227
|
-
match iterator.state {
|
|
228
|
-
IteratorState::Array(ref state) => {
|
|
229
|
-
self.mark_value(&Value::Array(state.array), &mut marks, &mut worklist);
|
|
230
|
-
}
|
|
231
|
-
IteratorState::ArrayKeys(ref state)
|
|
232
|
-
| IteratorState::ArrayEntries(ref state) => {
|
|
233
|
-
self.mark_value(&Value::Array(state.array), &mut marks, &mut worklist);
|
|
234
|
-
}
|
|
235
|
-
IteratorState::String(_) => {}
|
|
236
|
-
IteratorState::MapEntries(ref state)
|
|
237
|
-
| IteratorState::MapKeys(ref state)
|
|
238
|
-
| IteratorState::MapValues(ref state) => {
|
|
239
|
-
self.mark_value(&Value::Map(state.map), &mut marks, &mut worklist);
|
|
240
|
-
}
|
|
241
|
-
IteratorState::SetEntries(ref state) | IteratorState::SetValues(ref state) => {
|
|
242
|
-
self.mark_value(&Value::Set(state.set), &mut marks, &mut worklist);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
while let Some(key) = worklist.closures.pop() {
|
|
248
|
-
let closure = self
|
|
249
|
-
.closures
|
|
250
|
-
.get(key)
|
|
251
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing closure"))?;
|
|
252
|
-
self.mark_env(closure.env, &mut marks, &mut worklist);
|
|
253
|
-
self.mark_value(&closure.this_value, &mut marks, &mut worklist);
|
|
254
|
-
if let Some(prototype) = closure.prototype {
|
|
255
|
-
self.mark_value(&Value::Object(prototype), &mut marks, &mut worklist);
|
|
256
|
-
}
|
|
257
|
-
for value in closure.properties.values() {
|
|
258
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
while let Some(key) = worklist.promises.pop() {
|
|
263
|
-
let promise = self
|
|
264
|
-
.promises
|
|
265
|
-
.get(key)
|
|
266
|
-
.ok_or_else(|| MustardError::runtime("gc encountered missing promise"))?;
|
|
267
|
-
match &promise.state {
|
|
268
|
-
PromiseState::Pending => {}
|
|
269
|
-
PromiseState::Fulfilled(value) => {
|
|
270
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
271
|
-
}
|
|
272
|
-
PromiseState::Rejected(rejection) => {
|
|
273
|
-
self.mark_value(&rejection.value, &mut marks, &mut worklist);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
for continuation in &promise.awaiters {
|
|
277
|
-
for frame in &continuation.frames {
|
|
278
|
-
self.mark_frame_roots(frame, &mut marks, &mut worklist);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
for dependent in &promise.dependents {
|
|
282
|
-
self.mark_promise(*dependent, &mut marks, &mut worklist);
|
|
283
|
-
}
|
|
284
|
-
for reaction in &promise.reactions {
|
|
285
|
-
self.mark_promise(
|
|
286
|
-
self.promise_reaction_target(reaction),
|
|
287
|
-
&mut marks,
|
|
288
|
-
&mut worklist,
|
|
289
|
-
);
|
|
290
|
-
match reaction {
|
|
291
|
-
PromiseReaction::Then {
|
|
292
|
-
on_fulfilled,
|
|
293
|
-
on_rejected,
|
|
294
|
-
..
|
|
295
|
-
} => {
|
|
296
|
-
if let Some(handler) = on_fulfilled {
|
|
297
|
-
self.mark_value(handler, &mut marks, &mut worklist);
|
|
298
|
-
}
|
|
299
|
-
if let Some(handler) = on_rejected {
|
|
300
|
-
self.mark_value(handler, &mut marks, &mut worklist);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
PromiseReaction::Finally { callback, .. } => {
|
|
304
|
-
if let Some(callback) = callback {
|
|
305
|
-
self.mark_value(callback, &mut marks, &mut worklist);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
PromiseReaction::FinallyPassThrough {
|
|
309
|
-
original_outcome, ..
|
|
310
|
-
} => match original_outcome {
|
|
311
|
-
PromiseOutcome::Fulfilled(value) => {
|
|
312
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
313
|
-
}
|
|
314
|
-
PromiseOutcome::Rejected(rejection) => {
|
|
315
|
-
self.mark_value(&rejection.value, &mut marks, &mut worklist);
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
|
-
PromiseReaction::Combinator { .. } => {}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
if let Some(driver) = &promise.driver {
|
|
322
|
-
match driver {
|
|
323
|
-
PromiseDriver::Thenable { value } => {
|
|
324
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
325
|
-
}
|
|
326
|
-
PromiseDriver::All { values, .. } => {
|
|
327
|
-
for value in values.iter().flatten() {
|
|
328
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
PromiseDriver::AllSettled { results, .. } => {
|
|
332
|
-
for result in results.iter().flatten() {
|
|
333
|
-
match result {
|
|
334
|
-
PromiseSettledResult::Fulfilled(value)
|
|
335
|
-
| PromiseSettledResult::Rejected(value) => {
|
|
336
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
PromiseDriver::Any { reasons, .. } => {
|
|
342
|
-
for value in reasons.iter().flatten() {
|
|
343
|
-
self.mark_value(value, &mut marks, &mut worklist);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
Ok(marks)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
pub(super) fn mark_env(
|
|
355
|
-
&self,
|
|
356
|
-
key: EnvKey,
|
|
357
|
-
marks: &mut GarbageCollectionMarks,
|
|
358
|
-
worklist: &mut GarbageCollectionWorklist,
|
|
359
|
-
) {
|
|
360
|
-
if marks.envs.insert(key) {
|
|
361
|
-
worklist.envs.push(key);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
pub(super) fn mark_cell(
|
|
366
|
-
&self,
|
|
367
|
-
key: CellKey,
|
|
368
|
-
marks: &mut GarbageCollectionMarks,
|
|
369
|
-
worklist: &mut GarbageCollectionWorklist,
|
|
370
|
-
) {
|
|
371
|
-
if marks.cells.insert(key) {
|
|
372
|
-
worklist.cells.push(key);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
pub(super) fn mark_frame_roots(
|
|
377
|
-
&self,
|
|
378
|
-
frame: &Frame,
|
|
379
|
-
marks: &mut GarbageCollectionMarks,
|
|
380
|
-
worklist: &mut GarbageCollectionWorklist,
|
|
381
|
-
) {
|
|
382
|
-
self.mark_env(frame.env, marks, worklist);
|
|
383
|
-
for env in &frame.scope_stack {
|
|
384
|
-
self.mark_env(*env, marks, worklist);
|
|
385
|
-
}
|
|
386
|
-
for value in &frame.stack {
|
|
387
|
-
self.mark_value(value, marks, worklist);
|
|
388
|
-
}
|
|
389
|
-
if let Some(value) = &frame.pending_exception {
|
|
390
|
-
self.mark_value(value, marks, worklist);
|
|
391
|
-
}
|
|
392
|
-
for handler in &frame.handlers {
|
|
393
|
-
self.mark_env(handler.env, marks, worklist);
|
|
394
|
-
}
|
|
395
|
-
for completion in &frame.pending_completions {
|
|
396
|
-
match completion {
|
|
397
|
-
CompletionRecord::Jump { .. } => {}
|
|
398
|
-
CompletionRecord::Return(value) | CompletionRecord::Throw(value) => {
|
|
399
|
-
self.mark_value(value, marks, worklist);
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if let Some(async_promise) = frame.async_promise {
|
|
404
|
-
self.mark_promise(async_promise, marks, worklist);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
pub(super) fn mark_value(
|
|
409
|
-
&self,
|
|
410
|
-
value: &Value,
|
|
411
|
-
marks: &mut GarbageCollectionMarks,
|
|
412
|
-
worklist: &mut GarbageCollectionWorklist,
|
|
413
|
-
) {
|
|
414
|
-
match value {
|
|
415
|
-
Value::Object(key) => {
|
|
416
|
-
if marks.objects.insert(*key) {
|
|
417
|
-
worklist.objects.push(*key);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
Value::Array(key) => {
|
|
421
|
-
if marks.arrays.insert(*key) {
|
|
422
|
-
worklist.arrays.push(*key);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
Value::Map(key) => {
|
|
426
|
-
if marks.maps.insert(*key) {
|
|
427
|
-
worklist.maps.push(*key);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
Value::Set(key) => {
|
|
431
|
-
if marks.sets.insert(*key) {
|
|
432
|
-
worklist.sets.push(*key);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
Value::Iterator(key) => {
|
|
436
|
-
if marks.iterators.insert(*key) {
|
|
437
|
-
worklist.iterators.push(*key);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
Value::Closure(key) => {
|
|
441
|
-
if marks.closures.insert(*key) {
|
|
442
|
-
worklist.closures.push(*key);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
Value::Promise(key) => self.mark_promise(*key, marks, worklist),
|
|
446
|
-
Value::BuiltinFunction(BuiltinFunction::PromiseResolveFunction(key))
|
|
447
|
-
| Value::BuiltinFunction(BuiltinFunction::PromiseRejectFunction(key)) => {
|
|
448
|
-
self.mark_promise(*key, marks, worklist)
|
|
449
|
-
}
|
|
450
|
-
Value::Undefined
|
|
451
|
-
| Value::Null
|
|
452
|
-
| Value::Bool(_)
|
|
453
|
-
| Value::Number(_)
|
|
454
|
-
| Value::BigInt(_)
|
|
455
|
-
| Value::String(_)
|
|
456
|
-
| Value::BuiltinFunction(_)
|
|
457
|
-
| Value::HostFunction(_) => {}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
pub(super) fn sweep_unreachable_envs(&mut self, marks: &GarbageCollectionMarks) {
|
|
462
|
-
let dead: Vec<_> = self
|
|
463
|
-
.envs
|
|
464
|
-
.keys()
|
|
465
|
-
.filter(|key| !marks.envs.contains(key))
|
|
466
|
-
.collect();
|
|
467
|
-
for key in dead {
|
|
468
|
-
self.envs.remove(key);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
pub(super) fn sweep_unreachable_cells(&mut self, marks: &GarbageCollectionMarks) {
|
|
473
|
-
let dead: Vec<_> = self
|
|
474
|
-
.cells
|
|
475
|
-
.keys()
|
|
476
|
-
.filter(|key| !marks.cells.contains(key))
|
|
477
|
-
.collect();
|
|
478
|
-
for key in dead {
|
|
479
|
-
self.cells.remove(key);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
pub(super) fn sweep_unreachable_objects(&mut self, marks: &GarbageCollectionMarks) {
|
|
484
|
-
let dead: Vec<_> = self
|
|
485
|
-
.objects
|
|
486
|
-
.keys()
|
|
487
|
-
.filter(|key| !marks.objects.contains(key))
|
|
488
|
-
.collect();
|
|
489
|
-
for key in dead {
|
|
490
|
-
self.objects.remove(key);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
pub(super) fn sweep_unreachable_arrays(&mut self, marks: &GarbageCollectionMarks) {
|
|
495
|
-
let dead: Vec<_> = self
|
|
496
|
-
.arrays
|
|
497
|
-
.keys()
|
|
498
|
-
.filter(|key| !marks.arrays.contains(key))
|
|
499
|
-
.collect();
|
|
500
|
-
for key in dead {
|
|
501
|
-
self.arrays.remove(key);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
pub(super) fn sweep_unreachable_maps(&mut self, marks: &GarbageCollectionMarks) {
|
|
506
|
-
let dead: Vec<_> = self
|
|
507
|
-
.maps
|
|
508
|
-
.keys()
|
|
509
|
-
.filter(|key| !marks.maps.contains(key))
|
|
510
|
-
.collect();
|
|
511
|
-
for key in dead {
|
|
512
|
-
self.maps.remove(key);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
pub(super) fn sweep_unreachable_sets(&mut self, marks: &GarbageCollectionMarks) {
|
|
517
|
-
let dead: Vec<_> = self
|
|
518
|
-
.sets
|
|
519
|
-
.keys()
|
|
520
|
-
.filter(|key| !marks.sets.contains(key))
|
|
521
|
-
.collect();
|
|
522
|
-
for key in dead {
|
|
523
|
-
self.sets.remove(key);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
pub(super) fn sweep_unreachable_iterators(&mut self, marks: &GarbageCollectionMarks) {
|
|
528
|
-
let dead: Vec<_> = self
|
|
529
|
-
.iterators
|
|
530
|
-
.keys()
|
|
531
|
-
.filter(|key| !marks.iterators.contains(key))
|
|
532
|
-
.collect();
|
|
533
|
-
for key in dead {
|
|
534
|
-
self.iterators.remove(key);
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
pub(super) fn sweep_unreachable_closures(&mut self, marks: &GarbageCollectionMarks) {
|
|
539
|
-
let dead: Vec<_> = self
|
|
540
|
-
.closures
|
|
541
|
-
.keys()
|
|
542
|
-
.filter(|key| !marks.closures.contains(key))
|
|
543
|
-
.collect();
|
|
544
|
-
for key in dead {
|
|
545
|
-
self.closures.remove(key);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
pub(super) fn sweep_unreachable_promises(&mut self, marks: &GarbageCollectionMarks) {
|
|
550
|
-
let dead: Vec<_> = self
|
|
551
|
-
.promises
|
|
552
|
-
.keys()
|
|
553
|
-
.filter(|key| !marks.promises.contains(key))
|
|
554
|
-
.collect();
|
|
555
|
-
for key in dead {
|
|
556
|
-
self.promises.remove(key);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
pub(super) fn mark_promise(
|
|
561
|
-
&self,
|
|
562
|
-
key: PromiseKey,
|
|
563
|
-
marks: &mut GarbageCollectionMarks,
|
|
564
|
-
worklist: &mut GarbageCollectionWorklist,
|
|
565
|
-
) {
|
|
566
|
-
if marks.promises.insert(key) {
|
|
567
|
-
worklist.promises.push(key);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
fn instruction_may_allocate(instruction: &Instruction) -> bool {
|
|
573
|
-
matches!(
|
|
574
|
-
instruction,
|
|
575
|
-
Instruction::StoreName(_)
|
|
576
|
-
| Instruction::InitializePattern(_)
|
|
577
|
-
| Instruction::PushEnv
|
|
578
|
-
| Instruction::DeclareName { .. }
|
|
579
|
-
| Instruction::MakeClosure { .. }
|
|
580
|
-
| Instruction::MakeArray { .. }
|
|
581
|
-
| Instruction::ArrayPush
|
|
582
|
-
| Instruction::ArrayPushHole
|
|
583
|
-
| Instruction::ArrayExtend
|
|
584
|
-
| Instruction::MakeObject { .. }
|
|
585
|
-
| Instruction::CopyDataProperties
|
|
586
|
-
| Instruction::CreateIterator
|
|
587
|
-
| Instruction::SetPropStatic { .. }
|
|
588
|
-
| Instruction::SetPropComputed
|
|
589
|
-
| Instruction::Call { .. }
|
|
590
|
-
| Instruction::CallWithArray { .. }
|
|
591
|
-
| Instruction::Await
|
|
592
|
-
| Instruction::Construct { .. }
|
|
593
|
-
| Instruction::ConstructWithArray
|
|
594
|
-
)
|
|
595
|
-
}
|