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