1use crate::interpreter::interpreter_stack_value::RibInterpreterStackValue;
16use crate::{GetLiteralValue, LiteralValue};
17use golem_wasm_ast::analysis::analysed_type::{list, option, record, str, tuple, variant};
18use golem_wasm_ast::analysis::{
19 AnalysedType, NameOptionTypePair, NameTypePair, TypeEnum, TypeRecord, TypeResult,
20};
21use golem_wasm_rpc::{Value, ValueAndType};
22
23#[derive(Debug)]
24pub struct InterpreterStack {
25 pub stack: Vec<RibInterpreterStackValue>,
26}
27
28impl Default for InterpreterStack {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl InterpreterStack {
35 pub fn new() -> Self {
36 InterpreterStack { stack: Vec::new() }
37 }
38
39 pub fn create_record(&mut self, fields: Vec<NameTypePair>) {
41 self.push_val(ValueAndType::new(
42 Value::Record(
43 vec![Value::Tuple(vec![]); fields.len()], ),
45 record(fields),
46 ));
47 }
48
49 pub fn pop(&mut self) -> Option<RibInterpreterStackValue> {
50 self.stack.pop()
51 }
52
53 pub fn try_pop(&mut self) -> Result<RibInterpreterStackValue, String> {
54 self.pop()
55 .ok_or("internal error: failed to pop value from the interpreter stack".to_string())
56 }
57
58 pub fn pop_sink(&mut self) -> Option<(Vec<ValueAndType>, AnalysedType)> {
59 match self.pop() {
60 Some(RibInterpreterStackValue::Sink(vec, analysed_type)) => {
61 Some((vec.clone(), analysed_type))
62 }
63 _ => None,
64 }
65 }
66
67 pub fn pop_n(&mut self, n: usize) -> Option<Vec<RibInterpreterStackValue>> {
68 let mut results = Vec::new();
69 for _ in 0..n {
70 results.push(self.stack.pop()?);
71 }
72 Some(results)
73 }
74
75 pub fn try_pop_n(&mut self, n: usize) -> Result<Vec<RibInterpreterStackValue>, String> {
76 self.pop_n(n).ok_or(format!(
77 "internal error: failed to pop {} values from the interpreter stack",
78 n
79 ))
80 }
81
82 pub fn try_pop_n_val(&mut self, n: usize) -> Result<Vec<ValueAndType>, String> {
83 let stack_values = self.try_pop_n(n)?;
84
85 stack_values
86 .iter()
87 .map(|interpreter_result| {
88 interpreter_result.get_val().ok_or(format!(
89 "internal error: failed to convert last {} in the stack to ValueAndType",
90 n
91 ))
92 })
93 .collect::<Result<Vec<ValueAndType>, String>>()
94 }
95
96 pub fn try_pop_n_literals(&mut self, n: usize) -> Result<Vec<LiteralValue>, String> {
97 let values = self.try_pop_n_val(n)?;
98 values
99 .iter()
100 .map(|type_value| {
101 type_value.get_literal().ok_or(format!(
102 "internal error: failed to convert last {} in the stack to literals {type_value:?}",
103 n
104 ))
105 })
106 .collect::<Result<Vec<_>, String>>()
107 }
108
109 pub fn pop_str(&mut self) -> Option<String> {
110 self.pop_val().and_then(|v| match v {
111 ValueAndType {
112 value: Value::String(s),
113 ..
114 } => Some(s),
115 _ => None,
116 })
117 }
118
119 pub fn pop_val(&mut self) -> Option<ValueAndType> {
120 self.stack.pop().and_then(|v| v.get_val())
121 }
122
123 pub fn try_pop_val(&mut self) -> Result<ValueAndType, String> {
124 self.try_pop().and_then(|x| {
125 x.get_val().ok_or(
126 "internal error: failed to pop ValueAndType from the interpreter stack".to_string(),
127 )
128 })
129 }
130
131 pub fn try_pop_record(&mut self) -> Result<(Vec<Value>, TypeRecord), String> {
132 let value = self.try_pop_val()?;
133
134 match value {
135 ValueAndType {
136 value: Value::Record(field_values),
137 typ: AnalysedType::Record(typ),
138 } => Ok((field_values, typ)),
139 _ => Err("internal error: failed to pop a record from the interpreter".to_string()),
140 }
141 }
142
143 pub fn try_pop_bool(&mut self) -> Result<bool, String> {
144 self.try_pop_val().and_then(|val| {
145 val.get_literal().and_then(|x| x.get_bool()).ok_or(
146 "internal error: failed to pop boolean from the interpreter stack".to_string(),
147 )
148 })
149 }
150
151 pub fn push(&mut self, interpreter_result: RibInterpreterStackValue) {
152 self.stack.push(interpreter_result);
153 }
154
155 pub fn create_sink(&mut self, analysed_type: &AnalysedType) {
156 self.stack.push(RibInterpreterStackValue::Sink(
157 vec![],
158 analysed_type.clone(),
159 ))
160 }
161
162 pub fn push_val(&mut self, element: ValueAndType) {
163 self.stack.push(RibInterpreterStackValue::val(element));
164 }
165
166 pub fn push_to_sink(&mut self, value_and_type: ValueAndType) -> Result<(), String> {
167 let sink = self.pop();
168 let possible_iterator = self
170 .pop()
171 .ok_or("Failed to get the iterator before pushing to the sink")?;
172
173 if !possible_iterator.is_iterator() {
174 return Err("Expecting an the iterator before pushing to the sink".to_string());
175 }
176
177 match sink {
178 Some(RibInterpreterStackValue::Sink(mut list, analysed_type)) => {
179 list.push(value_and_type);
180 self.push(possible_iterator);
181 self.push(RibInterpreterStackValue::Sink(list, analysed_type));
182 Ok(())
183 }
184
185 a => Err(format!(
186 "internal error: failed to push values to sink {:?}",
187 a
188 )),
189 }
190 }
191
192 pub fn push_variant(
193 &mut self,
194 variant_name: String,
195 optional_variant_value: Option<Value>,
196 cases: Vec<NameOptionTypePair>,
197 ) -> Result<(), String> {
198 let case_idx = cases
199 .iter()
200 .position(|case| case.name == variant_name)
201 .ok_or(format!(
202 "internal Error: Failed to find the variant {} in the cases",
203 variant_name
204 ))? as u32;
205
206 let case_value = optional_variant_value.map(Box::new);
207 self.push_val(ValueAndType::new(
208 Value::Variant {
209 case_idx,
210 case_value,
211 },
212 variant(cases),
213 ));
214
215 Ok(())
216 }
217
218 pub fn push_enum(&mut self, enum_name: String, cases: Vec<String>) -> Result<(), String> {
219 let idx = cases.iter().position(|x| x == &enum_name).ok_or_else(|| {
220 format!(
221 "internal error: failed to find the enum {} in the cases",
222 enum_name
223 )
224 })? as u32;
225 self.push_val(ValueAndType::new(
226 Value::Enum(idx),
227 AnalysedType::Enum(TypeEnum {
228 cases: cases.into_iter().collect(),
229 }),
230 ));
231
232 Ok(())
233 }
234
235 pub fn push_some(&mut self, inner_element: Value, inner_type: &AnalysedType) {
236 self.push_val(ValueAndType {
237 value: Value::Option(Some(Box::new(inner_element))),
238 typ: option(inner_type.clone()),
239 });
240 }
241
242 pub fn push_none(&mut self, analysed_type: Option<AnalysedType>) {
246 self.push_val(ValueAndType {
247 value: Value::Option(None),
248 typ: option(analysed_type.unwrap_or(str())), });
250 }
251
252 pub fn push_ok(
253 &mut self,
254 inner_element: Value,
255 ok_type: Option<&AnalysedType>,
256 err_type: Option<&AnalysedType>,
257 ) {
258 self.push_val(ValueAndType {
259 value: Value::Result(Ok(Some(Box::new(inner_element)))),
260 typ: AnalysedType::Result(TypeResult {
261 ok: ok_type.map(|x| Box::new(x.clone())),
262 err: err_type.map(|x| Box::new(x.clone())),
263 }),
264 });
265 }
266
267 pub fn push_err(
268 &mut self,
269 inner_element: Value,
270 ok_type: Option<&AnalysedType>,
271 err_type: Option<&AnalysedType>,
272 ) {
273 self.push_val(ValueAndType {
274 value: Value::Result(Err(Some(Box::new(inner_element)))),
275 typ: AnalysedType::Result(TypeResult {
276 ok: ok_type.map(|x| Box::new(x.clone())),
277 err: err_type.map(|x| Box::new(x.clone())),
278 }),
279 });
280 }
281
282 pub fn push_list(&mut self, values: Vec<Value>, list_elem_type: &AnalysedType) {
283 self.push_val(ValueAndType {
284 value: Value::List(values),
285 typ: list(list_elem_type.clone()),
286 });
287 }
288
289 pub fn push_tuple(&mut self, values: Vec<ValueAndType>) {
290 self.push_val(ValueAndType {
291 value: Value::Tuple(values.iter().map(|x| x.value.clone()).collect()),
292 typ: tuple(values.into_iter().map(|x| x.typ).collect()),
293 });
294 }
295}