1use crate::interpreter::interpreter_stack_value::RibInterpreterStackValue;
16use crate::GetLiteralValue;
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 pop_str(&mut self) -> Option<String> {
97 self.pop_val().and_then(|v| match v {
98 ValueAndType {
99 value: Value::String(s),
100 ..
101 } => Some(s),
102 _ => None,
103 })
104 }
105
106 pub fn pop_val(&mut self) -> Option<ValueAndType> {
107 self.stack.pop().and_then(|v| v.get_val())
108 }
109
110 pub fn try_pop_val(&mut self) -> Result<ValueAndType, String> {
111 self.try_pop().and_then(|x| {
112 x.get_val().ok_or(
113 "internal error: failed to pop ValueAndType from the interpreter stack".to_string(),
114 )
115 })
116 }
117
118 pub fn try_pop_record(&mut self) -> Result<(Vec<Value>, TypeRecord), String> {
119 let value = self.try_pop_val()?;
120
121 match value {
122 ValueAndType {
123 value: Value::Record(field_values),
124 typ: AnalysedType::Record(typ),
125 } => Ok((field_values, typ)),
126 _ => Err("internal error: failed to pop a record from the interpreter".to_string()),
127 }
128 }
129
130 pub fn try_pop_bool(&mut self) -> Result<bool, String> {
131 self.try_pop_val().and_then(|val| {
132 val.get_literal().and_then(|x| x.get_bool()).ok_or(
133 "internal error: failed to pop boolean from the interpreter stack".to_string(),
134 )
135 })
136 }
137
138 pub fn push(&mut self, interpreter_result: RibInterpreterStackValue) {
139 self.stack.push(interpreter_result);
140 }
141
142 pub fn create_sink(&mut self, analysed_type: &AnalysedType) {
143 self.stack.push(RibInterpreterStackValue::Sink(
144 vec![],
145 analysed_type.clone(),
146 ))
147 }
148
149 pub fn push_val(&mut self, element: ValueAndType) {
150 self.stack.push(RibInterpreterStackValue::val(element));
151 }
152
153 pub fn push_to_sink(&mut self, value_and_type: ValueAndType) -> Result<(), String> {
154 let sink = self.pop();
155 let possible_iterator = self
157 .pop()
158 .ok_or("Failed to get the iterator before pushing to the sink")?;
159
160 if !possible_iterator.is_iterator() {
161 return Err("Expecting an the iterator before pushing to the sink".to_string());
162 }
163
164 match sink {
165 Some(RibInterpreterStackValue::Sink(mut list, analysed_type)) => {
166 list.push(value_and_type);
167 self.push(possible_iterator);
168 self.push(RibInterpreterStackValue::Sink(list, analysed_type));
169 Ok(())
170 }
171
172 a => Err(format!(
173 "internal error: failed to push values to sink {:?}",
174 a
175 )),
176 }
177 }
178
179 pub fn push_variant(
180 &mut self,
181 variant_name: String,
182 optional_variant_value: Option<Value>,
183 cases: Vec<NameOptionTypePair>,
184 ) -> Result<(), String> {
185 let case_idx = cases
186 .iter()
187 .position(|case| case.name == variant_name)
188 .ok_or(format!(
189 "internal Error: Failed to find the variant {} in the cases",
190 variant_name
191 ))? as u32;
192
193 let case_value = optional_variant_value.map(Box::new);
194 self.push_val(ValueAndType::new(
195 Value::Variant {
196 case_idx,
197 case_value,
198 },
199 variant(cases),
200 ));
201
202 Ok(())
203 }
204
205 pub fn push_enum(&mut self, enum_name: String, cases: Vec<String>) -> Result<(), String> {
206 let idx = cases.iter().position(|x| x == &enum_name).ok_or_else(|| {
207 format!(
208 "internal error: failed to find the enum {} in the cases",
209 enum_name
210 )
211 })? as u32;
212 self.push_val(ValueAndType::new(
213 Value::Enum(idx),
214 AnalysedType::Enum(TypeEnum {
215 cases: cases.into_iter().collect(),
216 }),
217 ));
218
219 Ok(())
220 }
221
222 pub fn push_some(&mut self, inner_element: Value, inner_type: &AnalysedType) {
223 self.push_val(ValueAndType {
224 value: Value::Option(Some(Box::new(inner_element))),
225 typ: option(inner_type.clone()),
226 });
227 }
228
229 pub fn push_none(&mut self, analysed_type: Option<AnalysedType>) {
233 self.push_val(ValueAndType {
234 value: Value::Option(None),
235 typ: option(analysed_type.unwrap_or(str())), });
237 }
238
239 pub fn push_ok(
240 &mut self,
241 inner_element: Value,
242 ok_type: Option<&AnalysedType>,
243 err_type: Option<&AnalysedType>,
244 ) {
245 self.push_val(ValueAndType {
246 value: Value::Result(Ok(Some(Box::new(inner_element)))),
247 typ: AnalysedType::Result(TypeResult {
248 ok: ok_type.map(|x| Box::new(x.clone())),
249 err: err_type.map(|x| Box::new(x.clone())),
250 }),
251 });
252 }
253
254 pub fn push_err(
255 &mut self,
256 inner_element: Value,
257 ok_type: Option<&AnalysedType>,
258 err_type: Option<&AnalysedType>,
259 ) {
260 self.push_val(ValueAndType {
261 value: Value::Result(Err(Some(Box::new(inner_element)))),
262 typ: AnalysedType::Result(TypeResult {
263 ok: ok_type.map(|x| Box::new(x.clone())),
264 err: err_type.map(|x| Box::new(x.clone())),
265 }),
266 });
267 }
268
269 pub fn push_list(&mut self, values: Vec<Value>, list_elem_type: &AnalysedType) {
270 self.push_val(ValueAndType {
271 value: Value::List(values),
272 typ: list(list_elem_type.clone()),
273 });
274 }
275
276 pub fn push_tuple(&mut self, values: Vec<ValueAndType>) {
277 self.push_val(ValueAndType {
278 value: Value::Tuple(values.iter().map(|x| x.value.clone()).collect()),
279 typ: tuple(values.into_iter().map(|x| x.typ).collect()),
280 });
281 }
282}