mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Get memory intrinsics at runtime.
This commit is contained in:
parent
a590d7cd07
commit
46e4cb05bc
@ -1,9 +1,11 @@
|
||||
pub use crate::backing::{ImportBacking, LocalBacking};
|
||||
use crate::{
|
||||
memory::Memory,
|
||||
module::ModuleInner,
|
||||
memory::{Memory, MemoryType},
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
structures::TypedIndex,
|
||||
types::{LocalOrImport, MemoryIndex},
|
||||
types::{LocalOrImport, MemoryIndex, LocalMemoryIndex},
|
||||
units::{Pages},
|
||||
vmcalls,
|
||||
};
|
||||
use std::{ffi::c_void, mem, ptr};
|
||||
|
||||
@ -61,6 +63,77 @@ pub struct InternalCtx {
|
||||
/// signature id. This is used to allow call-indirect to other
|
||||
/// modules safely.
|
||||
pub dynamic_sigindices: *const SigId,
|
||||
|
||||
pub intrinsics: *const Intrinsics,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Intrinsics {
|
||||
pub memory_grow: *const Func,
|
||||
pub memory_size: *const Func,
|
||||
/*pub memory_grow: unsafe extern "C" fn(
|
||||
ctx: &mut Ctx,
|
||||
memory_index: usize,
|
||||
delta: Pages,
|
||||
) -> i32,
|
||||
pub memory_size: unsafe extern "C" fn(
|
||||
ctx: &Ctx,
|
||||
memory_index: usize,
|
||||
) -> Pages,*/
|
||||
}
|
||||
|
||||
unsafe impl Send for Intrinsics {}
|
||||
unsafe impl Sync for Intrinsics {}
|
||||
|
||||
impl Intrinsics {
|
||||
pub fn offset_memory_grow() -> u8 {
|
||||
(0 * ::std::mem::size_of::<usize>()) as u8
|
||||
}
|
||||
pub fn offset_memory_size() -> u8 {
|
||||
(1 * ::std::mem::size_of::<usize>()) as u8
|
||||
}
|
||||
}
|
||||
|
||||
pub static INTRINSICS_LOCAL_STATIC_MEMORY: Intrinsics = Intrinsics {
|
||||
memory_grow: vmcalls::local_static_memory_grow as _,
|
||||
memory_size: vmcalls::local_static_memory_size as _,
|
||||
};
|
||||
pub static INTRINSICS_LOCAL_DYNAMIC_MEMORY: Intrinsics = Intrinsics {
|
||||
memory_grow: vmcalls::local_dynamic_memory_grow as _,
|
||||
memory_size: vmcalls::local_dynamic_memory_size as _,
|
||||
};
|
||||
pub static INTRINSICS_IMPORTED_STATIC_MEMORY: Intrinsics = Intrinsics {
|
||||
memory_grow: vmcalls::imported_static_memory_grow as _,
|
||||
memory_size: vmcalls::imported_static_memory_size as _,
|
||||
};
|
||||
pub static INTRINSICS_IMPORTED_DYNAMIC_MEMORY: Intrinsics = Intrinsics {
|
||||
memory_grow: vmcalls::imported_dynamic_memory_grow as _,
|
||||
memory_size: vmcalls::imported_dynamic_memory_size as _,
|
||||
};
|
||||
|
||||
fn get_intrinsics_for_module(m: &ModuleInfo) -> *const Intrinsics {
|
||||
if m.memories.len() == 0 && m.imported_memories.len() == 0 {
|
||||
::std::ptr::null()
|
||||
} else {
|
||||
match MemoryIndex::new(0).local_or_import(m) {
|
||||
LocalOrImport::Local(local_mem_index) => {
|
||||
let mem_desc = &m.memories[local_mem_index];
|
||||
match mem_desc.memory_type() {
|
||||
MemoryType::Dynamic => &INTRINSICS_LOCAL_DYNAMIC_MEMORY,
|
||||
MemoryType::Static => &INTRINSICS_LOCAL_STATIC_MEMORY,
|
||||
MemoryType::SharedStatic => unimplemented!(),
|
||||
}
|
||||
}
|
||||
LocalOrImport::Import(import_mem_index) => {
|
||||
let mem_desc = &m.imported_memories[import_mem_index].1;
|
||||
match mem_desc.memory_type() {
|
||||
MemoryType::Dynamic => &INTRINSICS_IMPORTED_DYNAMIC_MEMORY,
|
||||
MemoryType::Static => &INTRINSICS_IMPORTED_STATIC_MEMORY,
|
||||
MemoryType::SharedStatic => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ctx {
|
||||
@ -82,6 +155,8 @@ impl Ctx {
|
||||
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
||||
|
||||
dynamic_sigindices: local_backing.dynamic_sigindices.as_ptr(),
|
||||
|
||||
intrinsics: get_intrinsics_for_module(&module.info),
|
||||
},
|
||||
local_functions: local_backing.local_functions.as_ptr(),
|
||||
|
||||
@ -114,6 +189,8 @@ impl Ctx {
|
||||
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
||||
|
||||
dynamic_sigindices: local_backing.dynamic_sigindices.as_ptr(),
|
||||
|
||||
intrinsics: get_intrinsics_for_module(&module.info),
|
||||
},
|
||||
local_functions: local_backing.local_functions.as_ptr(),
|
||||
|
||||
@ -207,9 +284,13 @@ impl Ctx {
|
||||
7 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
|
||||
pub fn offset_local_functions() -> u8 {
|
||||
pub fn offset_intrinsics() -> u8 {
|
||||
8 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
|
||||
pub fn offset_local_functions() -> u8 {
|
||||
9 * (mem::size_of::<usize>() as u8)
|
||||
}
|
||||
}
|
||||
|
||||
enum InnerFunc {}
|
||||
@ -403,6 +484,11 @@ mod vm_offset_tests {
|
||||
offset_of!(InternalCtx => imported_funcs).get_byte_offset(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Ctx::offset_intrinsics() as usize,
|
||||
offset_of!(InternalCtx => intrinsics).get_byte_offset(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Ctx::offset_local_functions() as usize,
|
||||
offset_of!(Ctx => local_functions).get_byte_offset(),
|
||||
|
@ -3284,33 +3284,20 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
||||
Operator::Nop => {}
|
||||
Operator::MemorySize { reserved } => {
|
||||
let memory_index = MemoryIndex::new(reserved as usize);
|
||||
let target: usize = match memory_index.local_or_import(module_info) {
|
||||
LocalOrImport::Local(local_mem_index) => {
|
||||
let mem_desc = &module_info.memories[local_mem_index];
|
||||
match mem_desc.memory_type() {
|
||||
MemoryType::Dynamic => vmcalls::local_dynamic_memory_size as usize,
|
||||
MemoryType::Static => vmcalls::local_static_memory_size as usize,
|
||||
MemoryType::SharedStatic => unimplemented!(),
|
||||
}
|
||||
}
|
||||
LocalOrImport::Import(import_mem_index) => {
|
||||
let mem_desc = &module_info.imported_memories[import_mem_index].1;
|
||||
match mem_desc.memory_type() {
|
||||
MemoryType::Dynamic => vmcalls::imported_dynamic_memory_size as usize,
|
||||
MemoryType::Static => vmcalls::imported_static_memory_size as usize,
|
||||
MemoryType::SharedStatic => unimplemented!(),
|
||||
}
|
||||
}
|
||||
};
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Memory(Machine::get_vmctx_reg(), vm::Ctx::offset_intrinsics() as i32),
|
||||
Location::GPR(GPR::RAX)
|
||||
);
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Memory(GPR::RAX, vm::Intrinsics::offset_memory_size() as i32),
|
||||
Location::GPR(GPR::RAX)
|
||||
);
|
||||
Self::emit_call_sysv(
|
||||
a,
|
||||
&mut self.machine,
|
||||
|a| {
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Imm64(target as u64),
|
||||
Location::GPR(GPR::RAX),
|
||||
);
|
||||
a.emit_call_location(Location::GPR(GPR::RAX));
|
||||
},
|
||||
::std::iter::once(Location::Imm32(memory_index.index() as u32)),
|
||||
@ -3321,40 +3308,27 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
||||
}
|
||||
Operator::MemoryGrow { reserved } => {
|
||||
let memory_index = MemoryIndex::new(reserved as usize);
|
||||
let target: usize = match memory_index.local_or_import(module_info) {
|
||||
LocalOrImport::Local(local_mem_index) => {
|
||||
let mem_desc = &module_info.memories[local_mem_index];
|
||||
match mem_desc.memory_type() {
|
||||
MemoryType::Dynamic => vmcalls::local_dynamic_memory_grow as usize,
|
||||
MemoryType::Static => vmcalls::local_static_memory_grow as usize,
|
||||
MemoryType::SharedStatic => unimplemented!(),
|
||||
}
|
||||
}
|
||||
LocalOrImport::Import(import_mem_index) => {
|
||||
let mem_desc = &module_info.imported_memories[import_mem_index].1;
|
||||
match mem_desc.memory_type() {
|
||||
MemoryType::Dynamic => vmcalls::imported_dynamic_memory_grow as usize,
|
||||
MemoryType::Static => vmcalls::imported_static_memory_grow as usize,
|
||||
MemoryType::SharedStatic => unimplemented!(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let (param_pages, param_pages_lot) = self.value_stack.pop().unwrap();
|
||||
|
||||
if param_pages_lot == LocalOrTemp::Temp {
|
||||
self.machine.release_locations_only_regs(&[param_pages]);
|
||||
}
|
||||
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Memory(Machine::get_vmctx_reg(), vm::Ctx::offset_intrinsics() as i32),
|
||||
Location::GPR(GPR::RAX)
|
||||
);
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Memory(GPR::RAX, vm::Intrinsics::offset_memory_grow() as i32),
|
||||
Location::GPR(GPR::RAX)
|
||||
);
|
||||
|
||||
Self::emit_call_sysv(
|
||||
a,
|
||||
&mut self.machine,
|
||||
|a| {
|
||||
a.emit_mov(
|
||||
Size::S64,
|
||||
Location::Imm64(target as u64),
|
||||
Location::GPR(GPR::RAX),
|
||||
);
|
||||
a.emit_call_location(Location::GPR(GPR::RAX));
|
||||
},
|
||||
::std::iter::once(Location::Imm32(memory_index.index() as u32))
|
||||
|
Loading…
Reference in New Issue
Block a user