mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-25 22:51:32 +00:00
Implement function lookups using the table
This commit is contained in:
@ -518,7 +518,7 @@ impl LikeNamespace for Rc<Instance> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn call_func_with_index(
|
fn call_func_with_index(
|
||||||
info: &ModuleInfo,
|
info: &ModuleInfo,
|
||||||
runnable: &dyn RunnableModule,
|
runnable: &dyn RunnableModule,
|
||||||
import_backing: &ImportBacking,
|
import_backing: &ImportBacking,
|
||||||
@ -527,29 +527,12 @@ pub(crate) fn call_func_with_index(
|
|||||||
args: &[Value],
|
args: &[Value],
|
||||||
rets: &mut Vec<Value>,
|
rets: &mut Vec<Value>,
|
||||||
) -> CallResult<()> {
|
) -> CallResult<()> {
|
||||||
rets.clear();
|
|
||||||
|
|
||||||
let sig_index = *info
|
let sig_index = *info
|
||||||
.func_assoc
|
.func_assoc
|
||||||
.get(func_index)
|
.get(func_index)
|
||||||
.expect("broken invariant, incorrect func index");
|
.expect("broken invariant, incorrect func index");
|
||||||
|
|
||||||
let signature = &info.signatures[sig_index];
|
let signature = &info.signatures[sig_index];
|
||||||
let num_results = signature.returns().len();
|
|
||||||
let num_results = num_results
|
|
||||||
+ signature
|
|
||||||
.returns()
|
|
||||||
.iter()
|
|
||||||
.filter(|&&ty| ty == Type::V128)
|
|
||||||
.count();
|
|
||||||
rets.reserve(num_results);
|
|
||||||
|
|
||||||
if !signature.check_param_value_types(args) {
|
|
||||||
Err(ResolveError::Signature {
|
|
||||||
expected: signature.clone(),
|
|
||||||
found: args.iter().map(|val| val.ty()).collect(),
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
|
|
||||||
let func_ptr = match func_index.local_or_import(info) {
|
let func_ptr = match func_index.local_or_import(info) {
|
||||||
LocalOrImport::Local(local_func_index) => {
|
LocalOrImport::Local(local_func_index) => {
|
||||||
@ -567,6 +550,39 @@ pub(crate) fn call_func_with_index(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let wasm = runnable
|
||||||
|
.get_trampoline(info, sig_index)
|
||||||
|
.expect("wasm trampoline");
|
||||||
|
|
||||||
|
call_func_with_index_inner(ctx_ptr, func_ptr, signature, wasm, args, rets)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn call_func_with_index_inner(
|
||||||
|
ctx_ptr: *mut vm::Ctx,
|
||||||
|
func_ptr: NonNull<vm::Func>,
|
||||||
|
signature: &FuncSig,
|
||||||
|
wasm: Wasm,
|
||||||
|
args: &[Value],
|
||||||
|
rets: &mut Vec<Value>,
|
||||||
|
) -> CallResult<()> {
|
||||||
|
rets.clear();
|
||||||
|
|
||||||
|
let num_results = signature.returns().len();
|
||||||
|
let num_results = num_results
|
||||||
|
+ signature
|
||||||
|
.returns()
|
||||||
|
.iter()
|
||||||
|
.filter(|&&ty| ty == Type::V128)
|
||||||
|
.count();
|
||||||
|
rets.reserve(num_results);
|
||||||
|
|
||||||
|
if !signature.check_param_value_types(args) {
|
||||||
|
Err(ResolveError::Signature {
|
||||||
|
expected: signature.clone(),
|
||||||
|
found: args.iter().map(|val| val.ty()).collect(),
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
|
||||||
let mut raw_args: SmallVec<[u64; 8]> = SmallVec::new();
|
let mut raw_args: SmallVec<[u64; 8]> = SmallVec::new();
|
||||||
for v in args {
|
for v in args {
|
||||||
match v {
|
match v {
|
||||||
@ -598,9 +614,7 @@ pub(crate) fn call_func_with_index(
|
|||||||
trampoline,
|
trampoline,
|
||||||
invoke,
|
invoke,
|
||||||
invoke_env,
|
invoke_env,
|
||||||
} = runnable
|
} = wasm;
|
||||||
.get_trampoline(info, sig_index)
|
|
||||||
.expect("wasm trampoline");
|
|
||||||
|
|
||||||
let run_wasm = |result_space: *mut u64| unsafe {
|
let run_wasm = |result_space: *mut u64| unsafe {
|
||||||
let mut trap_info = WasmTrapInfo::Unknown;
|
let mut trap_info = WasmTrapInfo::Unknown;
|
||||||
|
@ -44,7 +44,7 @@ impl<'a> From<DynFunc<'a>> for Anyfunc<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct AnyfuncTable {
|
pub struct AnyfuncTable {
|
||||||
backing: Vec<vm::Anyfunc>,
|
pub backing: Vec<vm::Anyfunc>,
|
||||||
max: Option<u32>,
|
max: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,7 @@ use std::{cell::RefCell, fmt, ptr, rc::Rc};
|
|||||||
|
|
||||||
mod anyfunc;
|
mod anyfunc;
|
||||||
|
|
||||||
pub use self::anyfunc::Anyfunc;
|
pub use self::anyfunc::{Anyfunc, AnyfuncTable};
|
||||||
use self::anyfunc::AnyfuncTable;
|
|
||||||
use crate::error::GrowError;
|
use crate::error::GrowError;
|
||||||
|
|
||||||
pub enum Element<'a> {
|
pub enum Element<'a> {
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
pub use crate::backing::{ImportBacking, LocalBacking, INTERNALS_SIZE};
|
pub use crate::backing::{ImportBacking, LocalBacking, INTERNALS_SIZE};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{CallError, CallResult, RuntimeError},
|
error::CallResult,
|
||||||
instance::call_func_with_index,
|
instance::call_func_with_index_inner,
|
||||||
memory::{Memory, MemoryType},
|
memory::{Memory, MemoryType},
|
||||||
module::{ModuleInfo, ModuleInner},
|
module::{ModuleInfo, ModuleInner},
|
||||||
|
sig_registry::SigRegistry,
|
||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
types::{FuncIndex, LocalOrImport, MemoryIndex, Value},
|
types::{LocalOrImport, MemoryIndex, TableIndex, Value},
|
||||||
vmcalls,
|
vmcalls,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
cell::UnsafeCell,
|
cell::UnsafeCell,
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
mem, ptr,
|
mem,
|
||||||
|
ptr::{self, NonNull},
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
sync::Once,
|
sync::Once,
|
||||||
};
|
};
|
||||||
@ -397,24 +399,36 @@ impl Ctx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls a host or Wasm function at the given index
|
/// Calls a host or Wasm function at the given index
|
||||||
pub fn call_with_index(&mut self, index: FuncIndex, args: &[Value]) -> CallResult<Vec<Value>> {
|
pub fn call_with_index(&mut self, index: TableIndex, args: &[Value]) -> CallResult<Vec<Value>> {
|
||||||
let module = unsafe { &(*self.module) };
|
let anyfunc_table =
|
||||||
if module.info.func_assoc.get(index).is_none() {
|
unsafe { &*((**self.internal.tables).table as *mut crate::table::AnyfuncTable) };
|
||||||
return Err(CallError::Runtime(RuntimeError::Trap {
|
let entry = anyfunc_table.backing[index.index()];
|
||||||
msg: format!("Index out of bounds: {}", index.index()).into_boxed_str(),
|
|
||||||
}));
|
let fn_ptr = entry.func;
|
||||||
}
|
let sig_id = entry.sig_id;
|
||||||
let mut output = vec![];
|
let signature = SigRegistry.lookup_signature(unsafe { std::mem::transmute(sig_id.0) });
|
||||||
call_func_with_index(
|
let mut rets = vec![];
|
||||||
&module.info,
|
|
||||||
module.runnable_module.as_ref(),
|
let wasm = {
|
||||||
unsafe { &*self.import_backing },
|
let module = unsafe { &*self.module };
|
||||||
self as *mut Ctx,
|
let runnable = &module.runnable_module;
|
||||||
index,
|
|
||||||
|
let sig_index = SigRegistry.lookup_sig_index(signature.clone());
|
||||||
|
runnable
|
||||||
|
.get_trampoline(&module.info, sig_index)
|
||||||
|
.expect("wasm trampoline")
|
||||||
|
};
|
||||||
|
|
||||||
|
call_func_with_index_inner(
|
||||||
|
self as *mut Ctx, /* doesn't handle all cases */
|
||||||
|
NonNull::new(fn_ptr as *mut _).unwrap(),
|
||||||
|
&signature,
|
||||||
|
wasm,
|
||||||
args,
|
args,
|
||||||
&mut output,
|
&mut rets,
|
||||||
)?;
|
)?;
|
||||||
Ok(output)
|
|
||||||
|
Ok(rets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user