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.
Files changed (96) hide show
  1. package/README.md +62 -20
  2. package/SECURITY.md +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/lib/executor.js +16 -1
  5. package/dist/lib/policy.js +301 -22
  6. package/dist/lib/progress.js +499 -113
  7. package/dist/lib/runtime.js +109 -40
  8. package/dist/lib/structured.js +327 -11
  9. package/dist/native-loader.js +11 -12
  10. package/index.d.ts +54 -6
  11. package/mustard.d.ts +23 -1
  12. package/package.json +34 -25
  13. package/Cargo.lock +0 -1579
  14. package/Cargo.toml +0 -40
  15. package/crates/mustard/Cargo.toml +0 -31
  16. package/crates/mustard/src/cancellation.rs +0 -28
  17. package/crates/mustard/src/diagnostic.rs +0 -145
  18. package/crates/mustard/src/ir.rs +0 -435
  19. package/crates/mustard/src/lib.rs +0 -21
  20. package/crates/mustard/src/limits.rs +0 -22
  21. package/crates/mustard/src/parser/expressions.rs +0 -723
  22. package/crates/mustard/src/parser/mod.rs +0 -115
  23. package/crates/mustard/src/parser/operators.rs +0 -105
  24. package/crates/mustard/src/parser/patterns.rs +0 -123
  25. package/crates/mustard/src/parser/scope.rs +0 -107
  26. package/crates/mustard/src/parser/statements.rs +0 -298
  27. package/crates/mustard/src/parser/tests/acceptance.rs +0 -339
  28. package/crates/mustard/src/parser/tests/mod.rs +0 -2
  29. package/crates/mustard/src/parser/tests/rejections.rs +0 -107
  30. package/crates/mustard/src/runtime/accounting.rs +0 -613
  31. package/crates/mustard/src/runtime/api.rs +0 -192
  32. package/crates/mustard/src/runtime/async_runtime/mod.rs +0 -5
  33. package/crates/mustard/src/runtime/async_runtime/promises.rs +0 -246
  34. package/crates/mustard/src/runtime/async_runtime/reactions.rs +0 -400
  35. package/crates/mustard/src/runtime/async_runtime/scheduler.rs +0 -224
  36. package/crates/mustard/src/runtime/builtins/arrays.rs +0 -1205
  37. package/crates/mustard/src/runtime/builtins/collections.rs +0 -573
  38. package/crates/mustard/src/runtime/builtins/install.rs +0 -501
  39. package/crates/mustard/src/runtime/builtins/intl.rs +0 -553
  40. package/crates/mustard/src/runtime/builtins/mod.rs +0 -25
  41. package/crates/mustard/src/runtime/builtins/objects.rs +0 -405
  42. package/crates/mustard/src/runtime/builtins/primitives.rs +0 -859
  43. package/crates/mustard/src/runtime/builtins/promises.rs +0 -335
  44. package/crates/mustard/src/runtime/builtins/regexp.rs +0 -356
  45. package/crates/mustard/src/runtime/builtins/strings.rs +0 -803
  46. package/crates/mustard/src/runtime/builtins/support.rs +0 -561
  47. package/crates/mustard/src/runtime/bytecode.rs +0 -123
  48. package/crates/mustard/src/runtime/compiler/assignments.rs +0 -690
  49. package/crates/mustard/src/runtime/compiler/bindings.rs +0 -92
  50. package/crates/mustard/src/runtime/compiler/context.rs +0 -46
  51. package/crates/mustard/src/runtime/compiler/control.rs +0 -342
  52. package/crates/mustard/src/runtime/compiler/expressions.rs +0 -372
  53. package/crates/mustard/src/runtime/compiler/mod.rs +0 -173
  54. package/crates/mustard/src/runtime/compiler/statements.rs +0 -459
  55. package/crates/mustard/src/runtime/conversions/boundary.rs +0 -293
  56. package/crates/mustard/src/runtime/conversions/coercions.rs +0 -217
  57. package/crates/mustard/src/runtime/conversions/errors.rs +0 -118
  58. package/crates/mustard/src/runtime/conversions/mod.rs +0 -14
  59. package/crates/mustard/src/runtime/conversions/operators.rs +0 -334
  60. package/crates/mustard/src/runtime/env.rs +0 -355
  61. package/crates/mustard/src/runtime/exceptions.rs +0 -377
  62. package/crates/mustard/src/runtime/gc.rs +0 -595
  63. package/crates/mustard/src/runtime/mod.rs +0 -318
  64. package/crates/mustard/src/runtime/properties.rs +0 -1762
  65. package/crates/mustard/src/runtime/serialization.rs +0 -127
  66. package/crates/mustard/src/runtime/shared.rs +0 -108
  67. package/crates/mustard/src/runtime/snapshot_validation_tests.rs +0 -93
  68. package/crates/mustard/src/runtime/state.rs +0 -652
  69. package/crates/mustard/src/runtime/tests/async_host.rs +0 -104
  70. package/crates/mustard/src/runtime/tests/collections.rs +0 -50
  71. package/crates/mustard/src/runtime/tests/diagnostics.rs +0 -36
  72. package/crates/mustard/src/runtime/tests/exceptions.rs +0 -122
  73. package/crates/mustard/src/runtime/tests/execution.rs +0 -553
  74. package/crates/mustard/src/runtime/tests/gc.rs +0 -533
  75. package/crates/mustard/src/runtime/tests/mod.rs +0 -56
  76. package/crates/mustard/src/runtime/tests/serialization.rs +0 -170
  77. package/crates/mustard/src/runtime/validation/bytecode.rs +0 -484
  78. package/crates/mustard/src/runtime/validation/mod.rs +0 -14
  79. package/crates/mustard/src/runtime/validation/policy.rs +0 -94
  80. package/crates/mustard/src/runtime/validation/snapshot.rs +0 -406
  81. package/crates/mustard/src/runtime/validation/walk.rs +0 -206
  82. package/crates/mustard/src/runtime/vm.rs +0 -1016
  83. package/crates/mustard/src/span.rs +0 -22
  84. package/crates/mustard/src/structured.rs +0 -107
  85. package/crates/mustard-bridge/Cargo.toml +0 -17
  86. package/crates/mustard-bridge/src/codec.rs +0 -46
  87. package/crates/mustard-bridge/src/dto.rs +0 -99
  88. package/crates/mustard-bridge/src/lib.rs +0 -12
  89. package/crates/mustard-bridge/src/operations.rs +0 -142
  90. package/crates/mustard-node/Cargo.toml +0 -24
  91. package/crates/mustard-node/build.rs +0 -3
  92. package/crates/mustard-node/src/lib.rs +0 -236
  93. package/crates/mustard-sidecar/Cargo.toml +0 -21
  94. package/crates/mustard-sidecar/src/lib.rs +0 -134
  95. package/crates/mustard-sidecar/src/main.rs +0 -36
  96. package/dist/install.js +0 -117
@@ -1,613 +0,0 @@
1
- use super::*;
2
-
3
- impl Runtime {
4
- pub(super) fn ensure_heap_capacity(&self, additional_bytes: usize) -> MustardResult<()> {
5
- let next = self
6
- .heap_bytes_used
7
- .checked_add(additional_bytes)
8
- .ok_or_else(|| limit_error("heap limit exceeded"))?;
9
- if next > self.limits.heap_limit_bytes {
10
- return Err(limit_error("heap limit exceeded"));
11
- }
12
- Ok(())
13
- }
14
-
15
- pub(super) fn account_new_allocation(&mut self, bytes: usize) -> MustardResult<()> {
16
- let next_allocations = self
17
- .allocation_count
18
- .checked_add(1)
19
- .ok_or_else(|| limit_error("allocation budget exhausted"))?;
20
- if next_allocations > self.limits.allocation_budget {
21
- return Err(limit_error("allocation budget exhausted"));
22
- }
23
- self.ensure_heap_capacity(bytes)?;
24
- self.allocation_count = next_allocations;
25
- self.heap_bytes_used += bytes;
26
- Ok(())
27
- }
28
-
29
- pub(super) fn apply_heap_delta(
30
- &mut self,
31
- old_bytes: usize,
32
- new_bytes: usize,
33
- ) -> MustardResult<()> {
34
- if new_bytes >= old_bytes {
35
- self.ensure_heap_capacity(new_bytes - old_bytes)?;
36
- self.heap_bytes_used += new_bytes - old_bytes;
37
- } else {
38
- self.heap_bytes_used -= old_bytes - new_bytes;
39
- }
40
- Ok(())
41
- }
42
-
43
- pub(super) fn insert_env(&mut self, parent: Option<EnvKey>) -> MustardResult<EnvKey> {
44
- let mut env = Env {
45
- parent,
46
- bindings: IndexMap::new(),
47
- accounted_bytes: 0,
48
- };
49
- env.accounted_bytes = measure_env_bytes(&env);
50
- self.account_new_allocation(env.accounted_bytes)?;
51
- Ok(self.envs.insert(env))
52
- }
53
-
54
- pub(super) fn insert_cell(
55
- &mut self,
56
- value: Value,
57
- mutable: bool,
58
- initialized: bool,
59
- ) -> MustardResult<CellKey> {
60
- let mut cell = Cell {
61
- value,
62
- mutable,
63
- initialized,
64
- accounted_bytes: 0,
65
- };
66
- cell.accounted_bytes = measure_cell_bytes(&cell);
67
- self.account_new_allocation(cell.accounted_bytes)?;
68
- Ok(self.cells.insert(cell))
69
- }
70
-
71
- pub(super) fn insert_object(
72
- &mut self,
73
- properties: IndexMap<String, Value>,
74
- kind: ObjectKind,
75
- ) -> MustardResult<ObjectKey> {
76
- let mut object = PlainObject {
77
- properties,
78
- kind,
79
- accounted_bytes: 0,
80
- };
81
- object.accounted_bytes = measure_object_bytes(&object);
82
- self.account_new_allocation(object.accounted_bytes)?;
83
- Ok(self.objects.insert(object))
84
- }
85
-
86
- pub(super) fn insert_array(
87
- &mut self,
88
- elements: Vec<Value>,
89
- properties: IndexMap<String, Value>,
90
- ) -> MustardResult<ArrayKey> {
91
- self.insert_sparse_array(elements.into_iter().map(Some).collect(), properties)
92
- }
93
-
94
- pub(super) fn insert_sparse_array(
95
- &mut self,
96
- elements: Vec<Option<Value>>,
97
- properties: IndexMap<String, Value>,
98
- ) -> MustardResult<ArrayKey> {
99
- let mut array = ArrayObject {
100
- elements,
101
- properties,
102
- accounted_bytes: 0,
103
- };
104
- array.accounted_bytes = measure_array_bytes(&array);
105
- self.account_new_allocation(array.accounted_bytes)?;
106
- Ok(self.arrays.insert(array))
107
- }
108
-
109
- pub(super) fn insert_map(&mut self, entries: Vec<MapEntry>) -> MustardResult<MapKey> {
110
- let mut map = MapObject {
111
- entries,
112
- accounted_bytes: 0,
113
- };
114
- map.accounted_bytes = measure_map_bytes(&map);
115
- self.account_new_allocation(map.accounted_bytes)?;
116
- Ok(self.maps.insert(map))
117
- }
118
-
119
- pub(super) fn insert_set(&mut self, entries: Vec<Value>) -> MustardResult<SetKey> {
120
- let mut set = SetObject {
121
- entries,
122
- accounted_bytes: 0,
123
- };
124
- set.accounted_bytes = measure_set_bytes(&set);
125
- self.account_new_allocation(set.accounted_bytes)?;
126
- Ok(self.sets.insert(set))
127
- }
128
-
129
- pub(super) fn insert_iterator(&mut self, state: IteratorState) -> MustardResult<IteratorKey> {
130
- let mut iterator = IteratorObject {
131
- state,
132
- accounted_bytes: 0,
133
- };
134
- iterator.accounted_bytes = measure_iterator_bytes(&iterator);
135
- self.account_new_allocation(iterator.accounted_bytes)?;
136
- Ok(self.iterators.insert(iterator))
137
- }
138
-
139
- pub(super) fn insert_closure(
140
- &mut self,
141
- function_id: usize,
142
- env: EnvKey,
143
- this_value: Value,
144
- ) -> MustardResult<ClosureKey> {
145
- let mut closure = Closure {
146
- function_id,
147
- env,
148
- name: self
149
- .program
150
- .functions
151
- .get(function_id)
152
- .and_then(|function| function.name.clone()),
153
- this_value,
154
- prototype: None,
155
- properties: IndexMap::new(),
156
- accounted_bytes: 0,
157
- };
158
- closure.accounted_bytes = measure_closure_bytes(&closure);
159
- self.account_new_allocation(closure.accounted_bytes)?;
160
- let key = self.closures.insert(closure);
161
- let is_arrow = self
162
- .program
163
- .functions
164
- .get(function_id)
165
- .map(|function| function.is_arrow)
166
- .ok_or_else(|| MustardError::runtime("function not found"))?;
167
- if !is_arrow {
168
- let prototype = self.insert_object(
169
- IndexMap::new(),
170
- ObjectKind::FunctionPrototype(Value::Closure(key)),
171
- )?;
172
- self.closures
173
- .get_mut(key)
174
- .ok_or_else(|| MustardError::runtime("closure missing"))?
175
- .prototype = Some(prototype);
176
- self.refresh_closure_accounting(key)?;
177
- }
178
- Ok(key)
179
- }
180
-
181
- pub(super) fn insert_promise(&mut self, state: PromiseState) -> MustardResult<PromiseKey> {
182
- let mut promise = PromiseObject {
183
- state,
184
- awaiters: Vec::new(),
185
- dependents: Vec::new(),
186
- reactions: Vec::new(),
187
- driver: None,
188
- accounted_bytes: 0,
189
- };
190
- promise.accounted_bytes = measure_promise_bytes(&promise);
191
- self.account_new_allocation(promise.accounted_bytes)?;
192
- Ok(self.promises.insert(promise))
193
- }
194
-
195
- pub(super) fn account_existing_env(&mut self, key: EnvKey) -> MustardResult<()> {
196
- let bytes = {
197
- let env = self
198
- .envs
199
- .get(key)
200
- .ok_or_else(|| MustardError::runtime("environment missing"))?;
201
- measure_env_bytes(env)
202
- };
203
- self.account_new_allocation(bytes)?;
204
- self.envs
205
- .get_mut(key)
206
- .ok_or_else(|| MustardError::runtime("environment missing"))?
207
- .accounted_bytes = bytes;
208
- Ok(())
209
- }
210
-
211
- pub(super) fn refresh_env_accounting(&mut self, key: EnvKey) -> MustardResult<()> {
212
- let (old_bytes, new_bytes) = {
213
- let env = self
214
- .envs
215
- .get(key)
216
- .ok_or_else(|| MustardError::runtime("environment missing"))?;
217
- (env.accounted_bytes, measure_env_bytes(env))
218
- };
219
- self.apply_heap_delta(old_bytes, new_bytes)?;
220
- self.envs
221
- .get_mut(key)
222
- .ok_or_else(|| MustardError::runtime("environment missing"))?
223
- .accounted_bytes = new_bytes;
224
- Ok(())
225
- }
226
-
227
- pub(super) fn refresh_cell_accounting(&mut self, key: CellKey) -> MustardResult<()> {
228
- let (old_bytes, new_bytes) = {
229
- let cell = self
230
- .cells
231
- .get(key)
232
- .ok_or_else(|| MustardError::runtime("binding cell missing"))?;
233
- (cell.accounted_bytes, measure_cell_bytes(cell))
234
- };
235
- self.apply_heap_delta(old_bytes, new_bytes)?;
236
- self.cells
237
- .get_mut(key)
238
- .ok_or_else(|| MustardError::runtime("binding cell missing"))?
239
- .accounted_bytes = new_bytes;
240
- Ok(())
241
- }
242
-
243
- pub(super) fn refresh_object_accounting(&mut self, key: ObjectKey) -> MustardResult<()> {
244
- let (old_bytes, new_bytes) = {
245
- let object = self
246
- .objects
247
- .get(key)
248
- .ok_or_else(|| MustardError::runtime("object missing"))?;
249
- (object.accounted_bytes, measure_object_bytes(object))
250
- };
251
- self.apply_heap_delta(old_bytes, new_bytes)?;
252
- self.objects
253
- .get_mut(key)
254
- .ok_or_else(|| MustardError::runtime("object missing"))?
255
- .accounted_bytes = new_bytes;
256
- Ok(())
257
- }
258
-
259
- pub(super) fn refresh_array_accounting(&mut self, key: ArrayKey) -> MustardResult<()> {
260
- let (old_bytes, new_bytes) = {
261
- let array = self
262
- .arrays
263
- .get(key)
264
- .ok_or_else(|| MustardError::runtime("array missing"))?;
265
- (array.accounted_bytes, measure_array_bytes(array))
266
- };
267
- self.apply_heap_delta(old_bytes, new_bytes)?;
268
- self.arrays
269
- .get_mut(key)
270
- .ok_or_else(|| MustardError::runtime("array missing"))?
271
- .accounted_bytes = new_bytes;
272
- Ok(())
273
- }
274
-
275
- pub(super) fn refresh_map_accounting(&mut self, key: MapKey) -> MustardResult<()> {
276
- let (old_bytes, new_bytes) = {
277
- let map = self
278
- .maps
279
- .get(key)
280
- .ok_or_else(|| MustardError::runtime("map missing"))?;
281
- (map.accounted_bytes, measure_map_bytes(map))
282
- };
283
- self.apply_heap_delta(old_bytes, new_bytes)?;
284
- self.maps
285
- .get_mut(key)
286
- .ok_or_else(|| MustardError::runtime("map missing"))?
287
- .accounted_bytes = new_bytes;
288
- Ok(())
289
- }
290
-
291
- pub(super) fn refresh_set_accounting(&mut self, key: SetKey) -> MustardResult<()> {
292
- let (old_bytes, new_bytes) = {
293
- let set = self
294
- .sets
295
- .get(key)
296
- .ok_or_else(|| MustardError::runtime("set missing"))?;
297
- (set.accounted_bytes, measure_set_bytes(set))
298
- };
299
- self.apply_heap_delta(old_bytes, new_bytes)?;
300
- self.sets
301
- .get_mut(key)
302
- .ok_or_else(|| MustardError::runtime("set missing"))?
303
- .accounted_bytes = new_bytes;
304
- Ok(())
305
- }
306
-
307
- pub(super) fn refresh_iterator_accounting(&mut self, key: IteratorKey) -> MustardResult<()> {
308
- let (old_bytes, new_bytes) = {
309
- let iterator = self
310
- .iterators
311
- .get(key)
312
- .ok_or_else(|| MustardError::runtime("iterator missing"))?;
313
- (iterator.accounted_bytes, measure_iterator_bytes(iterator))
314
- };
315
- self.apply_heap_delta(old_bytes, new_bytes)?;
316
- self.iterators
317
- .get_mut(key)
318
- .ok_or_else(|| MustardError::runtime("iterator missing"))?
319
- .accounted_bytes = new_bytes;
320
- Ok(())
321
- }
322
-
323
- pub(super) fn refresh_closure_accounting(&mut self, key: ClosureKey) -> MustardResult<()> {
324
- let (old_bytes, new_bytes) = {
325
- let closure = self
326
- .closures
327
- .get(key)
328
- .ok_or_else(|| MustardError::runtime("closure missing"))?;
329
- (closure.accounted_bytes, measure_closure_bytes(closure))
330
- };
331
- self.apply_heap_delta(old_bytes, new_bytes)?;
332
- self.closures
333
- .get_mut(key)
334
- .ok_or_else(|| MustardError::runtime("closure missing"))?
335
- .accounted_bytes = new_bytes;
336
- Ok(())
337
- }
338
-
339
- pub(super) fn recompute_accounting_after_load(&mut self) -> MustardResult<()> {
340
- let (heap_bytes_used, allocation_count) =
341
- self.recompute_accounting_totals().map_err(|message| {
342
- serialization_error(format!("snapshot validation failed: {message}"))
343
- })?;
344
-
345
- if heap_bytes_used > self.limits.heap_limit_bytes {
346
- return Err(serialization_error(
347
- "snapshot validation failed: heap usage exceeds configured heap limit",
348
- ));
349
- }
350
- if allocation_count > self.limits.allocation_budget {
351
- return Err(serialization_error(
352
- "snapshot validation failed: allocation count exceeds configured allocation budget",
353
- ));
354
- }
355
-
356
- self.heap_bytes_used = heap_bytes_used;
357
- self.allocation_count = allocation_count;
358
- Ok(())
359
- }
360
-
361
- pub(super) fn refresh_promise_accounting(&mut self, key: PromiseKey) -> MustardResult<()> {
362
- let (old_bytes, new_bytes) = {
363
- let promise = self
364
- .promises
365
- .get(key)
366
- .ok_or_else(|| MustardError::runtime("promise missing"))?;
367
- (promise.accounted_bytes, measure_promise_bytes(promise))
368
- };
369
- self.apply_heap_delta(old_bytes, new_bytes)?;
370
- self.promises
371
- .get_mut(key)
372
- .ok_or_else(|| MustardError::runtime("promise missing"))?
373
- .accounted_bytes = new_bytes;
374
- Ok(())
375
- }
376
-
377
- pub(super) fn recompute_accounting_totals(&mut self) -> Result<(usize, usize), String> {
378
- let mut heap_bytes_used = 0usize;
379
- let mut allocation_count = 0usize;
380
-
381
- for env in self.envs.values_mut() {
382
- env.accounted_bytes = measure_env_bytes(env);
383
- heap_bytes_used = heap_bytes_used
384
- .checked_add(env.accounted_bytes)
385
- .ok_or_else(|| "heap accounting overflow".to_string())?;
386
- allocation_count += 1;
387
- }
388
- for cell in self.cells.values_mut() {
389
- cell.accounted_bytes = measure_cell_bytes(cell);
390
- heap_bytes_used = heap_bytes_used
391
- .checked_add(cell.accounted_bytes)
392
- .ok_or_else(|| "heap accounting overflow".to_string())?;
393
- allocation_count += 1;
394
- }
395
- for object in self.objects.values_mut() {
396
- object.accounted_bytes = measure_object_bytes(object);
397
- heap_bytes_used = heap_bytes_used
398
- .checked_add(object.accounted_bytes)
399
- .ok_or_else(|| "heap accounting overflow".to_string())?;
400
- allocation_count += 1;
401
- }
402
- for array in self.arrays.values_mut() {
403
- array.accounted_bytes = measure_array_bytes(array);
404
- heap_bytes_used = heap_bytes_used
405
- .checked_add(array.accounted_bytes)
406
- .ok_or_else(|| "heap accounting overflow".to_string())?;
407
- allocation_count += 1;
408
- }
409
- for map in self.maps.values_mut() {
410
- map.accounted_bytes = measure_map_bytes(map);
411
- heap_bytes_used = heap_bytes_used
412
- .checked_add(map.accounted_bytes)
413
- .ok_or_else(|| "heap accounting overflow".to_string())?;
414
- allocation_count += 1;
415
- }
416
- for set in self.sets.values_mut() {
417
- set.accounted_bytes = measure_set_bytes(set);
418
- heap_bytes_used = heap_bytes_used
419
- .checked_add(set.accounted_bytes)
420
- .ok_or_else(|| "heap accounting overflow".to_string())?;
421
- allocation_count += 1;
422
- }
423
- for iterator in self.iterators.values_mut() {
424
- iterator.accounted_bytes = measure_iterator_bytes(iterator);
425
- heap_bytes_used = heap_bytes_used
426
- .checked_add(iterator.accounted_bytes)
427
- .ok_or_else(|| "heap accounting overflow".to_string())?;
428
- allocation_count += 1;
429
- }
430
- for closure in self.closures.values_mut() {
431
- closure.accounted_bytes = measure_closure_bytes(closure);
432
- heap_bytes_used = heap_bytes_used
433
- .checked_add(closure.accounted_bytes)
434
- .ok_or_else(|| "heap accounting overflow".to_string())?;
435
- allocation_count += 1;
436
- }
437
- for promise in self.promises.values_mut() {
438
- promise.accounted_bytes = measure_promise_bytes(promise);
439
- heap_bytes_used = heap_bytes_used
440
- .checked_add(promise.accounted_bytes)
441
- .ok_or_else(|| "heap accounting overflow".to_string())?;
442
- allocation_count += 1;
443
- }
444
-
445
- Ok((heap_bytes_used, allocation_count))
446
- }
447
- }
448
-
449
- fn extra_value_bytes(value: &Value) -> usize {
450
- match value {
451
- Value::String(value) | Value::HostFunction(value) => value.len(),
452
- Value::BigInt(value) => value.to_signed_bytes_le().len(),
453
- _ => 0,
454
- }
455
- }
456
-
457
- fn measure_bindings_bytes(bindings: &IndexMap<String, CellKey>) -> usize {
458
- bindings.len() * std::mem::size_of::<(String, CellKey)>()
459
- + bindings.keys().map(|key| key.len()).sum::<usize>()
460
- }
461
-
462
- fn measure_properties_bytes(properties: &IndexMap<String, Value>) -> usize {
463
- properties.len() * std::mem::size_of::<(String, Value)>()
464
- + properties
465
- .iter()
466
- .map(|(key, value)| key.len() + extra_value_bytes(value))
467
- .sum::<usize>()
468
- }
469
-
470
- fn measure_env_bytes(env: &Env) -> usize {
471
- std::mem::size_of::<Env>() + measure_bindings_bytes(&env.bindings)
472
- }
473
-
474
- fn measure_cell_bytes(cell: &Cell) -> usize {
475
- std::mem::size_of::<Cell>() + extra_value_bytes(&cell.value)
476
- }
477
-
478
- fn measure_object_bytes(object: &PlainObject) -> usize {
479
- std::mem::size_of::<PlainObject>()
480
- + measure_properties_bytes(&object.properties)
481
- + match &object.kind {
482
- ObjectKind::FunctionPrototype(constructor) => extra_value_bytes(constructor),
483
- ObjectKind::BoundFunction(bound) => {
484
- extra_value_bytes(&bound.target)
485
- + extra_value_bytes(&bound.this_value)
486
- + bound.args.iter().map(extra_value_bytes).sum::<usize>()
487
- }
488
- ObjectKind::Error(name) => name.len(),
489
- ObjectKind::RegExp(regex) => regex.pattern.len() + regex.flags.len(),
490
- ObjectKind::StringObject(value) => value.len(),
491
- _ => 0,
492
- }
493
- }
494
-
495
- fn measure_array_bytes(array: &ArrayObject) -> usize {
496
- std::mem::size_of::<ArrayObject>()
497
- + array.elements.len() * std::mem::size_of::<Option<Value>>()
498
- + array
499
- .elements
500
- .iter()
501
- .filter_map(Option::as_ref)
502
- .map(extra_value_bytes)
503
- .sum::<usize>()
504
- + measure_properties_bytes(&array.properties)
505
- }
506
-
507
- fn measure_map_bytes(map: &MapObject) -> usize {
508
- std::mem::size_of::<MapObject>()
509
- + map.entries.len() * std::mem::size_of::<MapEntry>()
510
- + map
511
- .entries
512
- .iter()
513
- .map(|entry| extra_value_bytes(&entry.key) + extra_value_bytes(&entry.value))
514
- .sum::<usize>()
515
- }
516
-
517
- fn measure_set_bytes(set: &SetObject) -> usize {
518
- std::mem::size_of::<SetObject>()
519
- + set.entries.len() * std::mem::size_of::<Value>()
520
- + set.entries.iter().map(extra_value_bytes).sum::<usize>()
521
- }
522
-
523
- fn measure_iterator_bytes(iterator: &IteratorObject) -> usize {
524
- let state_bytes = match &iterator.state {
525
- IteratorState::String(state) => state.value.len(),
526
- IteratorState::Array(_)
527
- | IteratorState::ArrayKeys(_)
528
- | IteratorState::ArrayEntries(_)
529
- | IteratorState::MapEntries(_)
530
- | IteratorState::MapKeys(_)
531
- | IteratorState::MapValues(_)
532
- | IteratorState::SetEntries(_)
533
- | IteratorState::SetValues(_) => 0,
534
- };
535
- std::mem::size_of::<IteratorObject>() + state_bytes
536
- }
537
-
538
- fn measure_closure_bytes(closure: &Closure) -> usize {
539
- std::mem::size_of::<Closure>()
540
- + closure.name.as_ref().map_or(0, String::len)
541
- + extra_value_bytes(&closure.this_value)
542
- + measure_properties_bytes(&closure.properties)
543
- }
544
-
545
- fn measure_promise_bytes(promise: &PromiseObject) -> usize {
546
- let state_bytes = match &promise.state {
547
- PromiseState::Pending => 0,
548
- PromiseState::Fulfilled(value) => extra_value_bytes(value),
549
- PromiseState::Rejected(rejection) => {
550
- extra_value_bytes(&rejection.value)
551
- + rejection
552
- .traceback
553
- .iter()
554
- .map(|frame| frame.function_name.as_ref().map_or(0, String::len))
555
- .sum::<usize>()
556
- }
557
- };
558
- let reaction_bytes = promise
559
- .reactions
560
- .iter()
561
- .map(|reaction| match reaction {
562
- PromiseReaction::Then {
563
- on_fulfilled,
564
- on_rejected,
565
- ..
566
- } => on_fulfilled
567
- .iter()
568
- .chain(on_rejected.iter())
569
- .map(extra_value_bytes)
570
- .sum::<usize>(),
571
- PromiseReaction::Finally { callback, .. } => {
572
- callback.iter().map(extra_value_bytes).sum::<usize>()
573
- }
574
- PromiseReaction::FinallyPassThrough {
575
- original_outcome, ..
576
- } => match original_outcome {
577
- PromiseOutcome::Fulfilled(value) => extra_value_bytes(value),
578
- PromiseOutcome::Rejected(rejection) => extra_value_bytes(&rejection.value),
579
- },
580
- PromiseReaction::Combinator { .. } => 0,
581
- })
582
- .sum::<usize>();
583
- let driver_bytes = match &promise.driver {
584
- Some(PromiseDriver::Thenable { value }) => extra_value_bytes(value),
585
- Some(PromiseDriver::All { values, .. }) => values
586
- .iter()
587
- .flatten()
588
- .map(extra_value_bytes)
589
- .sum::<usize>(),
590
- Some(PromiseDriver::AllSettled { results, .. }) => results
591
- .iter()
592
- .flatten()
593
- .map(|result| match result {
594
- PromiseSettledResult::Fulfilled(value) | PromiseSettledResult::Rejected(value) => {
595
- extra_value_bytes(value)
596
- }
597
- })
598
- .sum::<usize>(),
599
- Some(PromiseDriver::Any { reasons, .. }) => reasons
600
- .iter()
601
- .flatten()
602
- .map(extra_value_bytes)
603
- .sum::<usize>(),
604
- None => 0,
605
- };
606
- std::mem::size_of::<PromiseObject>()
607
- + promise.awaiters.len() * std::mem::size_of::<AsyncContinuation>()
608
- + promise.dependents.len() * std::mem::size_of::<PromiseKey>()
609
- + promise.reactions.len() * std::mem::size_of::<PromiseReaction>()
610
- + state_bytes
611
- + reaction_bytes
612
- + driver_bytes
613
- }