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,400 +0,0 @@
1
- use super::*;
2
-
3
- impl Runtime {
4
- fn promise_combinator_slot_len(
5
- promise: &PromiseObject,
6
- kind: PromiseCombinatorKind,
7
- ) -> MustardResult<Option<usize>> {
8
- match (kind, promise.driver.as_ref()) {
9
- (PromiseCombinatorKind::Race, _) => Ok(None),
10
- (PromiseCombinatorKind::All, Some(PromiseDriver::All { values, .. })) => {
11
- Ok(Some(values.len()))
12
- }
13
- (
14
- PromiseCombinatorKind::AllSettled,
15
- Some(PromiseDriver::AllSettled { results, .. }),
16
- ) => Ok(Some(results.len())),
17
- (PromiseCombinatorKind::Any, Some(PromiseDriver::Any { reasons, .. })) => {
18
- Ok(Some(reasons.len()))
19
- }
20
- (_, Some(_)) => Err(MustardError::runtime("promise combinator kind mismatch")),
21
- (_, None) => Err(MustardError::runtime("promise combinator state missing")),
22
- }
23
- }
24
-
25
- pub(in crate::runtime) fn promise_reaction_target(
26
- &self,
27
- reaction: &PromiseReaction,
28
- ) -> PromiseKey {
29
- match reaction {
30
- PromiseReaction::Then { target, .. }
31
- | PromiseReaction::Finally { target, .. }
32
- | PromiseReaction::FinallyPassThrough { target, .. }
33
- | PromiseReaction::Combinator { target, .. } => *target,
34
- }
35
- }
36
-
37
- pub(in crate::runtime) fn invoke_promise_handler(
38
- &mut self,
39
- handler: Value,
40
- args: &[Value],
41
- target: PromiseKey,
42
- ) -> MustardResult<()> {
43
- match handler {
44
- Value::Closure(closure) => {
45
- let closure = self
46
- .closures
47
- .get(closure)
48
- .cloned()
49
- .ok_or_else(|| MustardError::runtime("closure not found"))?;
50
- let env = self.new_env(Some(closure.env))?;
51
- let (is_async, function_id) = self
52
- .program
53
- .functions
54
- .get(closure.function_id)
55
- .map(|function| (function.is_async, closure.function_id))
56
- .ok_or_else(|| MustardError::runtime("function not found"))?;
57
- if is_async {
58
- let bridge = self.insert_promise(PromiseState::Pending)?;
59
- self.attach_dependent(bridge, target)?;
60
- self.push_frame(function_id, env, args, Value::Undefined, Some(bridge))?;
61
- } else {
62
- self.push_frame(function_id, env, args, Value::Undefined, Some(target))?;
63
- }
64
- Ok(())
65
- }
66
- Value::BuiltinFunction(function)
67
- if matches!(
68
- function,
69
- BuiltinFunction::FunctionCall
70
- | BuiltinFunction::FunctionApply
71
- | BuiltinFunction::FunctionBind
72
- ) =>
73
- {
74
- match self.call_callable(
75
- Value::BuiltinFunction(function),
76
- Value::Undefined,
77
- args,
78
- )? {
79
- RunState::Completed(value) => self.resolve_promise(target, value),
80
- RunState::PushedFrame => Ok(()),
81
- RunState::StartedAsync(value) => {
82
- let promise = self.coerce_to_promise(value)?;
83
- self.attach_dependent(promise, target)
84
- }
85
- RunState::Suspended { .. } => Err(MustardError::runtime(
86
- "promise reactions do not support synchronous host suspensions",
87
- )),
88
- }
89
- }
90
- Value::BuiltinFunction(function) => {
91
- let value = self.call_builtin(function, Value::Undefined, args)?;
92
- self.resolve_promise(target, value)
93
- }
94
- Value::Object(object)
95
- if self
96
- .objects
97
- .get(object)
98
- .is_some_and(|object| matches!(object.kind, ObjectKind::BoundFunction(_))) =>
99
- {
100
- match self.call_callable(Value::Object(object), Value::Undefined, args)? {
101
- RunState::Completed(value) => self.resolve_promise(target, value),
102
- RunState::PushedFrame => Ok(()),
103
- RunState::StartedAsync(value) => {
104
- let promise = self.coerce_to_promise(value)?;
105
- self.attach_dependent(promise, target)
106
- }
107
- RunState::Suspended { .. } => Err(MustardError::runtime(
108
- "promise reactions do not support synchronous host suspensions",
109
- )),
110
- }
111
- }
112
- Value::HostFunction(capability) => {
113
- let outstanding =
114
- self.pending_host_calls.len() + usize::from(self.suspended_host_call.is_some());
115
- if outstanding >= self.limits.max_outstanding_host_calls {
116
- return Err(limit_error("outstanding host-call limit exhausted"));
117
- }
118
- let args = args
119
- .iter()
120
- .cloned()
121
- .map(|value| self.value_to_structured(value))
122
- .collect::<MustardResult<Vec<_>>>()?;
123
- let promise = self.insert_promise(PromiseState::Pending)?;
124
- self.attach_dependent(promise, target)?;
125
- self.pending_host_calls.push_back(PendingHostCall {
126
- capability,
127
- args,
128
- promise: Some(promise),
129
- resume_behavior: ResumeBehavior::Value,
130
- traceback: self.traceback_snapshots(),
131
- });
132
- Ok(())
133
- }
134
- _ => Err(MustardError::runtime("value is not callable")),
135
- }
136
- }
137
-
138
- pub(in crate::runtime) fn make_promise_all_settled_result(
139
- &mut self,
140
- result: PromiseSettledResult,
141
- ) -> MustardResult<Value> {
142
- let properties = match result {
143
- PromiseSettledResult::Fulfilled(value) => IndexMap::from([
144
- ("status".to_string(), Value::String("fulfilled".to_string())),
145
- ("value".to_string(), value),
146
- ]),
147
- PromiseSettledResult::Rejected(reason) => IndexMap::from([
148
- ("status".to_string(), Value::String("rejected".to_string())),
149
- ("reason".to_string(), reason),
150
- ]),
151
- };
152
- Ok(Value::Object(
153
- self.insert_object(properties, ObjectKind::Plain)?,
154
- ))
155
- }
156
-
157
- pub(in crate::runtime) fn make_aggregate_error(
158
- &mut self,
159
- reasons: Vec<Value>,
160
- ) -> MustardResult<Value> {
161
- let error = self.make_error_object(
162
- "AggregateError",
163
- &[Value::String("All promises were rejected".to_string())],
164
- None,
165
- None,
166
- None,
167
- )?;
168
- let errors = Value::Array(self.insert_array(reasons, IndexMap::new())?);
169
- self.set_property(error.clone(), Value::String("errors".to_string()), errors)?;
170
- Ok(error)
171
- }
172
-
173
- pub(in crate::runtime) fn activate_promise_combinator(
174
- &mut self,
175
- target: PromiseKey,
176
- index: usize,
177
- kind: PromiseCombinatorKind,
178
- outcome: PromiseOutcome,
179
- ) -> MustardResult<()> {
180
- if self.promise_outcome(target)?.is_some() {
181
- return Ok(());
182
- }
183
- let promise = self
184
- .promises
185
- .get(target)
186
- .ok_or_else(|| MustardError::runtime("promise missing"))?;
187
- if let Some(len) = Self::promise_combinator_slot_len(promise, kind)?
188
- && index >= len
189
- {
190
- return Err(serialization_error(
191
- "snapshot validation failed: promise combinator index out of range",
192
- ));
193
- }
194
- match kind {
195
- PromiseCombinatorKind::Race => self.resolve_promise_with_outcome(target, outcome),
196
- PromiseCombinatorKind::All => {
197
- let mut resolved_values = None;
198
- let mut rejection = None;
199
- {
200
- let promise = self
201
- .promises
202
- .get_mut(target)
203
- .ok_or_else(|| MustardError::runtime("promise missing"))?;
204
- let PromiseState::Pending = promise.state else {
205
- return Ok(());
206
- };
207
- let PromiseDriver::All { remaining, values } = promise
208
- .driver
209
- .as_mut()
210
- .ok_or_else(|| MustardError::runtime("promise combinator state missing"))?
211
- else {
212
- return Err(MustardError::runtime("promise combinator kind mismatch"));
213
- };
214
- match outcome {
215
- PromiseOutcome::Fulfilled(value) => {
216
- values[index] = Some(value);
217
- *remaining = remaining.saturating_sub(1);
218
- if *remaining == 0 {
219
- resolved_values = Some(
220
- values
221
- .iter()
222
- .map(|value| value.clone().unwrap_or(Value::Undefined))
223
- .collect::<Vec<_>>(),
224
- );
225
- }
226
- }
227
- PromiseOutcome::Rejected(reason) => rejection = Some(reason),
228
- }
229
- }
230
- self.refresh_promise_accounting(target)?;
231
- if let Some(rejection) = rejection {
232
- self.reject_promise(target, rejection)?;
233
- } else if let Some(values) = resolved_values {
234
- let array = Value::Array(self.insert_array(values, IndexMap::new())?);
235
- self.resolve_promise(target, array)?;
236
- }
237
- Ok(())
238
- }
239
- PromiseCombinatorKind::AllSettled => {
240
- let mut settled_results = None;
241
- {
242
- let promise = self
243
- .promises
244
- .get_mut(target)
245
- .ok_or_else(|| MustardError::runtime("promise missing"))?;
246
- let PromiseState::Pending = promise.state else {
247
- return Ok(());
248
- };
249
- let PromiseDriver::AllSettled { remaining, results } = promise
250
- .driver
251
- .as_mut()
252
- .ok_or_else(|| MustardError::runtime("promise combinator state missing"))?
253
- else {
254
- return Err(MustardError::runtime("promise combinator kind mismatch"));
255
- };
256
- results[index] = Some(match outcome {
257
- PromiseOutcome::Fulfilled(value) => PromiseSettledResult::Fulfilled(value),
258
- PromiseOutcome::Rejected(reason) => {
259
- PromiseSettledResult::Rejected(reason.value)
260
- }
261
- });
262
- *remaining = remaining.saturating_sub(1);
263
- if *remaining == 0 {
264
- settled_results = Some(
265
- results
266
- .iter()
267
- .map(|result| {
268
- result.clone().unwrap_or(PromiseSettledResult::Fulfilled(
269
- Value::Undefined,
270
- ))
271
- })
272
- .collect::<Vec<_>>(),
273
- );
274
- }
275
- }
276
- self.refresh_promise_accounting(target)?;
277
- if let Some(results) = settled_results {
278
- let mut values = Vec::with_capacity(results.len());
279
- for result in results {
280
- values.push(self.make_promise_all_settled_result(result)?);
281
- }
282
- let array = Value::Array(self.insert_array(values, IndexMap::new())?);
283
- self.resolve_promise(target, array)?;
284
- }
285
- Ok(())
286
- }
287
- PromiseCombinatorKind::Any => {
288
- let mut rejection_values = None;
289
- let mut fulfillment = None;
290
- {
291
- let promise = self
292
- .promises
293
- .get_mut(target)
294
- .ok_or_else(|| MustardError::runtime("promise missing"))?;
295
- let PromiseState::Pending = promise.state else {
296
- return Ok(());
297
- };
298
- let PromiseDriver::Any { remaining, reasons } = promise
299
- .driver
300
- .as_mut()
301
- .ok_or_else(|| MustardError::runtime("promise combinator state missing"))?
302
- else {
303
- return Err(MustardError::runtime("promise combinator kind mismatch"));
304
- };
305
- match outcome {
306
- PromiseOutcome::Fulfilled(value) => fulfillment = Some(value),
307
- PromiseOutcome::Rejected(reason) => {
308
- reasons[index] = Some(reason.value);
309
- *remaining = remaining.saturating_sub(1);
310
- if *remaining == 0 {
311
- rejection_values = Some(
312
- reasons
313
- .iter()
314
- .map(|value| value.clone().unwrap_or(Value::Undefined))
315
- .collect::<Vec<_>>(),
316
- );
317
- }
318
- }
319
- }
320
- }
321
- self.refresh_promise_accounting(target)?;
322
- if let Some(value) = fulfillment {
323
- self.resolve_promise(target, value)?;
324
- } else if let Some(reasons) = rejection_values {
325
- let rejection = PromiseRejection {
326
- value: self.make_aggregate_error(reasons)?,
327
- span: None,
328
- traceback: self.traceback_snapshots(),
329
- };
330
- self.reject_promise(target, rejection)?;
331
- }
332
- Ok(())
333
- }
334
- }
335
- }
336
-
337
- pub(in crate::runtime) fn activate_promise_reaction(
338
- &mut self,
339
- reaction: PromiseReaction,
340
- outcome: PromiseOutcome,
341
- ) -> MustardResult<()> {
342
- let target = self.promise_reaction_target(&reaction);
343
- let result = (|| match reaction {
344
- PromiseReaction::Then {
345
- target,
346
- on_fulfilled,
347
- on_rejected,
348
- } => match outcome {
349
- PromiseOutcome::Fulfilled(value) => {
350
- if let Some(handler) = on_fulfilled {
351
- self.invoke_promise_handler(handler, &[value], target)
352
- } else {
353
- self.resolve_promise(target, value)
354
- }
355
- }
356
- PromiseOutcome::Rejected(rejection) => {
357
- if let Some(handler) = on_rejected {
358
- self.invoke_promise_handler(handler, &[rejection.value], target)
359
- } else {
360
- self.reject_promise(target, rejection)
361
- }
362
- }
363
- },
364
- PromiseReaction::Finally { target, callback } => {
365
- if let Some(callback) = callback {
366
- let bridge = self.insert_promise(PromiseState::Pending)?;
367
- self.attach_promise_reaction(
368
- bridge,
369
- PromiseReaction::FinallyPassThrough {
370
- target,
371
- original_outcome: outcome,
372
- },
373
- )?;
374
- self.invoke_promise_handler(callback, &[], bridge)
375
- } else {
376
- self.resolve_promise_with_outcome(target, outcome)
377
- }
378
- }
379
- PromiseReaction::FinallyPassThrough {
380
- target,
381
- original_outcome,
382
- } => match outcome {
383
- PromiseOutcome::Fulfilled(_) => {
384
- self.resolve_promise_with_outcome(target, original_outcome)
385
- }
386
- PromiseOutcome::Rejected(rejection) => self.reject_promise(target, rejection),
387
- },
388
- PromiseReaction::Combinator {
389
- target,
390
- index,
391
- kind,
392
- } => self.activate_promise_combinator(target, index, kind, outcome),
393
- })();
394
-
395
- match result {
396
- Ok(()) => Ok(()),
397
- Err(error) => self.reject_promise_from_error(target, error),
398
- }
399
- }
400
- }
@@ -1,224 +0,0 @@
1
- use super::*;
2
-
3
- impl Runtime {
4
- pub(in crate::runtime) fn activate_microtask(
5
- &mut self,
6
- job: MicrotaskJob,
7
- ) -> MustardResult<()> {
8
- if !self.frames.is_empty() {
9
- return Err(MustardError::runtime(
10
- "microtask checkpoint ran while frames were still active",
11
- ));
12
- }
13
- match job {
14
- MicrotaskJob::ResumeAsync {
15
- continuation,
16
- outcome,
17
- } => {
18
- self.frames = continuation.frames;
19
- match outcome {
20
- PromiseOutcome::Fulfilled(value) => {
21
- let frame = self.frames.last_mut().ok_or_else(|| {
22
- MustardError::runtime("async continuation resumed without frames")
23
- })?;
24
- frame.stack.push(value);
25
- }
26
- PromiseOutcome::Rejected(rejection) => {
27
- match self.raise_exception_with_origin(
28
- rejection.value,
29
- rejection.span,
30
- Some(rejection.traceback),
31
- )? {
32
- StepAction::Continue => {}
33
- StepAction::Return(_) => {}
34
- }
35
- }
36
- }
37
- }
38
- MicrotaskJob::PromiseReaction { reaction, outcome } => {
39
- self.activate_promise_reaction(reaction, outcome)?;
40
- }
41
- }
42
- Ok(())
43
- }
44
-
45
- pub(in crate::runtime) fn has_pending_async_work(&self) -> bool {
46
- self.suspended_host_call.is_some()
47
- || !self.pending_host_calls.is_empty()
48
- || !self.microtasks.is_empty()
49
- || self.promises.values().any(|promise| {
50
- matches!(promise.state, PromiseState::Pending)
51
- && (!promise.awaiters.is_empty()
52
- || !promise.dependents.is_empty()
53
- || !promise.reactions.is_empty())
54
- })
55
- }
56
-
57
- pub(in crate::runtime) fn suspend_host_request(
58
- &mut self,
59
- request: PendingHostCall,
60
- ) -> ExecutionStep {
61
- let capability = request.capability.clone();
62
- let args = request.args.clone();
63
- self.suspended_host_call = Some(request);
64
- self.snapshot_nonce = next_snapshot_nonce();
65
- ExecutionStep::Suspended(Box::new(Suspension {
66
- capability,
67
- args,
68
- snapshot: ExecutionSnapshot {
69
- runtime: self.clone(),
70
- },
71
- }))
72
- }
73
-
74
- pub(in crate::runtime) fn process_idle_state(
75
- &mut self,
76
- ) -> MustardResult<Option<ExecutionStep>> {
77
- if let Some(job) = self.microtasks.pop_front() {
78
- self.activate_microtask(job)?;
79
- return Ok(None);
80
- }
81
- if let Some(request) = self.pending_host_calls.pop_front() {
82
- return Ok(Some(self.suspend_host_request(request)));
83
- }
84
- if let Some(root_result) = self.root_result.clone() {
85
- return match root_result {
86
- Value::Promise(promise) => match self.promise_outcome(promise)? {
87
- Some(PromiseOutcome::Fulfilled(value)) => Ok(Some(ExecutionStep::Completed(
88
- self.value_to_structured(value)?,
89
- ))),
90
- Some(PromiseOutcome::Rejected(rejection)) => {
91
- Err(self.root_error_from_rejection(rejection)?)
92
- }
93
- None => Err(MustardError::runtime(
94
- "async root promise could not make progress",
95
- )),
96
- },
97
- value => {
98
- if self.has_pending_async_work() {
99
- return Err(MustardError::runtime(
100
- "async execution became idle with pending work",
101
- ));
102
- }
103
- Ok(Some(ExecutionStep::Completed(
104
- self.value_to_structured(value)?,
105
- )))
106
- }
107
- };
108
- }
109
- if self.has_pending_async_work() {
110
- return Err(MustardError::runtime(
111
- "async execution became idle before producing a root result",
112
- ));
113
- }
114
- Err(MustardError::runtime("vm lost all frames"))
115
- }
116
-
117
- pub(in crate::runtime) fn resume(
118
- &mut self,
119
- payload: ResumePayload,
120
- ) -> MustardResult<ExecutionStep> {
121
- if let Err(error) = self.check_cancellation() {
122
- if let Some(request) = self.suspended_host_call.as_ref() {
123
- return Err(error.with_traceback(self.compose_traceback(&request.traceback)));
124
- }
125
- return Err(self.annotate_runtime_error(error));
126
- }
127
- self.collect_garbage()
128
- .map_err(|error| self.annotate_runtime_error(error))?;
129
- if let Some(request) = self.suspended_host_call.take() {
130
- if let Some(promise) = request.promise {
131
- let outcome = match payload {
132
- ResumePayload::Value(value) => {
133
- let value = match request.resume_behavior {
134
- ResumeBehavior::Value => self
135
- .value_from_structured(value)
136
- .map_err(|error| self.annotate_runtime_error(error))?,
137
- ResumeBehavior::Undefined => Value::Undefined,
138
- };
139
- PromiseOutcome::Fulfilled(value)
140
- }
141
- ResumePayload::Error(error) => PromiseOutcome::Rejected(PromiseRejection {
142
- value: self
143
- .value_from_host_error(error)
144
- .map_err(|error| self.annotate_runtime_error(error))?,
145
- span: None,
146
- traceback: Vec::new(),
147
- }),
148
- ResumePayload::Cancelled => {
149
- return Err(limit_error("execution cancelled")
150
- .with_traceback(self.compose_traceback(&request.traceback)));
151
- }
152
- };
153
- self.resolve_promise_with_outcome(promise, outcome)
154
- .map_err(|error| self.annotate_runtime_error(error))?;
155
- return self.run();
156
- }
157
-
158
- return match payload {
159
- ResumePayload::Value(value) => {
160
- let value = match request.resume_behavior {
161
- ResumeBehavior::Value => self
162
- .value_from_structured(value)
163
- .map_err(|error| self.annotate_runtime_error(error))?,
164
- ResumeBehavior::Undefined => Value::Undefined,
165
- };
166
- self.pending_resume_behavior = ResumeBehavior::Value;
167
- let Some(frame) = self.frames.last_mut() else {
168
- return Err(self.annotate_runtime_error(MustardError::runtime(
169
- "no suspended frame available",
170
- )));
171
- };
172
- frame.stack.push(value);
173
- self.run()
174
- }
175
- ResumePayload::Error(error) => {
176
- self.pending_resume_behavior = ResumeBehavior::Value;
177
- let value = self
178
- .value_from_host_error(error)
179
- .map_err(|error| self.annotate_runtime_error(error))?;
180
- match self.raise_exception(value, None) {
181
- Ok(StepAction::Continue) => self.run(),
182
- Ok(StepAction::Return(step)) => Ok(step),
183
- Err(error) => Err(self.annotate_runtime_error(error)),
184
- }
185
- }
186
- ResumePayload::Cancelled => {
187
- Err(self.annotate_runtime_error(limit_error("execution cancelled")))
188
- }
189
- };
190
- }
191
- match payload {
192
- ResumePayload::Value(value) => {
193
- let value = match self.pending_resume_behavior {
194
- ResumeBehavior::Value => self
195
- .value_from_structured(value)
196
- .map_err(|error| self.annotate_runtime_error(error))?,
197
- ResumeBehavior::Undefined => Value::Undefined,
198
- };
199
- self.pending_resume_behavior = ResumeBehavior::Value;
200
- let Some(frame) = self.frames.last_mut() else {
201
- return Err(self.annotate_runtime_error(MustardError::runtime(
202
- "no suspended frame available",
203
- )));
204
- };
205
- frame.stack.push(value);
206
- }
207
- ResumePayload::Error(error) => {
208
- self.pending_resume_behavior = ResumeBehavior::Value;
209
- let value = self
210
- .value_from_host_error(error)
211
- .map_err(|error| self.annotate_runtime_error(error))?;
212
- match self.raise_exception(value, None) {
213
- Ok(StepAction::Continue) => return self.run(),
214
- Ok(StepAction::Return(step)) => return Ok(step),
215
- Err(error) => return Err(self.annotate_runtime_error(error)),
216
- }
217
- }
218
- ResumePayload::Cancelled => {
219
- return Err(self.annotate_runtime_error(limit_error("execution cancelled")));
220
- }
221
- }
222
- self.run()
223
- }
224
- }