MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / store_flat_helper

Method store_flat_helper

crates/test-util/src/component_fuzz.rs:330–426  ·  view source on GitHub ↗

Generates a text-format wasm function which takes a pointer and this type's flat representation as arguments and then stores this value in the first argument. This is used to store records/variants to cut down on the size of final functions and make codegen here a bit easier.

(
        &'a self,
        s: &mut String,
        i: usize,
        helpers: &mut IndexSet<Helper<'a>>,
    )

Source from the content-addressed store, hash-verified

328 /// This is used to store records/variants to cut down on the size of final
329 /// functions and make codegen here a bit easier.
330 fn store_flat_helper<'a>(
331 &'a self,
332 s: &mut String,
333 i: usize,
334 helpers: &mut IndexSet<Helper<'a>>,
335 ) {
336 uwrite!(s, "(func $store_helper_{i} (param i32)");
337 let lowered = self.lowered();
338 for ty in &lowered {
339 uwrite!(s, " (param {ty})");
340 }
341 s.push_str("\n");
342 let locals = (0..lowered.len() as u32).map(|i| i + 1).collect::<Vec<_>>();
343 let record = |s: &mut String, helpers: &mut IndexSet<Helper<'a>>, types: &'a [Type]| {
344 let mut locals = locals.iter().cloned().map(FlatSource::Local);
345 for (offset, ty) in record_field_offsets(types) {
346 ty.store_flat(s, "0", offset, &mut locals, helpers);
347 }
348 assert!(locals.next().is_none());
349 };
350 let variant = |s: &mut String,
351 helpers: &mut IndexSet<Helper<'a>>,
352 types: &[Option<&'a Type>]| {
353 let (size, offset) = variant_memory_info(types.iter().cloned());
354 // One extra block for out-of-bounds discriminants.
355 for _ in 0..types.len() + 1 {
356 s.push_str("block\n");
357 }
358
359 // Store the discriminant in memory, then branch on it to figure
360 // out which case we're in.
361 let store = match size {
362 DiscriminantSize::Size1 => "i32.store8",
363 DiscriminantSize::Size2 => "i32.store16",
364 DiscriminantSize::Size4 => "i32.store",
365 };
366 uwriteln!(s, "({store} (local.get 0) (local.get 1))");
367 s.push_str("local.get 1\n");
368 s.push_str("br_table");
369 for i in 0..types.len() + 1 {
370 uwrite!(s, " {i}");
371 }
372 s.push_str("\nend\n");
373
374 // Store each payload individually while converting locals from
375 // their source types to the precise type necessary for this
376 // variant.
377 for ty in types {
378 if let Some(ty) = ty {
379 let ty_lowered = ty.lowered();
380 let mut locals = locals[1..].iter().zip(&lowered[1..]).zip(&ty_lowered).map(
381 |((i, from), to)| FlatSource::LocalConvert {
382 local: *i,
383 from: *from,
384 to: *to,
385 },
386 );
387 ty.store_flat(s, "0", offset, &mut locals, helpers);

Callers 1

make_import_and_exportFunction · 0.80

Calls 9

record_field_offsetsFunction · 0.85
variant_memory_infoFunction · 0.85
loweredMethod · 0.80
store_flatMethod · 0.80
push_strMethod · 0.45
mapMethod · 0.45
lenMethod · 0.45
iterMethod · 0.45
as_refMethod · 0.45

Tested by

no test coverage detected