mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 13:18:20 +00:00
Implement Exportable for NativeFunc
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
use crate::externals::{Extern, Function, Global, Memory, Table};
|
||||
use crate::import_object::LikeNamespace;
|
||||
use crate::native::NativeFunc;
|
||||
use indexmap::IndexMap;
|
||||
use std::{
|
||||
iter::{ExactSizeIterator, FromIterator},
|
||||
sync::Arc,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use wasm_common::WasmTypeList;
|
||||
use wasmer_runtime::Export;
|
||||
|
||||
/// The `ExportError` can happen when trying to get a specific
|
||||
@@ -89,7 +91,7 @@ impl Exports {
|
||||
///
|
||||
/// If you want to get an export dynamically handling manually
|
||||
/// type checking manually, please use `get_extern`.
|
||||
pub fn get<'a, T: Exportable<'a>>(&'a self, name: &str) -> Result<&T, ExportError> {
|
||||
pub fn get<'a, T: Exportable<'a>>(&'a self, name: &str) -> Result<T, ExportError> {
|
||||
match self.map.get(name) {
|
||||
None => Err(ExportError::Missing(name.to_string())),
|
||||
Some(extern_) => T::get_self_from_extern(extern_),
|
||||
@@ -97,32 +99,36 @@ impl Exports {
|
||||
}
|
||||
|
||||
/// Get an export as a `Global`.
|
||||
pub fn get_global(&self, name: &str) -> Result<&Global, ExportError> {
|
||||
pub fn get_global(&self, name: &str) -> Result<Global, ExportError> {
|
||||
self.get(name)
|
||||
}
|
||||
|
||||
/// Get an export as a `Memory`.
|
||||
pub fn get_memory(&self, name: &str) -> Result<&Memory, ExportError> {
|
||||
pub fn get_memory(&self, name: &str) -> Result<Memory, ExportError> {
|
||||
self.get(name)
|
||||
}
|
||||
|
||||
/// Get an export as a `Table`.
|
||||
pub fn get_table(&self, name: &str) -> Result<&Table, ExportError> {
|
||||
pub fn get_table(&self, name: &str) -> Result<Table, ExportError> {
|
||||
self.get(name)
|
||||
}
|
||||
|
||||
/// Get an export as a `Func`.
|
||||
pub fn get_function(&self, name: &str) -> Result<&Function, ExportError> {
|
||||
pub fn get_function(&self, name: &str) -> Result<Function, ExportError> {
|
||||
self.get(name)
|
||||
}
|
||||
|
||||
/*
|
||||
/// Get an export as a `Func`.
|
||||
pub fn get_native_function::<Args, Rets>(&self, name: &str) -> Result<&NativeFunction, ExportError> {
|
||||
// TODO:
|
||||
//self.get(name)
|
||||
/// Get an export as a `NativeFunc`.
|
||||
pub fn get_native_function<Args, Rets>(
|
||||
&self,
|
||||
name: &str,
|
||||
) -> Result<NativeFunc<Args, Rets>, ExportError>
|
||||
where
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
self.get(name)
|
||||
}
|
||||
*/
|
||||
|
||||
/// Get an export as an `Extern`.
|
||||
pub fn get_extern(&self, name: &str) -> Option<&Extern> {
|
||||
@@ -250,5 +256,5 @@ pub trait Exportable<'a>: Sized {
|
||||
/// from an [`Instance`] by name.
|
||||
///
|
||||
/// [`Instance`]: crate::Instance
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError>;
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<Self, ExportError>;
|
||||
}
|
||||
|
||||
4
lib/api/src/externals/function.rs
vendored
4
lib/api/src/externals/function.rs
vendored
@@ -317,9 +317,9 @@ impl<'a> Exportable<'a> for Function {
|
||||
fn to_export(&self) -> Export {
|
||||
self.exported.clone().into()
|
||||
}
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<Self, ExportError> {
|
||||
match _extern {
|
||||
Extern::Function(func) => Ok(func),
|
||||
Extern::Function(func) => Ok(func.clone()),
|
||||
_ => Err(ExportError::IncompatibleType),
|
||||
}
|
||||
}
|
||||
|
||||
4
lib/api/src/externals/global.rs
vendored
4
lib/api/src/externals/global.rs
vendored
@@ -130,9 +130,9 @@ impl<'a> Exportable<'a> for Global {
|
||||
self.exported.clone().into()
|
||||
}
|
||||
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<Self, ExportError> {
|
||||
match _extern {
|
||||
Extern::Global(global) => Ok(global),
|
||||
Extern::Global(global) => Ok(global.clone()),
|
||||
_ => Err(ExportError::IncompatibleType),
|
||||
}
|
||||
}
|
||||
|
||||
4
lib/api/src/externals/memory.rs
vendored
4
lib/api/src/externals/memory.rs
vendored
@@ -137,9 +137,9 @@ impl<'a> Exportable<'a> for Memory {
|
||||
fn to_export(&self) -> Export {
|
||||
self.exported.clone().into()
|
||||
}
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<Self, ExportError> {
|
||||
match _extern {
|
||||
Extern::Memory(memory) => Ok(memory),
|
||||
Extern::Memory(memory) => Ok(memory.clone()),
|
||||
_ => Err(ExportError::IncompatibleType),
|
||||
}
|
||||
}
|
||||
|
||||
4
lib/api/src/externals/mod.rs
vendored
4
lib/api/src/externals/mod.rs
vendored
@@ -51,9 +51,9 @@ impl<'a> Exportable<'a> for Extern {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<Self, ExportError> {
|
||||
// Since this is already an extern, we can just return it.
|
||||
Ok(_extern)
|
||||
Ok(_extern.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
4
lib/api/src/externals/table.rs
vendored
4
lib/api/src/externals/table.rs
vendored
@@ -158,9 +158,9 @@ impl<'a> Exportable<'a> for Table {
|
||||
fn to_export(&self) -> Export {
|
||||
self.exported.clone().into()
|
||||
}
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
fn get_self_from_extern(_extern: &'a Extern) -> Result<Self, ExportError> {
|
||||
match _extern {
|
||||
Extern::Table(table) => Ok(table),
|
||||
Extern::Table(table) => Ok(table.clone()),
|
||||
_ => Err(ExportError::IncompatibleType),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ use std::marker::PhantomData;
|
||||
|
||||
use crate::exports::{ExportError, Exportable};
|
||||
use crate::externals::function::{FunctionDefinition, WasmFunctionDefinition};
|
||||
use crate::{Extern, Function, FunctionType, RuntimeError, Store};
|
||||
use crate::{Extern, Function, FunctionType, Store};
|
||||
use wasm_common::{NativeWasmType, WasmExternType, WasmTypeList};
|
||||
use wasmer_runtime::{
|
||||
wasmer_call_trampoline, ExportFunction, VMContext, VMFunctionBody, VMFunctionKind, VMTrampoline,
|
||||
wasmer_call_trampoline, Export, ExportFunction, VMContext, VMFunctionBody, VMFunctionKind,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -15,29 +15,6 @@ pub struct UnprovidedArgs;
|
||||
#[derive(Clone)]
|
||||
pub struct UnprovidedRets;
|
||||
|
||||
/// This is just an empty trait to constrict that types that
|
||||
/// can be put into the third/fourth (depending if you include lifetimes)
|
||||
/// of the `NativeFunc` struct.
|
||||
pub trait Kind {}
|
||||
|
||||
/// TODO(lachlan): Naming TBD.
|
||||
/// This contains the trampoline and invoke functions for a specific signature,
|
||||
/// as well as the environment that the invoke function may or may not require.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Wasm {
|
||||
pub(crate) trampoline: VMTrampoline,
|
||||
//pub(crate) invoke: Invoke,
|
||||
//pub(crate) invoke_env: Option<NonNull<c_void>>,
|
||||
}
|
||||
|
||||
impl Kind for Wasm {}
|
||||
|
||||
/// This type, as part of the `NativeFunc` type signature, represents a function that is created
|
||||
/// by the host.
|
||||
pub struct Host(());
|
||||
|
||||
impl Kind for Host {}
|
||||
|
||||
pub struct NativeFunc<'a, Args = UnprovidedArgs, Rets = UnprovidedRets> {
|
||||
definition: FunctionDefinition,
|
||||
store: Store,
|
||||
@@ -69,35 +46,53 @@ impl<'a, Args, Rets> NativeFunc<'a, Args, Rets> {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl<'a, Args, Rets> Exportable for NativeFunc<'a, Args, Rets>
|
||||
impl<'a, Args, Rets> Exportable<'a> for NativeFunc<'a, Args, Rets>
|
||||
where
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
fn to_export(&self) -> Export {
|
||||
todo!("implement this")
|
||||
let ef: ExportFunction = self.into();
|
||||
ef.into()
|
||||
}
|
||||
|
||||
// Cannot be implemented because of the return type `&Self` TODO:
|
||||
fn get_self_from_extern(extern_: &'a Extern) -> Result<&'a Self, ExportError> {
|
||||
fn get_self_from_extern(extern_: &'a Extern) -> Result<Self, ExportError> {
|
||||
match extern_ {
|
||||
// TODO: review error return type in failure of `f.native()`
|
||||
Extern::Function(f) => f.native().ok_or_else(|| ExportError::IncompatibleType),
|
||||
Extern::Function(f) => f
|
||||
.clone()
|
||||
.native()
|
||||
.ok_or_else(|| ExportError::IncompatibleType),
|
||||
_ => Err(ExportError::IncompatibleType),
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl<'a, Args, Rets> From<&NativeFunc<'a, Args, Rets>> for ExportFunction
|
||||
where
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
fn from(other: &NativeFunc<'a, Args, Rets>) -> Self {
|
||||
let signature = FunctionType::new(Args::wasm_types(), Rets::wasm_types());
|
||||
Self {
|
||||
address: other.address,
|
||||
vmctx: other.vmctx,
|
||||
signature,
|
||||
kind: other.arg_kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Args, Rets> From<NativeFunc<'a, Args, Rets>> for Function
|
||||
where
|
||||
Args: WasmTypeList,
|
||||
Rets: WasmTypeList,
|
||||
{
|
||||
fn from(other: NativeFunc<'a, Args, Rets>) -> Function {
|
||||
fn from(other: NativeFunc<'a, Args, Rets>) -> Self {
|
||||
let signature = FunctionType::new(Args::wasm_types(), Rets::wasm_types());
|
||||
Function {
|
||||
Self {
|
||||
store: other.store,
|
||||
definition: other.definition,
|
||||
owned_by_store: true, // todo
|
||||
|
||||
@@ -111,10 +111,10 @@ impl Wasi {
|
||||
|
||||
let instance = Instance::new(&module, &import_object)?;
|
||||
|
||||
let memory: &Memory = instance.exports.get("memory")?;
|
||||
wasi_env.set_memory(memory);
|
||||
let memory: Memory = instance.exports.get("memory")?;
|
||||
wasi_env.set_memory(&memory);
|
||||
|
||||
let start: &Function = instance.exports.get("_start")?;
|
||||
let start: Function = instance.exports.get("_start")?;
|
||||
|
||||
start
|
||||
.call(&[])
|
||||
|
||||
@@ -341,7 +341,7 @@ impl Wast {
|
||||
args: &[Val],
|
||||
) -> Result<Vec<Val>> {
|
||||
let instance = self.get_instance(instance_name.as_ref().map(|x| &**x))?;
|
||||
let func: &Function = instance.exports.get(field)?;
|
||||
let func: Function = instance.exports.get(field)?;
|
||||
match func.call(args) {
|
||||
Ok(result) => Ok(result.into()),
|
||||
Err(e) => Err(e.into()),
|
||||
@@ -351,7 +351,7 @@ impl Wast {
|
||||
/// Get the value of an exported global from an instance.
|
||||
fn get(&mut self, instance_name: Option<&str>, field: &str) -> Result<Vec<Val>> {
|
||||
let instance = self.get_instance(instance_name.as_ref().map(|x| &**x))?;
|
||||
let global: &Global = instance.exports.get(field)?;
|
||||
let global: Global = instance.exports.get(field)?;
|
||||
Ok(vec![global.get()])
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user