Build a Wasm module with a single memory in the shape of the given heap image, exports that memory, and also exports four functions: `load{8,16,32,64}`. Each of these functions takes an `i64` address, truncates it to `i32` if the memory is not 64-bit, and loads its associated number of bits from memory at `address + offset`. ```wat (module (memory (export "memory") ...) (func (export "load8") (pa
(image: &HeapImage, offset: u32)
| 256 | /// ) |
| 257 | /// ``` |
| 258 | fn build_wasm(image: &HeapImage, offset: u32) -> Vec<u8> { |
| 259 | let mut module = wasm_encoder::Module::new(); |
| 260 | |
| 261 | { |
| 262 | let mut types = wasm_encoder::TypeSection::new(); |
| 263 | types |
| 264 | .ty() |
| 265 | .function([wasm_encoder::ValType::I64], [wasm_encoder::ValType::I32]); |
| 266 | types |
| 267 | .ty() |
| 268 | .function([wasm_encoder::ValType::I64], [wasm_encoder::ValType::I64]); |
| 269 | module.section(&types); |
| 270 | } |
| 271 | |
| 272 | { |
| 273 | let mut funcs = wasm_encoder::FunctionSection::new(); |
| 274 | funcs.function(0); |
| 275 | funcs.function(0); |
| 276 | funcs.function(0); |
| 277 | funcs.function(1); |
| 278 | module.section(&funcs); |
| 279 | } |
| 280 | |
| 281 | { |
| 282 | let mut memories = wasm_encoder::MemorySection::new(); |
| 283 | memories.memory(wasm_encoder::MemoryType { |
| 284 | minimum: u64::from(image.minimum), |
| 285 | maximum: image.maximum.map(Into::into), |
| 286 | memory64: image.memory64, |
| 287 | shared: false, |
| 288 | page_size_log2: image.page_size_log2, |
| 289 | }); |
| 290 | module.section(&memories); |
| 291 | } |
| 292 | |
| 293 | { |
| 294 | let mut exports = wasm_encoder::ExportSection::new(); |
| 295 | exports.export("memory", wasm_encoder::ExportKind::Memory, 0); |
| 296 | exports.export("load8", wasm_encoder::ExportKind::Func, 0); |
| 297 | exports.export("load16", wasm_encoder::ExportKind::Func, 1); |
| 298 | exports.export("load32", wasm_encoder::ExportKind::Func, 2); |
| 299 | exports.export("load64", wasm_encoder::ExportKind::Func, 3); |
| 300 | module.section(&exports); |
| 301 | } |
| 302 | |
| 303 | { |
| 304 | let mut code = wasm_encoder::CodeSection::new(); |
| 305 | { |
| 306 | let mut func = wasm_encoder::Function::new([]); |
| 307 | func.instruction(&wasm_encoder::Instruction::LocalGet(0)); |
| 308 | if !image.memory64 { |
| 309 | func.instruction(&wasm_encoder::Instruction::I32WrapI64); |
| 310 | } |
| 311 | func.instruction(&wasm_encoder::Instruction::I32Load8U( |
| 312 | wasm_encoder::MemArg { |
| 313 | offset: u64::from(offset), |
| 314 | align: 0, |
| 315 | memory_index: 0, |
no test coverage detected