mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 13:48:26 +00:00
Fix trampoline generation.
Updates to new API for trampolines, taking two vmctx pointers and reusing the input space to write the returns. Wasm values are padded to 128-bits. Removes a pile of dead code.
This commit is contained in:
@@ -3,6 +3,7 @@ use crate::translator::intrinsics::{func_type_to_llvm, type_to_llvm, Intrinsics}
|
|||||||
use inkwell::{
|
use inkwell::{
|
||||||
context::Context,
|
context::Context,
|
||||||
module::{Linkage, Module},
|
module::{Linkage, Module},
|
||||||
|
passes::PassManager,
|
||||||
targets::FileType,
|
targets::FileType,
|
||||||
types::{BasicType, FunctionType},
|
types::{BasicType, FunctionType},
|
||||||
values::FunctionValue,
|
values::FunctionValue,
|
||||||
@@ -44,12 +45,12 @@ impl FuncTrampoline {
|
|||||||
let callee_ty = func_type_to_llvm(&self.ctx, &intrinsics, ty);
|
let callee_ty = func_type_to_llvm(&self.ctx, &intrinsics, ty);
|
||||||
let trampoline_ty = intrinsics.void_ty.fn_type(
|
let trampoline_ty = intrinsics.void_ty.fn_type(
|
||||||
&[
|
&[
|
||||||
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // vmctx ptr
|
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // callee_vmctx ptr
|
||||||
|
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // caller_vmctx ptr
|
||||||
callee_ty
|
callee_ty
|
||||||
.ptr_type(AddressSpace::Generic)
|
.ptr_type(AddressSpace::Generic)
|
||||||
.as_basic_type_enum(), // func ptr
|
.as_basic_type_enum(), // callee function address
|
||||||
intrinsics.i64_ptr_ty.as_basic_type_enum(), // args ptr
|
intrinsics.i128_ptr_ty.as_basic_type_enum(), // in/out values ptr
|
||||||
intrinsics.i64_ptr_ty.as_basic_type_enum(), // returns ptr
|
|
||||||
],
|
],
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
@@ -63,16 +64,32 @@ impl FuncTrampoline {
|
|||||||
// TODO: remove debugging
|
// TODO: remove debugging
|
||||||
//module.print_to_stderr();
|
//module.print_to_stderr();
|
||||||
|
|
||||||
|
let pass_manager = PassManager::create(());
|
||||||
|
|
||||||
|
if config.enable_verifier {
|
||||||
|
pass_manager.add_verifier_pass();
|
||||||
|
}
|
||||||
|
|
||||||
|
pass_manager.add_early_cse_pass();
|
||||||
|
|
||||||
|
pass_manager.run_on(&mut module);
|
||||||
|
|
||||||
|
// TODO: remove debugging
|
||||||
|
//module.print_to_stderr();
|
||||||
|
|
||||||
let memory_buffer = target_machine
|
let memory_buffer = target_machine
|
||||||
.write_to_memory_buffer(&mut module, FileType::Object)
|
.write_to_memory_buffer(&mut module, FileType::Object)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// TODO: remove debugging
|
||||||
|
/*
|
||||||
let mem_buf_slice = memory_buffer.as_slice();
|
let mem_buf_slice = memory_buffer.as_slice();
|
||||||
let mut file = fs::File::create("/home/nicholas/x.o").unwrap();
|
let mut file = fs::File::create("/home/nicholas/trampoline.o").unwrap();
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
while pos < mem_buf_slice.len() {
|
while pos < mem_buf_slice.len() {
|
||||||
pos += file.write(&mem_buf_slice[pos..]).unwrap();
|
pos += file.write(&mem_buf_slice[pos..]).unwrap();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
let object = memory_buffer.create_object_file().map_err(|()| {
|
let object = memory_buffer.create_object_file().map_err(|()| {
|
||||||
CompileError::Codegen("failed to create object file from llvm ir".to_string())
|
CompileError::Codegen("failed to create object file from llvm ir".to_string())
|
||||||
@@ -107,41 +124,6 @@ impl FuncTrampoline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
pub fn generate_trampolines<'ctx>(
|
|
||||||
info: &ModuleInfo,
|
|
||||||
signatures: &SliceMap<SigIndex, FunctionType<'ctx>>,
|
|
||||||
module: &Module<'ctx>,
|
|
||||||
context: &'ctx Context,
|
|
||||||
intrinsics: &Intrinsics<'ctx>,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
for (sig_index, sig) in info.signatures.iter() {
|
|
||||||
let func_type = signatures[sig_index];
|
|
||||||
|
|
||||||
let trampoline_sig = intrinsics.void_ty.fn_type(
|
|
||||||
&[
|
|
||||||
intrinsics.ctx_ptr_ty.as_basic_type_enum(), // vmctx ptr
|
|
||||||
func_type
|
|
||||||
.ptr_type(AddressSpace::Generic)
|
|
||||||
.as_basic_type_enum(), // func ptr
|
|
||||||
intrinsics.i64_ptr_ty.as_basic_type_enum(), // args ptr
|
|
||||||
intrinsics.i64_ptr_ty.as_basic_type_enum(), // returns ptr
|
|
||||||
],
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
let trampoline_func = module.add_function(
|
|
||||||
&format!("trmp{}", sig_index.index()),
|
|
||||||
trampoline_sig,
|
|
||||||
Some(Linkage::External),
|
|
||||||
);
|
|
||||||
|
|
||||||
generate_trampoline(trampoline_func, sig, context, intrinsics)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn generate_trampoline<'ctx>(
|
fn generate_trampoline<'ctx>(
|
||||||
trampoline_func: FunctionValue,
|
trampoline_func: FunctionValue,
|
||||||
func_sig: &FuncType,
|
func_sig: &FuncType,
|
||||||
@@ -152,13 +134,13 @@ fn generate_trampoline<'ctx>(
|
|||||||
let builder = context.create_builder();
|
let builder = context.create_builder();
|
||||||
builder.position_at_end(entry_block);
|
builder.position_at_end(entry_block);
|
||||||
|
|
||||||
let (vmctx_ptr, func_ptr, args_ptr, returns_ptr) = match trampoline_func.get_params().as_slice()
|
let (callee_vmctx_ptr, caller_vmctx_ptr, func_ptr, args_rets_ptr) =
|
||||||
{
|
match trampoline_func.get_params().as_slice() {
|
||||||
&[vmctx_ptr, func_ptr, args_ptr, returns_ptr] => (
|
&[callee_vmctx_ptr, caller_vmctx_ptr, func_ptr, args_rets_ptr] => (
|
||||||
vmctx_ptr,
|
callee_vmctx_ptr,
|
||||||
|
caller_vmctx_ptr,
|
||||||
func_ptr.into_pointer_value(),
|
func_ptr.into_pointer_value(),
|
||||||
args_ptr.into_pointer_value(),
|
args_rets_ptr.into_pointer_value(),
|
||||||
returns_ptr.into_pointer_value(),
|
|
||||||
),
|
),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(CompileError::Codegen(
|
return Err(CompileError::Codegen(
|
||||||
@@ -178,12 +160,13 @@ fn generate_trampoline<'ctx>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut args_vec = Vec::with_capacity(func_sig.params().len() + 1);
|
let mut args_vec = Vec::with_capacity(func_sig.params().len() + 1);
|
||||||
args_vec.push(vmctx_ptr);
|
args_vec.push(callee_vmctx_ptr);
|
||||||
|
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for param_ty in func_sig.params().iter() {
|
for param_ty in func_sig.params().iter() {
|
||||||
let index = intrinsics.i32_ty.const_int(i as _, false);
|
let index = intrinsics.i32_ty.const_int(i as _, false);
|
||||||
let item_pointer = unsafe { builder.build_in_bounds_gep(args_ptr, &[index], "arg_ptr") };
|
let item_pointer =
|
||||||
|
unsafe { builder.build_in_bounds_gep(args_rets_ptr, &[index], "arg_ptr") };
|
||||||
|
|
||||||
let casted_pointer_type = cast_ptr_ty(*param_ty);
|
let casted_pointer_type = cast_ptr_ty(*param_ty);
|
||||||
|
|
||||||
@@ -206,7 +189,7 @@ fn generate_trampoline<'ctx>(
|
|||||||
let ret_ptr_type = cast_ptr_ty(one_ret);
|
let ret_ptr_type = cast_ptr_ty(one_ret);
|
||||||
|
|
||||||
let typed_ret_ptr =
|
let typed_ret_ptr =
|
||||||
builder.build_pointer_cast(returns_ptr, ret_ptr_type, "typed_ret_ptr");
|
builder.build_pointer_cast(args_rets_ptr, ret_ptr_type, "typed_ret_ptr");
|
||||||
builder.build_store(
|
builder.build_store(
|
||||||
typed_ret_ptr,
|
typed_ret_ptr,
|
||||||
call_site.try_as_basic_value().left().unwrap(),
|
call_site.try_as_basic_value().left().unwrap(),
|
||||||
|
|||||||
Reference in New Issue
Block a user