mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 13:18:20 +00:00
Make abi a trait.
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
use crate::config::{CompiledKind, LLVM};
|
||||
use crate::object_file::{load_object_file, CompiledFunction};
|
||||
use crate::translator::abi::{
|
||||
func_type_to_llvm, get_vmctx_ptr_param, is_sret, pack_values_for_register_return,
|
||||
rets_from_call,
|
||||
};
|
||||
use crate::translator::abi::{Abi, X86_64SystemV};
|
||||
use crate::translator::intrinsics::{type_to_llvm, type_to_llvm_ptr, Intrinsics};
|
||||
use inkwell::{
|
||||
attributes::{Attribute, AttributeLoc},
|
||||
@@ -23,6 +20,7 @@ use wasmer_types::{FunctionType, LocalFunctionIndex};
|
||||
pub struct FuncTrampoline {
|
||||
ctx: Context,
|
||||
target_machine: TargetMachine,
|
||||
abi: Box<dyn Abi>,
|
||||
}
|
||||
|
||||
const FUNCTION_SECTION: &str = "__TEXT,wasmer_trmpl"; // Needs to be between 1 and 16 chars
|
||||
@@ -32,6 +30,7 @@ impl FuncTrampoline {
|
||||
Self {
|
||||
ctx: Context::create(),
|
||||
target_machine,
|
||||
abi: Box::new(X86_64SystemV {}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +49,7 @@ impl FuncTrampoline {
|
||||
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
|
||||
let intrinsics = Intrinsics::declare(&module, &self.ctx);
|
||||
|
||||
let (callee_ty, callee_attrs) = func_type_to_llvm(&self.ctx, &intrinsics, ty)?;
|
||||
let (callee_ty, callee_attrs) = self.abi.func_type_to_llvm(&self.ctx, &intrinsics, ty)?;
|
||||
let trampoline_ty = intrinsics.void_ty.fn_type(
|
||||
&[
|
||||
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // vmctx ptr
|
||||
@@ -72,7 +71,7 @@ impl FuncTrampoline {
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_dll_storage_class(DLLStorageClass::Export);
|
||||
generate_trampoline(trampoline_func, ty, &callee_attrs, &self.ctx, &intrinsics)?;
|
||||
self.generate_trampoline(trampoline_func, ty, &callee_attrs, &self.ctx, &intrinsics)?;
|
||||
|
||||
if let Some(ref callbacks) = config.callbacks {
|
||||
callbacks.preopt_ir(&function, &module);
|
||||
@@ -180,7 +179,8 @@ impl FuncTrampoline {
|
||||
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
|
||||
let intrinsics = Intrinsics::declare(&module, &self.ctx);
|
||||
|
||||
let (trampoline_ty, trampoline_attrs) = func_type_to_llvm(&self.ctx, &intrinsics, ty)?;
|
||||
let (trampoline_ty, trampoline_attrs) =
|
||||
self.abi.func_type_to_llvm(&self.ctx, &intrinsics, ty)?;
|
||||
let trampoline_func = module.add_function(name, trampoline_ty, Some(Linkage::External));
|
||||
for (attr, attr_loc) in trampoline_attrs {
|
||||
trampoline_func.add_attribute(attr_loc, attr);
|
||||
@@ -194,7 +194,7 @@ impl FuncTrampoline {
|
||||
trampoline_func
|
||||
.as_global_value()
|
||||
.set_dll_storage_class(DLLStorageClass::Export);
|
||||
generate_dynamic_trampoline(trampoline_func, ty, &self.ctx, &intrinsics)?;
|
||||
self.generate_dynamic_trampoline(trampoline_func, ty, &self.ctx, &intrinsics)?;
|
||||
|
||||
if let Some(ref callbacks) = config.callbacks {
|
||||
callbacks.preopt_ir(&function, &module);
|
||||
@@ -286,225 +286,231 @@ impl FuncTrampoline {
|
||||
unwind_info: compiled_function.body.unwind_info,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_trampoline<'ctx>(
|
||||
trampoline_func: FunctionValue,
|
||||
func_sig: &FunctionType,
|
||||
func_attrs: &[(Attribute, AttributeLoc)],
|
||||
context: &'ctx Context,
|
||||
intrinsics: &Intrinsics<'ctx>,
|
||||
) -> Result<(), CompileError> {
|
||||
let entry_block = context.append_basic_block(trampoline_func, "entry");
|
||||
let builder = context.create_builder();
|
||||
builder.position_at_end(entry_block);
|
||||
fn generate_trampoline<'ctx>(
|
||||
&self,
|
||||
trampoline_func: FunctionValue,
|
||||
func_sig: &FunctionType,
|
||||
func_attrs: &[(Attribute, AttributeLoc)],
|
||||
context: &'ctx Context,
|
||||
intrinsics: &Intrinsics<'ctx>,
|
||||
) -> Result<(), CompileError> {
|
||||
let entry_block = context.append_basic_block(trampoline_func, "entry");
|
||||
let builder = context.create_builder();
|
||||
builder.position_at_end(entry_block);
|
||||
|
||||
/*
|
||||
// TODO: remove debugging
|
||||
builder.build_call(
|
||||
intrinsics.debug_trap,
|
||||
&[],
|
||||
"");
|
||||
*/
|
||||
/*
|
||||
// TODO: remove debugging
|
||||
builder.build_call(
|
||||
intrinsics.debug_trap,
|
||||
&[],
|
||||
"");
|
||||
*/
|
||||
|
||||
let (callee_vmctx_ptr, func_ptr, args_rets_ptr) = match *trampoline_func.get_params().as_slice()
|
||||
{
|
||||
[callee_vmctx_ptr, func_ptr, args_rets_ptr] => (
|
||||
callee_vmctx_ptr,
|
||||
func_ptr.into_pointer_value(),
|
||||
args_rets_ptr.into_pointer_value(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline function unimplemented".to_string(),
|
||||
))
|
||||
let (callee_vmctx_ptr, func_ptr, args_rets_ptr) =
|
||||
match *trampoline_func.get_params().as_slice() {
|
||||
[callee_vmctx_ptr, func_ptr, args_rets_ptr] => (
|
||||
callee_vmctx_ptr,
|
||||
func_ptr.into_pointer_value(),
|
||||
args_rets_ptr.into_pointer_value(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CompileError::Codegen(
|
||||
"trampoline function unimplemented".to_string(),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
let mut args_vec = Vec::with_capacity(func_sig.params().len() + 1);
|
||||
|
||||
if self.abi.is_sret(func_sig)? {
|
||||
let basic_types: Vec<_> = func_sig
|
||||
.results()
|
||||
.iter()
|
||||
.map(|&ty| type_to_llvm(intrinsics, ty))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
let sret_ty = context.struct_type(&basic_types, false);
|
||||
args_vec.push(builder.build_alloca(sret_ty, "sret").into());
|
||||
}
|
||||
};
|
||||
|
||||
let mut args_vec = Vec::with_capacity(func_sig.params().len() + 1);
|
||||
args_vec.push(callee_vmctx_ptr);
|
||||
|
||||
if is_sret(func_sig)? {
|
||||
let basic_types: Vec<_> = func_sig
|
||||
.results()
|
||||
.iter()
|
||||
.map(|&ty| type_to_llvm(intrinsics, ty))
|
||||
.collect::<Result<_, _>>()?;
|
||||
for (i, param_ty) in func_sig.params().iter().enumerate() {
|
||||
let index = intrinsics.i32_ty.const_int(i as _, false);
|
||||
let item_pointer =
|
||||
unsafe { builder.build_in_bounds_gep(args_rets_ptr, &[index], "arg_ptr") };
|
||||
|
||||
let sret_ty = context.struct_type(&basic_types, false);
|
||||
args_vec.push(builder.build_alloca(sret_ty, "sret").into());
|
||||
}
|
||||
let casted_pointer_type = type_to_llvm_ptr(intrinsics, *param_ty)?;
|
||||
|
||||
args_vec.push(callee_vmctx_ptr);
|
||||
let typed_item_pointer =
|
||||
builder.build_pointer_cast(item_pointer, casted_pointer_type, "typed_arg_pointer");
|
||||
|
||||
for (i, param_ty) in func_sig.params().iter().enumerate() {
|
||||
let index = intrinsics.i32_ty.const_int(i as _, false);
|
||||
let item_pointer =
|
||||
unsafe { builder.build_in_bounds_gep(args_rets_ptr, &[index], "arg_ptr") };
|
||||
|
||||
let casted_pointer_type = type_to_llvm_ptr(intrinsics, *param_ty)?;
|
||||
|
||||
let typed_item_pointer =
|
||||
builder.build_pointer_cast(item_pointer, casted_pointer_type, "typed_arg_pointer");
|
||||
|
||||
let arg = builder.build_load(typed_item_pointer, "arg");
|
||||
args_vec.push(arg);
|
||||
}
|
||||
|
||||
let call_site = builder.build_call(func_ptr, &args_vec, "call");
|
||||
for (attr, attr_loc) in func_attrs {
|
||||
call_site.add_attribute(*attr_loc, *attr);
|
||||
}
|
||||
|
||||
let rets = rets_from_call(&builder, intrinsics, call_site, func_sig);
|
||||
let mut idx = 0;
|
||||
rets.iter().for_each(|v| {
|
||||
let ptr = unsafe {
|
||||
builder.build_gep(
|
||||
args_rets_ptr,
|
||||
&[intrinsics.i32_ty.const_int(idx, false)],
|
||||
"",
|
||||
)
|
||||
};
|
||||
let ptr = builder.build_pointer_cast(ptr, v.get_type().ptr_type(AddressSpace::Generic), "");
|
||||
builder.build_store(ptr, *v);
|
||||
if v.get_type() == intrinsics.i128_ty.as_basic_type_enum() {
|
||||
idx += 1;
|
||||
let arg = builder.build_load(typed_item_pointer, "arg");
|
||||
args_vec.push(arg);
|
||||
}
|
||||
idx += 1;
|
||||
});
|
||||
|
||||
builder.build_return(None);
|
||||
Ok(())
|
||||
}
|
||||
let call_site = builder.build_call(func_ptr, &args_vec, "call");
|
||||
for (attr, attr_loc) in func_attrs {
|
||||
call_site.add_attribute(*attr_loc, *attr);
|
||||
}
|
||||
|
||||
fn generate_dynamic_trampoline<'ctx>(
|
||||
trampoline_func: FunctionValue,
|
||||
func_sig: &FunctionType,
|
||||
context: &'ctx Context,
|
||||
intrinsics: &Intrinsics<'ctx>,
|
||||
) -> Result<(), CompileError> {
|
||||
let entry_block = context.append_basic_block(trampoline_func, "entry");
|
||||
let builder = context.create_builder();
|
||||
builder.position_at_end(entry_block);
|
||||
|
||||
// Allocate stack space for the params and results.
|
||||
let values = builder.build_alloca(
|
||||
intrinsics.i128_ty.array_type(cmp::max(
|
||||
func_sig.params().len().try_into().unwrap(),
|
||||
func_sig.results().len().try_into().unwrap(),
|
||||
)),
|
||||
"",
|
||||
);
|
||||
|
||||
// Copy params to 'values'.
|
||||
let first_user_param = if is_sret(func_sig)? { 2 } else { 1 };
|
||||
for i in 0..func_sig.params().len() {
|
||||
let ptr = unsafe {
|
||||
builder.build_in_bounds_gep(
|
||||
values,
|
||||
&[
|
||||
intrinsics.i32_zero,
|
||||
intrinsics.i32_ty.const_int(i.try_into().unwrap(), false),
|
||||
],
|
||||
"",
|
||||
)
|
||||
};
|
||||
let ptr = builder
|
||||
.build_bitcast(ptr, type_to_llvm_ptr(intrinsics, func_sig.params()[i])?, "")
|
||||
.into_pointer_value();
|
||||
builder.build_store(
|
||||
ptr,
|
||||
trampoline_func
|
||||
.get_nth_param(i as u32 + first_user_param)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
let callee_ty = intrinsics
|
||||
.void_ty
|
||||
.fn_type(
|
||||
&[
|
||||
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // vmctx ptr
|
||||
intrinsics.i128_ptr_ty.as_basic_type_enum(), // in/out values ptr
|
||||
],
|
||||
false,
|
||||
)
|
||||
.ptr_type(AddressSpace::Generic);
|
||||
let vmctx = get_vmctx_ptr_param(&trampoline_func);
|
||||
let callee = builder
|
||||
.build_load(
|
||||
builder
|
||||
.build_bitcast(vmctx, callee_ty.ptr_type(AddressSpace::Generic), "")
|
||||
.into_pointer_value(),
|
||||
"",
|
||||
)
|
||||
.into_pointer_value();
|
||||
|
||||
let values_ptr = builder.build_pointer_cast(values, intrinsics.i128_ptr_ty, "");
|
||||
builder.build_call(
|
||||
callee,
|
||||
&[
|
||||
vmctx.as_basic_value_enum(),
|
||||
values_ptr.as_basic_value_enum(),
|
||||
],
|
||||
"",
|
||||
);
|
||||
|
||||
if func_sig.results().is_empty() {
|
||||
builder.build_return(None);
|
||||
} else {
|
||||
let results = func_sig
|
||||
.results()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, ty)| {
|
||||
let ptr = unsafe {
|
||||
builder.build_gep(
|
||||
values,
|
||||
&[
|
||||
intrinsics.i32_ty.const_zero(),
|
||||
intrinsics.i32_ty.const_int(idx.try_into().unwrap(), false),
|
||||
],
|
||||
"",
|
||||
)
|
||||
};
|
||||
let ptr = builder.build_pointer_cast(ptr, type_to_llvm_ptr(intrinsics, *ty)?, "");
|
||||
Ok(builder.build_load(ptr, ""))
|
||||
})
|
||||
.collect::<Result<Vec<_>, CompileError>>()?;
|
||||
|
||||
if is_sret(func_sig)? {
|
||||
let sret = trampoline_func
|
||||
.get_first_param()
|
||||
.unwrap()
|
||||
.into_pointer_value();
|
||||
let mut struct_value = sret
|
||||
.get_type()
|
||||
.get_element_type()
|
||||
.into_struct_type()
|
||||
.get_undef();
|
||||
for (idx, value) in results.iter().enumerate() {
|
||||
let value = builder.build_bitcast(
|
||||
*value,
|
||||
type_to_llvm(&intrinsics, func_sig.results()[idx])?,
|
||||
let rets = self
|
||||
.abi
|
||||
.rets_from_call(&builder, intrinsics, call_site, func_sig);
|
||||
let mut idx = 0;
|
||||
rets.iter().for_each(|v| {
|
||||
let ptr = unsafe {
|
||||
builder.build_gep(
|
||||
args_rets_ptr,
|
||||
&[intrinsics.i32_ty.const_int(idx, false)],
|
||||
"",
|
||||
);
|
||||
struct_value = builder
|
||||
.build_insert_value(struct_value, value, idx as u32, "")
|
||||
.unwrap()
|
||||
.into_struct_value();
|
||||
)
|
||||
};
|
||||
let ptr =
|
||||
builder.build_pointer_cast(ptr, v.get_type().ptr_type(AddressSpace::Generic), "");
|
||||
builder.build_store(ptr, *v);
|
||||
if v.get_type() == intrinsics.i128_ty.as_basic_type_enum() {
|
||||
idx += 1;
|
||||
}
|
||||
builder.build_store(sret, struct_value);
|
||||
idx += 1;
|
||||
});
|
||||
|
||||
builder.build_return(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_dynamic_trampoline<'ctx>(
|
||||
&self,
|
||||
trampoline_func: FunctionValue,
|
||||
func_sig: &FunctionType,
|
||||
context: &'ctx Context,
|
||||
intrinsics: &Intrinsics<'ctx>,
|
||||
) -> Result<(), CompileError> {
|
||||
let entry_block = context.append_basic_block(trampoline_func, "entry");
|
||||
let builder = context.create_builder();
|
||||
builder.position_at_end(entry_block);
|
||||
|
||||
// Allocate stack space for the params and results.
|
||||
let values = builder.build_alloca(
|
||||
intrinsics.i128_ty.array_type(cmp::max(
|
||||
func_sig.params().len().try_into().unwrap(),
|
||||
func_sig.results().len().try_into().unwrap(),
|
||||
)),
|
||||
"",
|
||||
);
|
||||
|
||||
// Copy params to 'values'.
|
||||
let first_user_param = if self.abi.is_sret(func_sig)? { 2 } else { 1 };
|
||||
for i in 0..func_sig.params().len() {
|
||||
let ptr = unsafe {
|
||||
builder.build_in_bounds_gep(
|
||||
values,
|
||||
&[
|
||||
intrinsics.i32_zero,
|
||||
intrinsics.i32_ty.const_int(i.try_into().unwrap(), false),
|
||||
],
|
||||
"",
|
||||
)
|
||||
};
|
||||
let ptr = builder
|
||||
.build_bitcast(ptr, type_to_llvm_ptr(intrinsics, func_sig.params()[i])?, "")
|
||||
.into_pointer_value();
|
||||
builder.build_store(
|
||||
ptr,
|
||||
trampoline_func
|
||||
.get_nth_param(i as u32 + first_user_param)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
let callee_ty = intrinsics
|
||||
.void_ty
|
||||
.fn_type(
|
||||
&[
|
||||
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // vmctx ptr
|
||||
intrinsics.i128_ptr_ty.as_basic_type_enum(), // in/out values ptr
|
||||
],
|
||||
false,
|
||||
)
|
||||
.ptr_type(AddressSpace::Generic);
|
||||
let vmctx = self.abi.get_vmctx_ptr_param(&trampoline_func);
|
||||
let callee = builder
|
||||
.build_load(
|
||||
builder
|
||||
.build_bitcast(vmctx, callee_ty.ptr_type(AddressSpace::Generic), "")
|
||||
.into_pointer_value(),
|
||||
"",
|
||||
)
|
||||
.into_pointer_value();
|
||||
|
||||
let values_ptr = builder.build_pointer_cast(values, intrinsics.i128_ptr_ty, "");
|
||||
builder.build_call(
|
||||
callee,
|
||||
&[
|
||||
vmctx.as_basic_value_enum(),
|
||||
values_ptr.as_basic_value_enum(),
|
||||
],
|
||||
"",
|
||||
);
|
||||
|
||||
if func_sig.results().is_empty() {
|
||||
builder.build_return(None);
|
||||
} else {
|
||||
builder.build_return(Some(&pack_values_for_register_return(
|
||||
&intrinsics,
|
||||
&builder,
|
||||
&results.as_slice(),
|
||||
&trampoline_func.get_type(),
|
||||
)?));
|
||||
}
|
||||
}
|
||||
let results = func_sig
|
||||
.results()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, ty)| {
|
||||
let ptr = unsafe {
|
||||
builder.build_gep(
|
||||
values,
|
||||
&[
|
||||
intrinsics.i32_ty.const_zero(),
|
||||
intrinsics.i32_ty.const_int(idx.try_into().unwrap(), false),
|
||||
],
|
||||
"",
|
||||
)
|
||||
};
|
||||
let ptr =
|
||||
builder.build_pointer_cast(ptr, type_to_llvm_ptr(intrinsics, *ty)?, "");
|
||||
Ok(builder.build_load(ptr, ""))
|
||||
})
|
||||
.collect::<Result<Vec<_>, CompileError>>()?;
|
||||
|
||||
Ok(())
|
||||
if self.abi.is_sret(func_sig)? {
|
||||
let sret = trampoline_func
|
||||
.get_first_param()
|
||||
.unwrap()
|
||||
.into_pointer_value();
|
||||
let mut struct_value = sret
|
||||
.get_type()
|
||||
.get_element_type()
|
||||
.into_struct_type()
|
||||
.get_undef();
|
||||
for (idx, value) in results.iter().enumerate() {
|
||||
let value = builder.build_bitcast(
|
||||
*value,
|
||||
type_to_llvm(&intrinsics, func_sig.results()[idx])?,
|
||||
"",
|
||||
);
|
||||
struct_value = builder
|
||||
.build_insert_value(struct_value, value, idx as u32, "")
|
||||
.unwrap()
|
||||
.into_struct_value();
|
||||
}
|
||||
builder.build_store(sret, struct_value);
|
||||
builder.build_return(None);
|
||||
} else {
|
||||
builder.build_return(Some(&self.abi.pack_values_for_register_return(
|
||||
&intrinsics,
|
||||
&builder,
|
||||
&results.as_slice(),
|
||||
&trampoline_func.get_type(),
|
||||
)?));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
use super::{
|
||||
abi,
|
||||
abi::{Abi, X86_64SystemV},
|
||||
intrinsics::{
|
||||
tbaa_label, type_to_llvm, CtxType, FunctionCache, GlobalCache, Intrinsics, MemoryCache,
|
||||
},
|
||||
@@ -57,6 +57,7 @@ fn const_zero(ty: BasicTypeEnum) -> BasicValueEnum {
|
||||
pub struct FuncTranslator {
|
||||
ctx: Context,
|
||||
target_machine: TargetMachine,
|
||||
abi: Box<dyn Abi>,
|
||||
}
|
||||
|
||||
impl FuncTranslator {
|
||||
@@ -64,6 +65,7 @@ impl FuncTranslator {
|
||||
Self {
|
||||
ctx: Context::create(),
|
||||
target_machine,
|
||||
abi: Box::new(X86_64SystemV {}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +101,9 @@ impl FuncTranslator {
|
||||
.unwrap();
|
||||
|
||||
let intrinsics = Intrinsics::declare(&module, &self.ctx);
|
||||
let (func_type, func_attrs) = abi::func_type_to_llvm(&self.ctx, &intrinsics, wasm_fn_type)?;
|
||||
let (func_type, func_attrs) =
|
||||
self.abi
|
||||
.func_type_to_llvm(&self.ctx, &intrinsics, wasm_fn_type)?;
|
||||
|
||||
let func = module.add_function(&function_name, func_type, Some(Linkage::External));
|
||||
for (attr, attr_loc) in &func_attrs {
|
||||
@@ -203,7 +207,7 @@ impl FuncTranslator {
|
||||
state,
|
||||
function: func,
|
||||
locals: params_locals,
|
||||
ctx: CtxType::new(wasm_module, &func, &cache_builder),
|
||||
ctx: CtxType::new(wasm_module, &func, &cache_builder, &self.abi),
|
||||
unreachable_depth: 0,
|
||||
memory_styles,
|
||||
_table_styles,
|
||||
@@ -211,6 +215,7 @@ impl FuncTranslator {
|
||||
module_translation,
|
||||
wasm_module,
|
||||
symbol_registry,
|
||||
abi: &self.abi,
|
||||
};
|
||||
fcg.ctx.add_func(
|
||||
func_index,
|
||||
@@ -1171,7 +1176,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
.map(|(v, i)| self.apply_pending_canonicalization(v, i));
|
||||
if wasm_fn_type.results().is_empty() {
|
||||
self.builder.build_return(None);
|
||||
} else if abi::is_sret(wasm_fn_type)? {
|
||||
} else if self.abi.is_sret(wasm_fn_type)? {
|
||||
let sret = self
|
||||
.function
|
||||
.get_first_param()
|
||||
@@ -1198,7 +1203,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
self.builder.build_return(None);
|
||||
} else {
|
||||
self.builder
|
||||
.build_return(Some(&abi::pack_values_for_register_return(
|
||||
.build_return(Some(&self.abi.pack_values_for_register_return(
|
||||
&self.intrinsics,
|
||||
&self.builder,
|
||||
&results.collect::<Vec<_>>(),
|
||||
@@ -1318,6 +1323,7 @@ pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
module_translation: &'a ModuleTranslationState,
|
||||
wasm_module: &'a ModuleInfo,
|
||||
symbol_registry: &'a dyn SymbolRegistry,
|
||||
abi: &'a Box<dyn Abi>,
|
||||
}
|
||||
|
||||
impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
@@ -2138,7 +2144,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
_ => *v,
|
||||
});
|
||||
|
||||
let params = abi::args_to_call(
|
||||
let params = self.abi.args_to_call(
|
||||
&self.alloca_builder,
|
||||
func_type,
|
||||
callee_vmctx.into_pointer_value(),
|
||||
@@ -2186,7 +2192,8 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
}
|
||||
*/
|
||||
|
||||
abi::rets_from_call(&self.builder, &self.intrinsics, call_site, func_type)
|
||||
self.abi
|
||||
.rets_from_call(&self.builder, &self.intrinsics, call_site, func_type)
|
||||
.iter()
|
||||
.for_each(|ret| self.state.push1(*ret));
|
||||
}
|
||||
@@ -2357,7 +2364,8 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
self.builder.position_at_end(continue_block);
|
||||
|
||||
let (llvm_func_type, llvm_func_attrs) =
|
||||
abi::func_type_to_llvm(&self.context, &self.intrinsics, func_type)?;
|
||||
self.abi
|
||||
.func_type_to_llvm(&self.context, &self.intrinsics, func_type)?;
|
||||
|
||||
let params = self.state.popn_save_extra(func_type.params().len())?;
|
||||
|
||||
@@ -2381,7 +2389,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
_ => *v,
|
||||
});
|
||||
|
||||
let params = abi::args_to_call(
|
||||
let params = self.abi.args_to_call(
|
||||
&self.alloca_builder,
|
||||
func_type,
|
||||
ctx_ptr.into_pointer_value(),
|
||||
@@ -2436,7 +2444,8 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
|
||||
}
|
||||
*/
|
||||
|
||||
abi::rets_from_call(&self.builder, &self.intrinsics, call_site, func_type)
|
||||
self.abi
|
||||
.rets_from_call(&self.builder, &self.intrinsics, call_site, func_type)
|
||||
.iter()
|
||||
.for_each(|ret| self.state.push1(*ret));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//!
|
||||
//! [llvm-intrinsics]: https://llvm.org/docs/LangRef.html#intrinsic-functions
|
||||
|
||||
use super::abi;
|
||||
use super::abi::Abi;
|
||||
use inkwell::{
|
||||
attributes::{Attribute, AttributeLoc},
|
||||
builder::Builder,
|
||||
@@ -536,6 +536,7 @@ pub struct CtxType<'ctx, 'a> {
|
||||
|
||||
wasm_module: &'a WasmerCompilerModule,
|
||||
cache_builder: &'a Builder<'ctx>,
|
||||
abi: &'a Box<dyn Abi>,
|
||||
|
||||
cached_memories: HashMap<MemoryIndex, MemoryCache<'ctx>>,
|
||||
cached_tables: HashMap<TableIndex, TableCache<'ctx>>,
|
||||
@@ -553,12 +554,14 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
wasm_module: &'a WasmerCompilerModule,
|
||||
func_value: &FunctionValue<'ctx>,
|
||||
cache_builder: &'a Builder<'ctx>,
|
||||
abi: &'a Box<dyn Abi>,
|
||||
) -> CtxType<'ctx, 'a> {
|
||||
CtxType {
|
||||
ctx_ptr_value: abi::get_vmctx_ptr_param(func_value),
|
||||
ctx_ptr_value: abi.get_vmctx_ptr_param(func_value),
|
||||
|
||||
wasm_module,
|
||||
cache_builder,
|
||||
abi,
|
||||
|
||||
cached_memories: HashMap::new(),
|
||||
cached_tables: HashMap::new(),
|
||||
@@ -937,7 +940,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
Entry::Vacant(entry) => {
|
||||
debug_assert!(module.get_function(function_name).is_none());
|
||||
let (llvm_func_type, llvm_func_attrs) =
|
||||
abi::func_type_to_llvm(context, intrinsics, func_type)?;
|
||||
self.abi.func_type_to_llvm(context, intrinsics, func_type)?;
|
||||
let func =
|
||||
module.add_function(function_name, llvm_func_type, Some(Linkage::External));
|
||||
for (attr, attr_loc) in &llvm_func_attrs {
|
||||
@@ -970,7 +973,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
Entry::Occupied(entry) => entry.into_mut(),
|
||||
Entry::Vacant(entry) => {
|
||||
let (llvm_func_type, llvm_func_attrs) =
|
||||
abi::func_type_to_llvm(context, intrinsics, func_type)?;
|
||||
self.abi.func_type_to_llvm(context, intrinsics, func_type)?;
|
||||
debug_assert!(wasm_module.local_func_index(function_index).is_none());
|
||||
let offset = offsets.vmctx_vmfunction_import(function_index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
|
||||
Reference in New Issue
Block a user