Remove transmutes.

This commit is contained in:
losfair 2019-05-07 19:20:18 +08:00
parent 9c0cbc9775
commit e53d5a91ca
2 changed files with 151 additions and 113 deletions

View File

@ -8,6 +8,7 @@ use inkwell::{
AddressSpace, FloatPredicate, IntPredicate, AddressSpace, FloatPredicate, IntPredicate,
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use std::ops::{Deref, DerefMut};
use std::sync::Arc; use std::sync::Arc;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::{Backend, CacheGen, Token}, backend::{Backend, CacheGen, Token},
@ -292,7 +293,7 @@ fn resolve_memory_ptr(
let var_offset = let var_offset =
builder.build_int_z_extend(var_offset_i32, intrinsics.i64_ty, &state.var_name()); builder.build_int_z_extend(var_offset_i32, intrinsics.i64_ty, &state.var_name());
let effective_offset = builder.build_int_add(var_offset, imm_offset, &state.var_name()); let effective_offset = builder.build_int_add(var_offset, imm_offset, &state.var_name());
let memory_cache = ctx.memory(MemoryIndex::new(0)); let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics);
let mem_base_int = match memory_cache { let mem_base_int = match memory_cache {
MemoryCache::Dynamic { MemoryCache::Dynamic {
@ -363,25 +364,25 @@ pub struct CodegenError {
} }
pub struct LLVMModuleCodeGenerator { pub struct LLVMModuleCodeGenerator {
context: Context, context: Option<Context>,
builder: Builder, builder: Option<Builder>,
intrinsics: Option<Intrinsics>,
functions: Vec<LLVMFunctionCodeGenerator>, functions: Vec<LLVMFunctionCodeGenerator>,
signatures: Map<SigIndex, FunctionType>, signatures: Map<SigIndex, FunctionType>,
signatures_raw: Map<SigIndex, FuncSig>, signatures_raw: Map<SigIndex, FuncSig>,
function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>, function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>,
func_import_count: usize, func_import_count: usize,
intrinsics: Intrinsics,
personality_func: FunctionValue, personality_func: FunctionValue,
module: Module, module: Module,
} }
pub struct LLVMFunctionCodeGenerator { pub struct LLVMFunctionCodeGenerator {
context: Option<Context>,
builder: Option<Builder>,
intrinsics: Option<Intrinsics>,
state: State, state: State,
builder: &'static Builder,
context: &'static Context,
function: FunctionValue, function: FunctionValue,
func_sig: FuncSig, func_sig: FuncSig,
intrinsics: &'static Intrinsics,
signatures: Map<SigIndex, FunctionType>, signatures: Map<SigIndex, FunctionType>,
locals: Vec<PointerValue>, // Contains params and locals locals: Vec<PointerValue>, // Contains params and locals
num_params: usize, num_params: usize,
@ -405,21 +406,23 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
// let (count, ty) = local?; // let (count, ty) = local?;
let count = n; let count = n;
let wasmer_ty = type_to_type(ty)?; let wasmer_ty = type_to_type(ty)?;
let ty = type_to_llvm(self.intrinsics, wasmer_ty);
let intrinsics = self.intrinsics.as_ref().unwrap();
let ty = type_to_llvm(intrinsics, wasmer_ty);
let default_value = match wasmer_ty { let default_value = match wasmer_ty {
Type::I32 => self.intrinsics.i32_zero.as_basic_value_enum(), Type::I32 => intrinsics.i32_zero.as_basic_value_enum(),
Type::I64 => self.intrinsics.i64_zero.as_basic_value_enum(), Type::I64 => intrinsics.i64_zero.as_basic_value_enum(),
Type::F32 => self.intrinsics.f32_zero.as_basic_value_enum(), Type::F32 => intrinsics.f32_zero.as_basic_value_enum(),
Type::F64 => self.intrinsics.f64_zero.as_basic_value_enum(), Type::F64 => intrinsics.f64_zero.as_basic_value_enum(),
}; };
for _ in 0..count { let builder = self.builder.as_ref().unwrap();
let alloca = self
.builder
.build_alloca(ty, &format!("local{}", param_len + local_idx));
self.builder.build_store(alloca, default_value); for _ in 0..count {
let alloca = builder.build_alloca(ty, &format!("local{}", param_len + local_idx));
builder.build_store(alloca, default_value);
self.locals.push(alloca); self.locals.push(alloca);
local_idx += 1; local_idx += 1;
@ -430,22 +433,27 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
fn begin_body(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError> { fn begin_body(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError> {
let start_of_code_block = self let start_of_code_block = self
.context .context
.as_ref()
.unwrap()
.append_basic_block(&self.function, "start_of_code"); .append_basic_block(&self.function, "start_of_code");
let entry_end_inst = self let entry_end_inst = self
.builder .builder
.as_ref()
.unwrap()
.build_unconditional_branch(&start_of_code_block); .build_unconditional_branch(&start_of_code_block);
self.builder.position_at_end(&start_of_code_block); self.builder
.as_ref()
.unwrap()
.position_at_end(&start_of_code_block);
let cache_builder = self.context.create_builder(); let cache_builder = self.context.as_ref().unwrap().create_builder();
cache_builder.position_before(&entry_end_inst); cache_builder.position_before(&entry_end_inst);
let module_info = let module_info =
unsafe { ::std::mem::transmute::<&ModuleInfo, &'static ModuleInfo>(module_info) }; unsafe { ::std::mem::transmute::<&ModuleInfo, &'static ModuleInfo>(module_info) };
let function = unsafe { let function = unsafe {
::std::mem::transmute::<&FunctionValue, &'static FunctionValue>(&self.function) ::std::mem::transmute::<&FunctionValue, &'static FunctionValue>(&self.function)
}; };
let ctx = self let ctx = CtxType::new(module_info, function, cache_builder);
.intrinsics
.ctx(module_info, self.builder, function, cache_builder);
self.ctx = Some(ctx); self.ctx = Some(ctx);
Ok(()) Ok(())
@ -460,10 +468,10 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
}; };
let mut state = &mut self.state; let mut state = &mut self.state;
let builder = self.builder; let builder = self.builder.as_ref().unwrap();
let context = self.context; let context = self.context.as_ref().unwrap();
let function = self.function; let function = self.function;
let intrinsics = self.intrinsics; let intrinsics = self.intrinsics.as_ref().unwrap();
let locals = &self.locals; let locals = &self.locals;
let info = module_info; let info = module_info;
let signatures = &self.signatures; let signatures = &self.signatures;
@ -868,7 +876,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
Operator::GetGlobal { global_index } => { Operator::GetGlobal { global_index } => {
let index = GlobalIndex::new(global_index as usize); let index = GlobalIndex::new(global_index as usize);
let global_cache = ctx.global_cache(index); let global_cache = ctx.global_cache(index, intrinsics);
match global_cache { match global_cache {
GlobalCache::Const { value } => { GlobalCache::Const { value } => {
state.push1(value); state.push1(value);
@ -882,7 +890,7 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
Operator::SetGlobal { global_index } => { Operator::SetGlobal { global_index } => {
let value = state.pop1()?; let value = state.pop1()?;
let index = GlobalIndex::new(global_index as usize); let index = GlobalIndex::new(global_index as usize);
let global_cache = ctx.global_cache(index); let global_cache = ctx.global_cache(index, intrinsics);
match global_cache { match global_cache {
GlobalCache::Mut { ptr_to_value } => { GlobalCache::Mut { ptr_to_value } => {
builder.build_store(ptr_to_value, value); builder.build_store(ptr_to_value, value);
@ -918,12 +926,14 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
.map(|v| *v) .map(|v| *v)
.collect(); .collect();
let func_ptr = ctx.local_func(local_func_index, llvm_sig); let func_ptr =
ctx.local_func(local_func_index, llvm_sig, intrinsics, builder);
builder.build_call(func_ptr, &params, &state.var_name()) builder.build_call(func_ptr, &params, &state.var_name())
} }
LocalOrImport::Import(import_func_index) => { LocalOrImport::Import(import_func_index) => {
let (func_ptr_untyped, ctx_ptr) = ctx.imported_func(import_func_index); let (func_ptr_untyped, ctx_ptr) =
ctx.imported_func(import_func_index, intrinsics);
let params: Vec<_> = [ctx_ptr.as_basic_value_enum()] let params: Vec<_> = [ctx_ptr.as_basic_value_enum()]
.iter() .iter()
.chain(state.peekn(func_sig.params().len())?.iter()) .chain(state.peekn(func_sig.params().len())?.iter())
@ -962,8 +972,9 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
} }
Operator::CallIndirect { index, table_index } => { Operator::CallIndirect { index, table_index } => {
let sig_index = SigIndex::new(index as usize); let sig_index = SigIndex::new(index as usize);
let expected_dynamic_sigindex = ctx.dynamic_sigindex(sig_index); let expected_dynamic_sigindex = ctx.dynamic_sigindex(sig_index, intrinsics);
let (table_base, table_bound) = ctx.table(TableIndex::new(table_index as usize)); let (table_base, table_bound) =
ctx.table(TableIndex::new(table_index as usize), intrinsics, builder);
let func_index = state.pop1()?.into_int_value(); let func_index = state.pop1()?.into_int_value();
// We assume the table has the `anyfunc` element type. // We assume the table has the `anyfunc` element type.
@ -2404,10 +2415,10 @@ impl FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator {
match results.as_slice() { match results.as_slice() {
[] => { [] => {
self.builder.build_return(None); self.builder.as_ref().unwrap().build_return(None);
} }
[one_value] => { [one_value] => {
self.builder.build_return(Some(one_value)); self.builder.as_ref().unwrap().build_return(Some(one_value));
} }
_ => { _ => {
// let struct_ty = llvm_sig.get_return_type().as_struct_type(); // let struct_ty = llvm_sig.get_return_type().as_struct_type();
@ -2446,15 +2457,15 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
let signatures = Map::new(); let signatures = Map::new();
LLVMModuleCodeGenerator { LLVMModuleCodeGenerator {
context, context: Some(context),
builder, builder: Some(builder),
intrinsics: Some(intrinsics),
module, module,
functions: vec![], functions: vec![],
signatures, signatures,
signatures_raw: Map::new(), signatures_raw: Map::new(),
function_signatures: None, function_signatures: None,
func_import_count: 0, func_import_count: 0,
intrinsics,
personality_func, personality_func,
} }
} }
@ -2469,6 +2480,18 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
fn next_function(&mut self) -> Result<&mut LLVMFunctionCodeGenerator, CodegenError> { fn next_function(&mut self) -> Result<&mut LLVMFunctionCodeGenerator, CodegenError> {
// Creates a new function and returns the function-scope code generator for it. // Creates a new function and returns the function-scope code generator for it.
let (context, builder, intrinsics) = match self.functions.last_mut() {
Some(x) => (
x.context.take().unwrap(),
x.builder.take().unwrap(),
x.intrinsics.take().unwrap(),
),
None => (
self.context.take().unwrap(),
self.builder.take().unwrap(),
self.intrinsics.take().unwrap(),
),
};
let sig_id = self.function_signatures.as_ref().unwrap() let sig_id = self.function_signatures.as_ref().unwrap()
[FuncIndex::new(self.func_import_count + self.functions.len())]; [FuncIndex::new(self.func_import_count + self.functions.len())];
@ -2482,20 +2505,20 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
function.set_personality_function(self.personality_func); function.set_personality_function(self.personality_func);
let mut state = State::new(); let mut state = State::new();
let entry_block = self.context.append_basic_block(&function, "entry"); let entry_block = context.append_basic_block(&function, "entry");
let return_block = self.context.append_basic_block(&function, "return"); let return_block = context.append_basic_block(&function, "return");
self.builder.position_at_end(&return_block); builder.position_at_end(&return_block);
let phis: SmallVec<[PhiValue; 1]> = func_sig let phis: SmallVec<[PhiValue; 1]> = func_sig
.returns() .returns()
.iter() .iter()
.map(|&wasmer_ty| type_to_llvm(&self.intrinsics, wasmer_ty)) .map(|&wasmer_ty| type_to_llvm(&intrinsics, wasmer_ty))
.map(|ty| self.builder.build_phi(ty, &state.var_name())) .map(|ty| builder.build_phi(ty, &state.var_name()))
.collect(); .collect();
state.push_block(return_block, phis); state.push_block(return_block, phis);
self.builder.position_at_end(&entry_block); builder.position_at_end(&entry_block);
let mut locals = Vec::new(); let mut locals = Vec::new();
locals.extend( locals.extend(
@ -2506,8 +2529,8 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
.map(|(index, param)| { .map(|(index, param)| {
let ty = param.get_type(); let ty = param.get_type();
let alloca = self.builder.build_alloca(ty, &format!("local{}", index)); let alloca = builder.build_alloca(ty, &format!("local{}", index));
self.builder.build_store(alloca, param); builder.build_store(alloca, param);
alloca alloca
}), }),
); );
@ -2515,16 +2538,14 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
let code = LLVMFunctionCodeGenerator { let code = LLVMFunctionCodeGenerator {
state, state,
builder: unsafe { ::std::mem::transmute::<&Builder, &'static Builder>(&self.builder) }, context: Some(context),
context: unsafe { ::std::mem::transmute::<&Context, &'static Context>(&self.context) }, builder: Some(builder),
intrinsics: Some(intrinsics),
function, function,
func_sig: func_sig, func_sig: func_sig,
locals, locals,
signatures: self.signatures.clone(), signatures: self.signatures.clone(),
num_params, num_params,
intrinsics: unsafe {
::std::mem::transmute::<&Intrinsics, &'static Intrinsics>(&self.intrinsics)
},
ctx: None, ctx: None,
unreachable_depth: 0, unreachable_depth: 0,
}; };
@ -2533,18 +2554,33 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
} }
fn finalize( fn finalize(
self, mut self,
module_info: &ModuleInfo, module_info: &ModuleInfo,
) -> Result<(LLVMBackend, Box<dyn CacheGen>), CodegenError> { ) -> Result<(LLVMBackend, Box<dyn CacheGen>), CodegenError> {
// self.module.print_to_stderr(); // self.module.print_to_stderr();
let (context, builder, intrinsics) = match self.functions.last_mut() {
Some(x) => (
x.context.take().unwrap(),
x.builder.take().unwrap(),
x.intrinsics.take().unwrap(),
),
None => (
self.context.take().unwrap(),
self.builder.take().unwrap(),
self.intrinsics.take().unwrap(),
),
};
self.context = Some(context);
self.builder = Some(builder);
self.intrinsics = Some(intrinsics);
generate_trampolines( generate_trampolines(
module_info, module_info,
&self.signatures, &self.signatures,
&self.module, &self.module,
&self.context, self.context.as_ref().unwrap(),
&self.builder, self.builder.as_ref().unwrap(),
&self.intrinsics, self.intrinsics.as_ref().unwrap(),
); );
let pass_manager = PassManager::create_for_module(); let pass_manager = PassManager::create_for_module();
@ -2563,14 +2599,20 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
// self.module.print_to_stderr(); // self.module.print_to_stderr();
let (backend, cache_gen) = LLVMBackend::new(self.module, self.intrinsics); let (backend, cache_gen) = LLVMBackend::new(self.module, self.intrinsics.take().unwrap());
Ok((backend, Box::new(cache_gen))) Ok((backend, Box::new(cache_gen)))
} }
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> { fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
self.signatures = signatures self.signatures = signatures
.iter() .iter()
.map(|(_, sig)| func_sig_to_llvm(&self.context, &self.intrinsics, sig)) .map(|(_, sig)| {
func_sig_to_llvm(
self.context.as_ref().unwrap(),
self.intrinsics.as_ref().unwrap(),
sig,
)
})
.collect(); .collect();
self.signatures_raw = signatures.clone(); self.signatures_raw = signatures.clone();
Ok(()) Ok(())

View File

@ -369,31 +369,6 @@ impl Intrinsics {
ctx_ptr_ty, ctx_ptr_ty,
} }
} }
pub fn ctx<'a>(
&'a self,
info: &'a ModuleInfo,
builder: &'a Builder,
func_value: &'a FunctionValue,
cache_builder: Builder,
) -> CtxType<'a> {
CtxType {
ctx_ptr_value: func_value.get_nth_param(0).unwrap().into_pointer_value(),
builder,
intrinsics: self,
info,
cache_builder,
cached_memories: HashMap::new(),
cached_tables: HashMap::new(),
cached_sigindices: HashMap::new(),
cached_globals: HashMap::new(),
cached_imported_functions: HashMap::new(),
_phantom: PhantomData,
}
}
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -429,8 +404,6 @@ struct ImportedFuncCache {
pub struct CtxType<'a> { pub struct CtxType<'a> {
ctx_ptr_value: PointerValue, ctx_ptr_value: PointerValue,
builder: &'a Builder,
intrinsics: &'a Intrinsics,
info: &'a ModuleInfo, info: &'a ModuleInfo,
cache_builder: Builder, cache_builder: Builder,
@ -444,16 +417,36 @@ pub struct CtxType<'a> {
} }
impl<'a> CtxType<'a> { impl<'a> CtxType<'a> {
pub fn new(
info: &'a ModuleInfo,
func_value: &'a FunctionValue,
cache_builder: Builder,
) -> CtxType<'a> {
CtxType {
ctx_ptr_value: func_value.get_nth_param(0).unwrap().into_pointer_value(),
info,
cache_builder,
cached_memories: HashMap::new(),
cached_tables: HashMap::new(),
cached_sigindices: HashMap::new(),
cached_globals: HashMap::new(),
cached_imported_functions: HashMap::new(),
_phantom: PhantomData,
}
}
pub fn basic(&self) -> BasicValueEnum { pub fn basic(&self) -> BasicValueEnum {
self.ctx_ptr_value.as_basic_value_enum() self.ctx_ptr_value.as_basic_value_enum()
} }
pub fn memory(&mut self, index: MemoryIndex) -> MemoryCache { pub fn memory(&mut self, index: MemoryIndex, intrinsics: &Intrinsics) -> MemoryCache {
let (cached_memories, info, ctx_ptr_value, intrinsics, cache_builder) = ( let (cached_memories, info, ctx_ptr_value, cache_builder) = (
&mut self.cached_memories, &mut self.cached_memories,
self.info, self.info,
self.ctx_ptr_value, self.ctx_ptr_value,
self.intrinsics,
&self.cache_builder, &self.cache_builder,
); );
@ -514,13 +507,16 @@ impl<'a> CtxType<'a> {
}) })
} }
pub fn table(&mut self, index: TableIndex) -> (PointerValue, IntValue) { pub fn table(
let (cached_tables, builder, info, ctx_ptr_value, intrinsics, cache_builder) = ( &mut self,
index: TableIndex,
intrinsics: &Intrinsics,
builder: &Builder,
) -> (PointerValue, IntValue) {
let (cached_tables, info, ctx_ptr_value, cache_builder) = (
&mut self.cached_tables, &mut self.cached_tables,
self.builder,
self.info, self.info,
self.ctx_ptr_value, self.ctx_ptr_value,
self.intrinsics,
&self.cache_builder, &self.cache_builder,
); );
@ -575,41 +571,39 @@ impl<'a> CtxType<'a> {
) )
} }
pub fn local_func(&mut self, index: LocalFuncIndex, fn_ty: FunctionType) -> PointerValue { pub fn local_func(
let local_func_array_ptr_ptr = unsafe { &mut self,
self.builder index: LocalFuncIndex,
.build_struct_gep(self.ctx_ptr_value, 8, "local_func_array_ptr_ptr") fn_ty: FunctionType,
}; intrinsics: &Intrinsics,
let local_func_array_ptr = self builder: &Builder,
.builder ) -> PointerValue {
let local_func_array_ptr_ptr =
unsafe { builder.build_struct_gep(self.ctx_ptr_value, 8, "local_func_array_ptr_ptr") };
let local_func_array_ptr = builder
.build_load(local_func_array_ptr_ptr, "local_func_array_ptr") .build_load(local_func_array_ptr_ptr, "local_func_array_ptr")
.into_pointer_value(); .into_pointer_value();
let local_func_ptr_ptr = unsafe { let local_func_ptr_ptr = unsafe {
self.builder.build_in_bounds_gep( builder.build_in_bounds_gep(
local_func_array_ptr, local_func_array_ptr,
&[self &[intrinsics.i32_ty.const_int(index.index() as u64, false)],
.intrinsics
.i32_ty
.const_int(index.index() as u64, false)],
"local_func_ptr_ptr", "local_func_ptr_ptr",
) )
}; };
let local_func_ptr = self let local_func_ptr = builder
.builder
.build_load(local_func_ptr_ptr, "local_func_ptr") .build_load(local_func_ptr_ptr, "local_func_ptr")
.into_pointer_value(); .into_pointer_value();
self.builder.build_pointer_cast( builder.build_pointer_cast(
local_func_ptr, local_func_ptr,
fn_ty.ptr_type(AddressSpace::Generic), fn_ty.ptr_type(AddressSpace::Generic),
"local_func_ptr", "local_func_ptr",
) )
} }
pub fn dynamic_sigindex(&mut self, index: SigIndex) -> IntValue { pub fn dynamic_sigindex(&mut self, index: SigIndex, intrinsics: &Intrinsics) -> IntValue {
let (cached_sigindices, ctx_ptr_value, intrinsics, cache_builder) = ( let (cached_sigindices, ctx_ptr_value, cache_builder) = (
&mut self.cached_sigindices, &mut self.cached_sigindices,
self.ctx_ptr_value, self.ctx_ptr_value,
self.intrinsics,
&self.cache_builder, &self.cache_builder,
); );
@ -636,12 +630,11 @@ impl<'a> CtxType<'a> {
}) })
} }
pub fn global_cache(&mut self, index: GlobalIndex) -> GlobalCache { pub fn global_cache(&mut self, index: GlobalIndex, intrinsics: &Intrinsics) -> GlobalCache {
let (cached_globals, ctx_ptr_value, info, intrinsics, cache_builder) = ( let (cached_globals, ctx_ptr_value, info, cache_builder) = (
&mut self.cached_globals, &mut self.cached_globals,
self.ctx_ptr_value, self.ctx_ptr_value,
self.info, self.info,
self.intrinsics,
&self.cache_builder, &self.cache_builder,
); );
@ -712,11 +705,14 @@ impl<'a> CtxType<'a> {
}) })
} }
pub fn imported_func(&mut self, index: ImportedFuncIndex) -> (PointerValue, PointerValue) { pub fn imported_func(
let (cached_imported_functions, ctx_ptr_value, intrinsics, cache_builder) = ( &mut self,
index: ImportedFuncIndex,
intrinsics: &Intrinsics,
) -> (PointerValue, PointerValue) {
let (cached_imported_functions, ctx_ptr_value, cache_builder) = (
&mut self.cached_imported_functions, &mut self.cached_imported_functions,
self.ctx_ptr_value, self.ctx_ptr_value,
self.intrinsics,
&self.cache_builder, &self.cache_builder,
); );