mirror of
https://github.com/fluencelabs/wasmer
synced 2025-03-16 16:20:49 +00:00
Add memory_grow*, memory_size vmcalls
This commit is contained in:
parent
0f3833fecb
commit
98c9ce5ed9
@ -10,8 +10,8 @@ use crate::runtime::{
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LocalBacking {
|
||||
memories: Box<[LinearMemory]>,
|
||||
tables: Box<[TableBacking]>,
|
||||
pub memories: Box<[LinearMemory]>,
|
||||
pub tables: Box<[TableBacking]>,
|
||||
|
||||
pub vm_memories: Box<[vm::LocalMemory]>,
|
||||
pub vm_tables: Box<[vm::LocalTable]>,
|
||||
|
@ -14,7 +14,7 @@ use std::iter;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct Instance {
|
||||
backing: LocalBacking,
|
||||
pub (in crate::runtime) backing: LocalBacking,
|
||||
import_backing: ImportBacking,
|
||||
sig_registry: SigRegistry,
|
||||
pub module: Arc<Module>,
|
||||
@ -43,6 +43,26 @@ impl Instance {
|
||||
Ok(instance)
|
||||
}
|
||||
|
||||
/// Call an exported webassembly function given the export name.
|
||||
/// Pass arguments by wrapping each one in the `Val` enum.
|
||||
/// The returned value is also returned in a `Val`.
|
||||
///
|
||||
/// This will eventually return `Result<Option<Vec<Val>>, String>` in
|
||||
/// order to support multi-value returns.
|
||||
pub fn call(&mut self, name: &str, args: &[Val]) -> Result<Option<Val>, String> {
|
||||
let func_index = *self
|
||||
.module
|
||||
.exports
|
||||
.get(name)
|
||||
.ok_or_else(|| "there is no export with that name".to_string())
|
||||
.and_then(|export| match export {
|
||||
Export::Func(func_index) => Ok(func_index),
|
||||
_ => Err("that export is not a function".to_string()),
|
||||
})?;
|
||||
|
||||
self.call_with_index(func_index, args)
|
||||
}
|
||||
|
||||
fn call_with_index(
|
||||
&mut self,
|
||||
func_index: FuncIndex,
|
||||
@ -54,15 +74,18 @@ impl Instance {
|
||||
.signature_assoc
|
||||
.get(func_index)
|
||||
.expect("broken invariant, incorrect func index");
|
||||
let signature = &self.module.signatures[sig_index];
|
||||
|
||||
{
|
||||
let signature = &self.module.signatures[sig_index];
|
||||
|
||||
assert!(
|
||||
signature.returns.len() <= 1,
|
||||
"multi-value returns not yet supported"
|
||||
);
|
||||
assert!(
|
||||
signature.returns.len() <= 1,
|
||||
"multi-value returns not yet supported"
|
||||
);
|
||||
|
||||
if !signature.check_sig(args) {
|
||||
return Err("incorrect signature".to_string());
|
||||
if !signature.check_sig(args) {
|
||||
return Err("incorrect signature".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// the vmctx will be located at the same place on the stack the entire time that this
|
||||
@ -93,7 +116,7 @@ impl Instance {
|
||||
);
|
||||
|
||||
call_protected(|| {
|
||||
signature
|
||||
self.module.signatures[sig_index]
|
||||
.returns
|
||||
.first()
|
||||
.map(|ty| match ty {
|
||||
@ -111,26 +134,6 @@ impl Instance {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Call an exported webassembly function given the export name.
|
||||
/// Pass arguments by wrapping each one in the `Val` enum.
|
||||
/// The returned value is also returned in a `Val`.
|
||||
///
|
||||
/// This will eventually return `Result<Option<Vec<Val>>, String>` in
|
||||
/// order to support multi-value returns.
|
||||
pub fn call(&mut self, name: &str, args: &[Val]) -> Result<Option<Val>, String> {
|
||||
let func_index = *self
|
||||
.module
|
||||
.exports
|
||||
.get(name)
|
||||
.ok_or_else(|| "there is no export with that name".to_string())
|
||||
.and_then(|export| match export {
|
||||
Export::Func(func_index) => Ok(func_index),
|
||||
_ => Err("that export is not a function".to_string()),
|
||||
})?;
|
||||
|
||||
self.call_with_index(func_index, args)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -7,6 +7,7 @@ mod sig_registry;
|
||||
mod table;
|
||||
pub mod types;
|
||||
pub mod vm;
|
||||
pub mod vmcalls;
|
||||
|
||||
pub use self::backend::Compiler;
|
||||
pub use self::instance::{Import, Imports, Instance};
|
||||
|
@ -1,8 +1,4 @@
|
||||
use crate::runtime::{
|
||||
// types::{
|
||||
// MemoryIndex, TableIndex, GlobalIndex, FuncIndex,
|
||||
// SigIndex,
|
||||
// },
|
||||
backing::{ImportBacking, LocalBacking},
|
||||
sig_registry::SigRegistry,
|
||||
};
|
||||
@ -34,6 +30,9 @@ pub struct Ctx {
|
||||
|
||||
/// Signature identifiers for signature-checked indirect calls.
|
||||
pub signatures: *const SigId,
|
||||
|
||||
/// The parent instance.
|
||||
pub local_backing: *mut LocalBacking,
|
||||
}
|
||||
|
||||
impl Ctx {
|
||||
@ -53,6 +52,7 @@ impl Ctx {
|
||||
imported_funcs: import_backing.functions.as_mut_ptr(),
|
||||
|
||||
signatures: sig_registry.into_vm_signatures(),
|
||||
local_backing: local_backing,
|
||||
}
|
||||
}
|
||||
|
||||
|
18
src/runtime/vmcalls.rs
Normal file
18
src/runtime/vmcalls.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::runtime::{
|
||||
vm,
|
||||
memory::LinearMemory,
|
||||
};
|
||||
|
||||
pub unsafe extern fn memory_grow_static(memory_index: u32, by_pages: u32, ctx: *mut vm::Ctx) -> i32 {
|
||||
if let Some(old) = (*(*ctx).local_backing).memories[memory_index as usize].grow_static(by_pages) {
|
||||
// Store the new size back into the vmctx.
|
||||
(*(*ctx).memories.add(memory_index as usize)).size = (old as usize + by_pages as usize) * LinearMemory::PAGE_SIZE as usize;
|
||||
old
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe extern fn memory_size(memory_index: u32, ctx: *mut vm::Ctx) -> u32 {
|
||||
(*(*ctx).local_backing).memories[memory_index as usize].current_pages()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user