(
&mut self,
callee: ir::Value,
callee_load_trap_code: Option<ir::TrapCode>,
)
| 2343 | } |
| 2344 | |
| 2345 | fn load_code_and_vmctx( |
| 2346 | &mut self, |
| 2347 | callee: ir::Value, |
| 2348 | callee_load_trap_code: Option<ir::TrapCode>, |
| 2349 | ) -> (ir::Value, ir::Value) { |
| 2350 | let pointer_type = self.env.pointer_type(); |
| 2351 | |
| 2352 | // Dereference callee pointer to get the function address. |
| 2353 | // |
| 2354 | // Note that this may trap if `callee` hasn't previously been verified |
| 2355 | // to be non-null. This means that this load is annotated with an |
| 2356 | // optional trap code provided by the caller of `unchecked_call` which |
| 2357 | // will handle the case where this is either already known to be |
| 2358 | // non-null or may trap. |
| 2359 | let mem_flags = ir::MemFlagsData::trusted().with_readonly(); |
| 2360 | let mut callee_flags = mem_flags; |
| 2361 | if self.env.clif_memory_traps_enabled() { |
| 2362 | callee_flags = callee_flags.with_trap_code(callee_load_trap_code); |
| 2363 | } else { |
| 2364 | if let Some(trap) = callee_load_trap_code { |
| 2365 | self.env.trapz(self.builder, callee, trap); |
| 2366 | } |
| 2367 | } |
| 2368 | let func_addr = self.builder.ins().load( |
| 2369 | pointer_type, |
| 2370 | callee_flags, |
| 2371 | callee, |
| 2372 | i32::from(self.env.offsets.ptr.vm_func_ref_wasm_call()), |
| 2373 | ); |
| 2374 | let callee_vmctx = self.builder.ins().load( |
| 2375 | pointer_type, |
| 2376 | mem_flags, |
| 2377 | callee, |
| 2378 | i32::from(self.env.offsets.ptr.vm_func_ref_vmctx()), |
| 2379 | ); |
| 2380 | |
| 2381 | (func_addr, callee_vmctx) |
| 2382 | } |
| 2383 | |
| 2384 | fn caller_vmctx(&self) -> ir::Value { |
| 2385 | self.builder |
no test coverage detected