mustardscript 0.1.0 → 0.1.2
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 +65 -22
- 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,192 +0,0 @@
|
|
|
1
|
-
use indexmap::IndexMap;
|
|
2
|
-
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|
3
|
-
|
|
4
|
-
use crate::{
|
|
5
|
-
cancellation::CancellationToken,
|
|
6
|
-
diagnostic::{DiagnosticKind, MustardError, MustardResult},
|
|
7
|
-
ir::CompiledProgram,
|
|
8
|
-
limits::RuntimeLimits,
|
|
9
|
-
structured::StructuredValue,
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
use super::{
|
|
13
|
-
Runtime,
|
|
14
|
-
bytecode::BytecodeProgram,
|
|
15
|
-
lower_to_bytecode,
|
|
16
|
-
validation::{validate_bytecode_program, validate_snapshot},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
20
|
-
pub struct ExecutionOptions {
|
|
21
|
-
pub inputs: IndexMap<String, StructuredValue>,
|
|
22
|
-
pub capabilities: Vec<String>,
|
|
23
|
-
pub limits: RuntimeLimits,
|
|
24
|
-
#[serde(skip, default)]
|
|
25
|
-
pub cancellation_token: Option<CancellationToken>,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
impl Default for ExecutionOptions {
|
|
29
|
-
fn default() -> Self {
|
|
30
|
-
Self {
|
|
31
|
-
inputs: IndexMap::new(),
|
|
32
|
-
capabilities: Vec::new(),
|
|
33
|
-
limits: RuntimeLimits::default(),
|
|
34
|
-
cancellation_token: None,
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
40
|
-
pub struct HostError {
|
|
41
|
-
pub name: String,
|
|
42
|
-
pub message: String,
|
|
43
|
-
pub code: Option<String>,
|
|
44
|
-
pub details: Option<StructuredValue>,
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
48
|
-
pub enum ResumePayload {
|
|
49
|
-
Value(StructuredValue),
|
|
50
|
-
Error(HostError),
|
|
51
|
-
Cancelled,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
55
|
-
pub struct SnapshotPolicy {
|
|
56
|
-
pub capabilities: Vec<String>,
|
|
57
|
-
pub limits: RuntimeLimits,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
61
|
-
pub struct SnapshotInspection {
|
|
62
|
-
pub capability: String,
|
|
63
|
-
pub args: Vec<StructuredValue>,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
#[derive(Debug, Clone, Default)]
|
|
67
|
-
pub struct ResumeOptions {
|
|
68
|
-
pub cancellation_token: Option<CancellationToken>,
|
|
69
|
-
pub snapshot_policy: Option<SnapshotPolicy>,
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
#[derive(Debug, Clone)]
|
|
73
|
-
pub struct ExecutionSnapshot {
|
|
74
|
-
pub(super) runtime: Runtime,
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
78
|
-
pub struct Suspension {
|
|
79
|
-
pub capability: String,
|
|
80
|
-
pub args: Vec<StructuredValue>,
|
|
81
|
-
pub snapshot: ExecutionSnapshot,
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
85
|
-
pub enum ExecutionStep {
|
|
86
|
-
Completed(StructuredValue),
|
|
87
|
-
Suspended(Box<Suspension>),
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
#[derive(Serialize)]
|
|
91
|
-
struct SerializableExecutionSnapshot<'a> {
|
|
92
|
-
runtime: &'a Runtime,
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
#[derive(Deserialize)]
|
|
96
|
-
struct DeserializableExecutionSnapshot {
|
|
97
|
-
runtime: Runtime,
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
impl ExecutionSnapshot {
|
|
101
|
-
pub(in crate::runtime) fn restore_loaded_runtime(runtime: Runtime) -> MustardResult<Self> {
|
|
102
|
-
let mut snapshot = Self { runtime };
|
|
103
|
-
validate_snapshot(&snapshot)?;
|
|
104
|
-
snapshot.runtime.recompute_accounting_after_load()?;
|
|
105
|
-
snapshot.runtime.snapshot_policy_required = true;
|
|
106
|
-
Ok(snapshot)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
impl Serialize for ExecutionSnapshot {
|
|
111
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
112
|
-
where
|
|
113
|
-
S: Serializer,
|
|
114
|
-
{
|
|
115
|
-
SerializableExecutionSnapshot {
|
|
116
|
-
runtime: &self.runtime,
|
|
117
|
-
}
|
|
118
|
-
.serialize(serializer)
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
impl<'de> Deserialize<'de> for ExecutionSnapshot {
|
|
123
|
-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
124
|
-
where
|
|
125
|
-
D: Deserializer<'de>,
|
|
126
|
-
{
|
|
127
|
-
let decoded = DeserializableExecutionSnapshot::deserialize(deserializer)?;
|
|
128
|
-
Self::restore_loaded_runtime(decoded.runtime).map_err(serde::de::Error::custom)
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
pub fn execute(
|
|
133
|
-
program: &CompiledProgram,
|
|
134
|
-
options: ExecutionOptions,
|
|
135
|
-
) -> MustardResult<StructuredValue> {
|
|
136
|
-
match start(program, options)? {
|
|
137
|
-
ExecutionStep::Completed(value) => Ok(value),
|
|
138
|
-
ExecutionStep::Suspended(suspension) => Err(MustardError::runtime(format!(
|
|
139
|
-
"execution suspended on capability `{}`; use start()/resume() for iterative execution",
|
|
140
|
-
suspension.capability
|
|
141
|
-
))),
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
pub fn start(program: &CompiledProgram, options: ExecutionOptions) -> MustardResult<ExecutionStep> {
|
|
146
|
-
let bytecode = lower_to_bytecode(program)?;
|
|
147
|
-
start_bytecode(&bytecode, options)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
pub fn start_bytecode(
|
|
151
|
-
program: &BytecodeProgram,
|
|
152
|
-
options: ExecutionOptions,
|
|
153
|
-
) -> MustardResult<ExecutionStep> {
|
|
154
|
-
validate_bytecode_program(program)?;
|
|
155
|
-
let mut runtime = Runtime::new(program.clone(), options)?;
|
|
156
|
-
runtime.run_root()
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
pub fn resume(snapshot: ExecutionSnapshot, payload: ResumePayload) -> MustardResult<ExecutionStep> {
|
|
160
|
-
resume_with_options(snapshot, payload, ResumeOptions::default())
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
pub fn resume_with_options(
|
|
164
|
-
snapshot: ExecutionSnapshot,
|
|
165
|
-
payload: ResumePayload,
|
|
166
|
-
options: ResumeOptions,
|
|
167
|
-
) -> MustardResult<ExecutionStep> {
|
|
168
|
-
let mut runtime = snapshot.runtime;
|
|
169
|
-
runtime.apply_resume_options(options)?;
|
|
170
|
-
runtime.resume(payload)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
pub fn inspect_snapshot(
|
|
174
|
-
snapshot: &mut ExecutionSnapshot,
|
|
175
|
-
policy: SnapshotPolicy,
|
|
176
|
-
) -> MustardResult<SnapshotInspection> {
|
|
177
|
-
snapshot.runtime.apply_snapshot_policy(policy)?;
|
|
178
|
-
let request = snapshot
|
|
179
|
-
.runtime
|
|
180
|
-
.suspended_host_call
|
|
181
|
-
.as_ref()
|
|
182
|
-
.ok_or_else(|| MustardError::Message {
|
|
183
|
-
kind: DiagnosticKind::Serialization,
|
|
184
|
-
message: "snapshot is not suspended on a host capability".to_string(),
|
|
185
|
-
span: None,
|
|
186
|
-
traceback: Vec::new(),
|
|
187
|
-
})?;
|
|
188
|
-
Ok(SnapshotInspection {
|
|
189
|
-
capability: request.capability.clone(),
|
|
190
|
-
args: request.args.clone(),
|
|
191
|
-
})
|
|
192
|
-
}
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
use crate::runtime::builtins::PromiseSetupPolicy;
|
|
2
|
-
|
|
3
|
-
use super::*;
|
|
4
|
-
|
|
5
|
-
impl Runtime {
|
|
6
|
-
pub(in crate::runtime) fn current_async_boundary_index(&self) -> Option<usize> {
|
|
7
|
-
self.frames
|
|
8
|
-
.iter()
|
|
9
|
-
.rposition(|frame| frame.async_promise.is_some())
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
pub(in crate::runtime) fn promise_outcome(
|
|
13
|
-
&self,
|
|
14
|
-
promise: PromiseKey,
|
|
15
|
-
) -> MustardResult<Option<PromiseOutcome>> {
|
|
16
|
-
let promise = self
|
|
17
|
-
.promises
|
|
18
|
-
.get(promise)
|
|
19
|
-
.ok_or_else(|| MustardError::runtime("promise missing"))?;
|
|
20
|
-
Ok(match &promise.state {
|
|
21
|
-
PromiseState::Pending => None,
|
|
22
|
-
PromiseState::Fulfilled(value) => Some(PromiseOutcome::Fulfilled(value.clone())),
|
|
23
|
-
PromiseState::Rejected(rejection) => Some(PromiseOutcome::Rejected(rejection.clone())),
|
|
24
|
-
})
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
pub(in crate::runtime) fn coerce_to_promise(
|
|
28
|
-
&mut self,
|
|
29
|
-
value: Value,
|
|
30
|
-
) -> MustardResult<PromiseKey> {
|
|
31
|
-
match value {
|
|
32
|
-
Value::Promise(promise) => Ok(promise),
|
|
33
|
-
other => {
|
|
34
|
-
let promise = self.insert_promise(PromiseState::Pending)?;
|
|
35
|
-
self.resolve_promise(promise, other)?;
|
|
36
|
-
Ok(promise)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
pub(in crate::runtime) fn attach_awaiter(
|
|
42
|
-
&mut self,
|
|
43
|
-
promise: PromiseKey,
|
|
44
|
-
continuation: AsyncContinuation,
|
|
45
|
-
) -> MustardResult<()> {
|
|
46
|
-
self.promises
|
|
47
|
-
.get_mut(promise)
|
|
48
|
-
.ok_or_else(|| MustardError::runtime("promise missing"))?
|
|
49
|
-
.awaiters
|
|
50
|
-
.push(continuation);
|
|
51
|
-
self.refresh_promise_accounting(promise)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
pub(in crate::runtime) fn attach_dependent(
|
|
55
|
-
&mut self,
|
|
56
|
-
promise: PromiseKey,
|
|
57
|
-
dependent: PromiseKey,
|
|
58
|
-
) -> MustardResult<()> {
|
|
59
|
-
self.promises
|
|
60
|
-
.get_mut(promise)
|
|
61
|
-
.ok_or_else(|| MustardError::runtime("promise missing"))?
|
|
62
|
-
.dependents
|
|
63
|
-
.push(dependent);
|
|
64
|
-
self.refresh_promise_accounting(promise)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
pub(in crate::runtime) fn attach_promise_reaction(
|
|
68
|
-
&mut self,
|
|
69
|
-
promise: PromiseKey,
|
|
70
|
-
reaction: PromiseReaction,
|
|
71
|
-
) -> MustardResult<()> {
|
|
72
|
-
match self.promise_outcome(promise)? {
|
|
73
|
-
Some(outcome) => self.schedule_promise_reaction(reaction, outcome),
|
|
74
|
-
None => {
|
|
75
|
-
self.promises
|
|
76
|
-
.get_mut(promise)
|
|
77
|
-
.ok_or_else(|| MustardError::runtime("promise missing"))?
|
|
78
|
-
.reactions
|
|
79
|
-
.push(reaction);
|
|
80
|
-
self.refresh_promise_accounting(promise)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
pub(in crate::runtime) fn schedule_promise_reaction(
|
|
86
|
-
&mut self,
|
|
87
|
-
reaction: PromiseReaction,
|
|
88
|
-
outcome: PromiseOutcome,
|
|
89
|
-
) -> MustardResult<()> {
|
|
90
|
-
self.microtasks
|
|
91
|
-
.push_back(MicrotaskJob::PromiseReaction { reaction, outcome });
|
|
92
|
-
Ok(())
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
pub(in crate::runtime) fn settle_promise_with_outcome(
|
|
96
|
-
&mut self,
|
|
97
|
-
promise: PromiseKey,
|
|
98
|
-
outcome: PromiseOutcome,
|
|
99
|
-
) -> MustardResult<()> {
|
|
100
|
-
let (awaiters, dependents, reactions) = {
|
|
101
|
-
let promise_ref = self
|
|
102
|
-
.promises
|
|
103
|
-
.get_mut(promise)
|
|
104
|
-
.ok_or_else(|| MustardError::runtime("promise missing"))?;
|
|
105
|
-
if !matches!(promise_ref.state, PromiseState::Pending) {
|
|
106
|
-
return Ok(());
|
|
107
|
-
}
|
|
108
|
-
promise_ref.state = match &outcome {
|
|
109
|
-
PromiseOutcome::Fulfilled(value) => PromiseState::Fulfilled(value.clone()),
|
|
110
|
-
PromiseOutcome::Rejected(rejection) => PromiseState::Rejected(rejection.clone()),
|
|
111
|
-
};
|
|
112
|
-
promise_ref.driver = None;
|
|
113
|
-
(
|
|
114
|
-
std::mem::take(&mut promise_ref.awaiters),
|
|
115
|
-
std::mem::take(&mut promise_ref.dependents),
|
|
116
|
-
std::mem::take(&mut promise_ref.reactions),
|
|
117
|
-
)
|
|
118
|
-
};
|
|
119
|
-
self.refresh_promise_accounting(promise)?;
|
|
120
|
-
for continuation in awaiters {
|
|
121
|
-
self.microtasks.push_back(MicrotaskJob::ResumeAsync {
|
|
122
|
-
continuation,
|
|
123
|
-
outcome: outcome.clone(),
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
for dependent in dependents {
|
|
127
|
-
self.resolve_promise_with_outcome(dependent, outcome.clone())?;
|
|
128
|
-
}
|
|
129
|
-
for reaction in reactions {
|
|
130
|
-
self.schedule_promise_reaction(reaction, outcome.clone())?;
|
|
131
|
-
}
|
|
132
|
-
Ok(())
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
pub(in crate::runtime) fn resolve_promise_with_outcome(
|
|
136
|
-
&mut self,
|
|
137
|
-
promise: PromiseKey,
|
|
138
|
-
outcome: PromiseOutcome,
|
|
139
|
-
) -> MustardResult<()> {
|
|
140
|
-
match outcome {
|
|
141
|
-
PromiseOutcome::Fulfilled(value) => self.resolve_promise(promise, value),
|
|
142
|
-
PromiseOutcome::Rejected(rejection) => self.reject_promise(promise, rejection),
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
pub(in crate::runtime) fn resolve_promise(
|
|
147
|
-
&mut self,
|
|
148
|
-
promise: PromiseKey,
|
|
149
|
-
value: Value,
|
|
150
|
-
) -> MustardResult<()> {
|
|
151
|
-
if self.promise_outcome(promise)?.is_some() {
|
|
152
|
-
return Ok(());
|
|
153
|
-
}
|
|
154
|
-
if let Value::Promise(source) = value {
|
|
155
|
-
if source == promise {
|
|
156
|
-
let error_value =
|
|
157
|
-
self.value_from_runtime_message("TypeError: promise cannot resolve to itself")?;
|
|
158
|
-
return self.reject_promise(
|
|
159
|
-
promise,
|
|
160
|
-
PromiseRejection {
|
|
161
|
-
value: error_value,
|
|
162
|
-
span: None,
|
|
163
|
-
traceback: self.traceback_snapshots(),
|
|
164
|
-
},
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
match self.promise_outcome(source)? {
|
|
168
|
-
Some(outcome) => self.resolve_promise_with_outcome(promise, outcome),
|
|
169
|
-
None => self.attach_dependent(source, promise),
|
|
170
|
-
}
|
|
171
|
-
} else if let Some(then) = self.promise_thenable_handler(&value)? {
|
|
172
|
-
let tracked_thenable = self
|
|
173
|
-
.promises
|
|
174
|
-
.get(promise)
|
|
175
|
-
.ok_or_else(|| MustardError::runtime("promise missing"))?
|
|
176
|
-
.driver
|
|
177
|
-
.as_ref()
|
|
178
|
-
.and_then(|driver| match driver {
|
|
179
|
-
PromiseDriver::Thenable { value } => Some(value),
|
|
180
|
-
_ => None,
|
|
181
|
-
});
|
|
182
|
-
if tracked_thenable.is_some_and(|tracked| strict_equal(tracked, &value)) {
|
|
183
|
-
let error_value = self
|
|
184
|
-
.value_from_runtime_message("TypeError: thenable cannot resolve to itself")?;
|
|
185
|
-
return self.reject_promise(
|
|
186
|
-
promise,
|
|
187
|
-
PromiseRejection {
|
|
188
|
-
value: error_value,
|
|
189
|
-
span: None,
|
|
190
|
-
traceback: self.traceback_snapshots(),
|
|
191
|
-
},
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
self.promises
|
|
195
|
-
.get_mut(promise)
|
|
196
|
-
.ok_or_else(|| MustardError::runtime("promise missing"))?
|
|
197
|
-
.driver = Some(PromiseDriver::Thenable {
|
|
198
|
-
value: value.clone(),
|
|
199
|
-
});
|
|
200
|
-
self.refresh_promise_accounting(promise)?;
|
|
201
|
-
let resolve = self.promise_settler(promise, false);
|
|
202
|
-
let reject = self.promise_settler(promise, true);
|
|
203
|
-
self.call_promise_setup_callback(
|
|
204
|
-
promise,
|
|
205
|
-
then,
|
|
206
|
-
value,
|
|
207
|
-
&[resolve, reject],
|
|
208
|
-
PromiseSetupPolicy {
|
|
209
|
-
non_callable_message: "TypeError: adopted thenable `.then` must be callable",
|
|
210
|
-
host_suspension_message:
|
|
211
|
-
"TypeError: adopted thenables do not support synchronous host suspensions",
|
|
212
|
-
async_message:
|
|
213
|
-
"TypeError: adopted thenables must use synchronous `.then` handlers",
|
|
214
|
-
},
|
|
215
|
-
)
|
|
216
|
-
} else {
|
|
217
|
-
self.settle_promise_with_outcome(promise, PromiseOutcome::Fulfilled(value))
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
pub(in crate::runtime) fn reject_promise(
|
|
222
|
-
&mut self,
|
|
223
|
-
promise: PromiseKey,
|
|
224
|
-
rejection: PromiseRejection,
|
|
225
|
-
) -> MustardResult<()> {
|
|
226
|
-
self.settle_promise_with_outcome(promise, PromiseOutcome::Rejected(rejection))
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
pub(in crate::runtime) fn suspend_async_await(&mut self, value: Value) -> MustardResult<()> {
|
|
230
|
-
let boundary = self.current_async_boundary_index().ok_or_else(|| {
|
|
231
|
-
MustardError::runtime("await is only supported inside async functions")
|
|
232
|
-
})?;
|
|
233
|
-
let promise = self.coerce_to_promise(value)?;
|
|
234
|
-
let continuation = AsyncContinuation {
|
|
235
|
-
frames: self.frames.split_off(boundary),
|
|
236
|
-
};
|
|
237
|
-
match self.promise_outcome(promise)? {
|
|
238
|
-
Some(outcome) => self.microtasks.push_back(MicrotaskJob::ResumeAsync {
|
|
239
|
-
continuation,
|
|
240
|
-
outcome,
|
|
241
|
-
}),
|
|
242
|
-
None => self.attach_awaiter(promise, continuation)?,
|
|
243
|
-
}
|
|
244
|
-
Ok(())
|
|
245
|
-
}
|
|
246
|
-
}
|