mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 14:25:32 +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};
|
pub use crate::backing::{ImportBacking, LocalBacking};
|
||||||
use crate::{
|
use crate::{
|
||||||
memory::Memory,
|
memory::{Memory, MemoryType},
|
||||||
module::ModuleInner,
|
module::{ModuleInfo, ModuleInner},
|
||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
types::{LocalOrImport, MemoryIndex},
|
types::{LocalOrImport, MemoryIndex, LocalMemoryIndex},
|
||||||
|
units::{Pages},
|
||||||
|
vmcalls,
|
||||||
};
|
};
|
||||||
use std::{ffi::c_void, mem, ptr};
|
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
|
/// signature id. This is used to allow call-indirect to other
|
||||||
/// modules safely.
|
/// modules safely.
|
||||||
pub dynamic_sigindices: *const SigId,
|
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 {
|
impl Ctx {
|
||||||
@ -82,6 +155,8 @@ impl Ctx {
|
|||||||
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
||||||
|
|
||||||
dynamic_sigindices: local_backing.dynamic_sigindices.as_ptr(),
|
dynamic_sigindices: local_backing.dynamic_sigindices.as_ptr(),
|
||||||
|
|
||||||
|
intrinsics: get_intrinsics_for_module(&module.info),
|
||||||
},
|
},
|
||||||
local_functions: local_backing.local_functions.as_ptr(),
|
local_functions: local_backing.local_functions.as_ptr(),
|
||||||
|
|
||||||
@ -114,6 +189,8 @@ impl Ctx {
|
|||||||
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
imported_funcs: import_backing.vm_functions.as_mut_ptr(),
|
||||||
|
|
||||||
dynamic_sigindices: local_backing.dynamic_sigindices.as_ptr(),
|
dynamic_sigindices: local_backing.dynamic_sigindices.as_ptr(),
|
||||||
|
|
||||||
|
intrinsics: get_intrinsics_for_module(&module.info),
|
||||||
},
|
},
|
||||||
local_functions: local_backing.local_functions.as_ptr(),
|
local_functions: local_backing.local_functions.as_ptr(),
|
||||||
|
|
||||||
@ -207,9 +284,13 @@ impl Ctx {
|
|||||||
7 * (mem::size_of::<usize>() as u8)
|
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)
|
8 * (mem::size_of::<usize>() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn offset_local_functions() -> u8 {
|
||||||
|
9 * (mem::size_of::<usize>() as u8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum InnerFunc {}
|
enum InnerFunc {}
|
||||||
@ -403,6 +484,11 @@ mod vm_offset_tests {
|
|||||||
offset_of!(InternalCtx => imported_funcs).get_byte_offset(),
|
offset_of!(InternalCtx => imported_funcs).get_byte_offset(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Ctx::offset_intrinsics() as usize,
|
||||||
|
offset_of!(InternalCtx => intrinsics).get_byte_offset(),
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ctx::offset_local_functions() as usize,
|
Ctx::offset_local_functions() as usize,
|
||||||
offset_of!(Ctx => local_functions).get_byte_offset(),
|
offset_of!(Ctx => local_functions).get_byte_offset(),
|
||||||
|
@ -3284,33 +3284,20 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
Operator::Nop => {}
|
Operator::Nop => {}
|
||||||
Operator::MemorySize { reserved } => {
|
Operator::MemorySize { reserved } => {
|
||||||
let memory_index = MemoryIndex::new(reserved as usize);
|
let memory_index = MemoryIndex::new(reserved as usize);
|
||||||
let target: usize = match memory_index.local_or_import(module_info) {
|
a.emit_mov(
|
||||||
LocalOrImport::Local(local_mem_index) => {
|
Size::S64,
|
||||||
let mem_desc = &module_info.memories[local_mem_index];
|
Location::Memory(Machine::get_vmctx_reg(), vm::Ctx::offset_intrinsics() as i32),
|
||||||
match mem_desc.memory_type() {
|
Location::GPR(GPR::RAX)
|
||||||
MemoryType::Dynamic => vmcalls::local_dynamic_memory_size as usize,
|
);
|
||||||
MemoryType::Static => vmcalls::local_static_memory_size as usize,
|
a.emit_mov(
|
||||||
MemoryType::SharedStatic => unimplemented!(),
|
Size::S64,
|
||||||
}
|
Location::Memory(GPR::RAX, vm::Intrinsics::offset_memory_size() as i32),
|
||||||
}
|
Location::GPR(GPR::RAX)
|
||||||
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!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Self::emit_call_sysv(
|
Self::emit_call_sysv(
|
||||||
a,
|
a,
|
||||||
&mut self.machine,
|
&mut self.machine,
|
||||||
|a| {
|
|a| {
|
||||||
a.emit_mov(
|
|
||||||
Size::S64,
|
|
||||||
Location::Imm64(target as u64),
|
|
||||||
Location::GPR(GPR::RAX),
|
|
||||||
);
|
|
||||||
a.emit_call_location(Location::GPR(GPR::RAX));
|
a.emit_call_location(Location::GPR(GPR::RAX));
|
||||||
},
|
},
|
||||||
::std::iter::once(Location::Imm32(memory_index.index() as u32)),
|
::std::iter::once(Location::Imm32(memory_index.index() as u32)),
|
||||||
@ -3321,40 +3308,27 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
}
|
}
|
||||||
Operator::MemoryGrow { reserved } => {
|
Operator::MemoryGrow { reserved } => {
|
||||||
let memory_index = MemoryIndex::new(reserved as usize);
|
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();
|
let (param_pages, param_pages_lot) = self.value_stack.pop().unwrap();
|
||||||
|
|
||||||
if param_pages_lot == LocalOrTemp::Temp {
|
if param_pages_lot == LocalOrTemp::Temp {
|
||||||
self.machine.release_locations_only_regs(&[param_pages]);
|
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(
|
Self::emit_call_sysv(
|
||||||
a,
|
a,
|
||||||
&mut self.machine,
|
&mut self.machine,
|
||||||
|a| {
|
|a| {
|
||||||
a.emit_mov(
|
|
||||||
Size::S64,
|
|
||||||
Location::Imm64(target as u64),
|
|
||||||
Location::GPR(GPR::RAX),
|
|
||||||
);
|
|
||||||
a.emit_call_location(Location::GPR(GPR::RAX));
|
a.emit_call_location(Location::GPR(GPR::RAX));
|
||||||
},
|
},
|
||||||
::std::iter::once(Location::Imm32(memory_index.index() as u32))
|
::std::iter::once(Location::Imm32(memory_index.index() as u32))
|
||||||
|
Loading…
Reference in New Issue
Block a user