mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-18 06:19:12 +00:00
Dynamic function support for singlepass.
This commit is contained in:
@@ -8349,11 +8349,104 @@ pub fn gen_std_trampoline(sig: FunctionType) -> FunctionBody {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates dynamic import function call trampoline for a function type.
|
||||||
|
pub fn gen_std_dynamic_import_trampoline(
|
||||||
|
vmoffsets: &VMOffsets,
|
||||||
|
sig: &FunctionType,
|
||||||
|
) -> FunctionBody {
|
||||||
|
let mut a = Assembler::new().unwrap();
|
||||||
|
|
||||||
|
// Allocate argument array.
|
||||||
|
let stack_offset: usize = 16 * std::cmp::max(sig.params().len(), sig.results().len()) + 8; // 16 bytes each + 8 bytes sysv call padding
|
||||||
|
a.emit_sub(
|
||||||
|
Size::S64,
|
||||||
|
Location::Imm32(stack_offset as _),
|
||||||
|
Location::GPR(GPR::RSP),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy arguments.
|
||||||
|
if sig.params().len() > 0 {
|
||||||
|
let mut argalloc = ArgumentRegisterAllocator::default();
|
||||||
|
argalloc.next(Type::I32).unwrap(); // skip VMContext
|
||||||
|
|
||||||
|
let mut stack_param_count: usize = 0;
|
||||||
|
|
||||||
|
for (i, ty) in sig.params().iter().enumerate() {
|
||||||
|
let source_loc = match argalloc.next(*ty) {
|
||||||
|
Some(X64Register::GPR(gpr)) => Location::GPR(gpr),
|
||||||
|
Some(X64Register::XMM(xmm)) => Location::XMM(xmm),
|
||||||
|
None => {
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Memory(GPR::RSP, (stack_offset + 8 + stack_param_count * 8) as _),
|
||||||
|
Location::GPR(GPR::RAX),
|
||||||
|
);
|
||||||
|
stack_param_count += 1;
|
||||||
|
Location::GPR(GPR::RAX)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
source_loc,
|
||||||
|
Location::Memory(GPR::RSP, (i * 16) as _),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Zero upper 64 bits.
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Imm32(0),
|
||||||
|
Location::Memory(GPR::RSP, (i * 16 + 8) as _),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load target address.
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Memory(
|
||||||
|
GPR::RDI,
|
||||||
|
vmoffsets.vmdynamicfunction_import_context_address() as i32,
|
||||||
|
),
|
||||||
|
Location::GPR(GPR::RAX),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Load values array.
|
||||||
|
a.emit_mov(Size::S64, Location::GPR(GPR::RSP), Location::GPR(GPR::RSI));
|
||||||
|
|
||||||
|
// Call target.
|
||||||
|
a.emit_call_location(Location::GPR(GPR::RAX));
|
||||||
|
|
||||||
|
// Fetch return value.
|
||||||
|
if sig.results().len() > 0 {
|
||||||
|
assert_eq!(sig.results().len(), 1);
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Memory(GPR::RSP, 0),
|
||||||
|
Location::GPR(GPR::RAX),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release values array.
|
||||||
|
a.emit_add(
|
||||||
|
Size::S64,
|
||||||
|
Location::Imm32(stack_offset as _),
|
||||||
|
Location::GPR(GPR::RSP),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return.
|
||||||
|
a.emit_ret();
|
||||||
|
|
||||||
|
FunctionBody {
|
||||||
|
body: a.finalize().unwrap().to_vec(),
|
||||||
|
unwind_info: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Singlepass calls import functions through a trampoline.
|
// Singlepass calls import functions through a trampoline.
|
||||||
pub fn gen_import_call_trampoline(
|
pub fn gen_import_call_trampoline(
|
||||||
vmoffsets: &VMOffsets,
|
vmoffsets: &VMOffsets,
|
||||||
index: FunctionIndex,
|
index: FunctionIndex,
|
||||||
sig: FunctionType,
|
sig: &FunctionType,
|
||||||
) -> CustomSection {
|
) -> CustomSection {
|
||||||
let mut a = Assembler::new().unwrap();
|
let mut a = Assembler::new().unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
// Allow unused imports while developing.
|
// Allow unused imports while developing.
|
||||||
#![allow(unused_imports, dead_code)]
|
#![allow(unused_imports, dead_code)]
|
||||||
|
|
||||||
use crate::codegen_x64::{gen_import_call_trampoline, gen_std_trampoline, CodegenError, FuncGen};
|
use crate::codegen_x64::{
|
||||||
|
gen_import_call_trampoline, gen_std_dynamic_import_trampoline, gen_std_trampoline,
|
||||||
|
CodegenError, FuncGen,
|
||||||
|
};
|
||||||
use crate::config::SinglepassConfig;
|
use crate::config::SinglepassConfig;
|
||||||
use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator};
|
||||||
use wasm_common::entity::{EntityRef, PrimaryMap};
|
use wasm_common::entity::{EntityRef, PrimaryMap};
|
||||||
@@ -64,11 +67,7 @@ impl Compiler for SinglepassCompiler {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
gen_import_call_trampoline(
|
gen_import_call_trampoline(&vmoffsets, i, &module.signatures[module.functions[i]])
|
||||||
&vmoffsets,
|
|
||||||
i,
|
|
||||||
module.signatures[module.functions[i]].clone(),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -131,10 +130,21 @@ impl Compiler for SinglepassCompiler {
|
|||||||
|
|
||||||
fn compile_dynamic_function_trampolines(
|
fn compile_dynamic_function_trampolines(
|
||||||
&self,
|
&self,
|
||||||
_module: &ModuleInfo,
|
module: &ModuleInfo,
|
||||||
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
|
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
|
||||||
Ok(PrimaryMap::new())
|
let vmoffsets = VMOffsets::new(8, module);
|
||||||
// unimplemented!("Dynamic funciton trampolines not yet implemented");
|
Ok(module
|
||||||
|
.functions
|
||||||
|
.values()
|
||||||
|
.take(module.num_imported_funcs)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.par_iter()
|
||||||
|
.map(|&&sig_index| {
|
||||||
|
gen_std_dynamic_import_trampoline(&vmoffsets, &module.signatures[sig_index])
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into_iter()
|
||||||
|
.collect::<PrimaryMap<FunctionIndex, FunctionBody>>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user