Generates text format wasm into `s` to store a value of this type, in its flat representation stored in the `locals` provided, to the local named `ptr` at the `offset` provided. This will register helper functions necessary in `helpers`. The `locals` iterator will be advanced for all locals consumed by this store operation.
(
&'a self,
s: &mut String,
ptr: &str,
offset: u32,
locals: &mut dyn Iterator<Item = FlatSource>,
helpers: &mut IndexSet<Helper<'a>>,
)
| 262 | /// `locals` iterator will be advanced for all locals consumed by this |
| 263 | /// store operation. |
| 264 | fn store_flat<'a>( |
| 265 | &'a self, |
| 266 | s: &mut String, |
| 267 | ptr: &str, |
| 268 | offset: u32, |
| 269 | locals: &mut dyn Iterator<Item = FlatSource>, |
| 270 | helpers: &mut IndexSet<Helper<'a>>, |
| 271 | ) { |
| 272 | enum Kind { |
| 273 | Primitive(&'static str), |
| 274 | PointerPair, |
| 275 | Helper, |
| 276 | } |
| 277 | let kind = match self { |
| 278 | Type::Bool | Type::S8 | Type::U8 => Kind::Primitive("i32.store8"), |
| 279 | Type::S16 | Type::U16 => Kind::Primitive("i32.store16"), |
| 280 | Type::S32 | Type::U32 | Type::Char => Kind::Primitive("i32.store"), |
| 281 | Type::S64 | Type::U64 => Kind::Primitive("i64.store"), |
| 282 | Type::Float32 => Kind::Primitive("f32.store"), |
| 283 | Type::Float64 => Kind::Primitive("f64.store"), |
| 284 | Type::String | Type::List(_) | Type::Map(_, _) => Kind::PointerPair, |
| 285 | Type::Enum(n) if *n <= (1 << 8) => Kind::Primitive("i32.store8"), |
| 286 | Type::Enum(n) if *n <= (1 << 16) => Kind::Primitive("i32.store16"), |
| 287 | Type::Enum(_) => Kind::Primitive("i32.store"), |
| 288 | Type::Flags(n) if *n <= 8 => Kind::Primitive("i32.store8"), |
| 289 | Type::Flags(n) if *n <= 16 => Kind::Primitive("i32.store16"), |
| 290 | Type::Flags(n) if *n <= 32 => Kind::Primitive("i32.store"), |
| 291 | Type::Flags(_) => unreachable!(), |
| 292 | Type::Record(_) |
| 293 | | Type::Tuple(_) |
| 294 | | Type::Variant(_) |
| 295 | | Type::Option(_) |
| 296 | | Type::Result { .. } => Kind::Helper, |
| 297 | }; |
| 298 | |
| 299 | match kind { |
| 300 | Kind::Primitive(op) => uwriteln!( |
| 301 | s, |
| 302 | "({op} offset={offset} (local.get {ptr}) {})", |
| 303 | locals.next().unwrap() |
| 304 | ), |
| 305 | Kind::PointerPair => { |
| 306 | let abi_ptr = locals.next().unwrap(); |
| 307 | let abi_len = locals.next().unwrap(); |
| 308 | uwriteln!(s, "(i32.store offset={offset} (local.get {ptr}) {abi_ptr})",); |
| 309 | let offset = offset + 4; |
| 310 | uwriteln!(s, "(i32.store offset={offset} (local.get {ptr}) {abi_len})",); |
| 311 | } |
| 312 | Kind::Helper => { |
| 313 | let (index, _) = helpers.insert_full(Helper(self)); |
| 314 | uwriteln!(s, "(i32.add (local.get {ptr}) (i32.const {offset}))"); |
| 315 | for _ in 0..self.lowered().len() { |
| 316 | let i = locals.next().unwrap(); |
| 317 | uwriteln!(s, "{i}"); |
| 318 | } |
| 319 | uwriteln!(s, "call $store_helper_{index}"); |
| 320 | } |
| 321 | } |