mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 06:08:29 +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::externals::{Extern, Function, Global, Memory, Table};
|
||||||
use crate::import_object::LikeNamespace;
|
use crate::import_object::LikeNamespace;
|
||||||
|
use crate::native::NativeFunc;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use std::{
|
use std::{
|
||||||
iter::{ExactSizeIterator, FromIterator},
|
iter::{ExactSizeIterator, FromIterator},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use wasm_common::WasmTypeList;
|
||||||
use wasmer_runtime::Export;
|
use wasmer_runtime::Export;
|
||||||
|
|
||||||
/// The `ExportError` can happen when trying to get a specific
|
/// 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
|
/// If you want to get an export dynamically handling manually
|
||||||
/// type checking manually, please use `get_extern`.
|
/// 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) {
|
match self.map.get(name) {
|
||||||
None => Err(ExportError::Missing(name.to_string())),
|
None => Err(ExportError::Missing(name.to_string())),
|
||||||
Some(extern_) => T::get_self_from_extern(extern_),
|
Some(extern_) => T::get_self_from_extern(extern_),
|
||||||
@@ -97,32 +99,36 @@ impl Exports {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get an export as a `Global`.
|
/// 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)
|
self.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an export as a `Memory`.
|
/// 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)
|
self.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an export as a `Table`.
|
/// 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)
|
self.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an export as a `Func`.
|
/// 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)
|
self.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Get an export as a `NativeFunc`.
|
||||||
/// Get an export as a `Func`.
|
pub fn get_native_function<Args, Rets>(
|
||||||
pub fn get_native_function::<Args, Rets>(&self, name: &str) -> Result<&NativeFunction, ExportError> {
|
&self,
|
||||||
// TODO:
|
name: &str,
|
||||||
//self.get(name)
|
) -> Result<NativeFunc<Args, Rets>, ExportError>
|
||||||
|
where
|
||||||
|
Args: WasmTypeList,
|
||||||
|
Rets: WasmTypeList,
|
||||||
|
{
|
||||||
|
self.get(name)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/// Get an export as an `Extern`.
|
/// Get an export as an `Extern`.
|
||||||
pub fn get_extern(&self, name: &str) -> Option<&Extern> {
|
pub fn get_extern(&self, name: &str) -> Option<&Extern> {
|
||||||
@@ -250,5 +256,5 @@ pub trait Exportable<'a>: Sized {
|
|||||||
/// from an [`Instance`] by name.
|
/// from an [`Instance`] by name.
|
||||||
///
|
///
|
||||||
/// [`Instance`]: crate::Instance
|
/// [`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 {
|
fn to_export(&self) -> Export {
|
||||||
self.exported.clone().into()
|
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 {
|
match _extern {
|
||||||
Extern::Function(func) => Ok(func),
|
Extern::Function(func) => Ok(func.clone()),
|
||||||
_ => Err(ExportError::IncompatibleType),
|
_ => 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()
|
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 {
|
match _extern {
|
||||||
Extern::Global(global) => Ok(global),
|
Extern::Global(global) => Ok(global.clone()),
|
||||||
_ => Err(ExportError::IncompatibleType),
|
_ => 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 {
|
fn to_export(&self) -> Export {
|
||||||
self.exported.clone().into()
|
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 {
|
match _extern {
|
||||||
Extern::Memory(memory) => Ok(memory),
|
Extern::Memory(memory) => Ok(memory.clone()),
|
||||||
_ => Err(ExportError::IncompatibleType),
|
_ => 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.
|
// 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 {
|
fn to_export(&self) -> Export {
|
||||||
self.exported.clone().into()
|
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 {
|
match _extern {
|
||||||
Extern::Table(table) => Ok(table),
|
Extern::Table(table) => Ok(table.clone()),
|
||||||
_ => Err(ExportError::IncompatibleType),
|
_ => Err(ExportError::IncompatibleType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ use std::marker::PhantomData;
|
|||||||
|
|
||||||
use crate::exports::{ExportError, Exportable};
|
use crate::exports::{ExportError, Exportable};
|
||||||
use crate::externals::function::{FunctionDefinition, WasmFunctionDefinition};
|
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 wasm_common::{NativeWasmType, WasmExternType, WasmTypeList};
|
||||||
use wasmer_runtime::{
|
use wasmer_runtime::{
|
||||||
wasmer_call_trampoline, ExportFunction, VMContext, VMFunctionBody, VMFunctionKind, VMTrampoline,
|
wasmer_call_trampoline, Export, ExportFunction, VMContext, VMFunctionBody, VMFunctionKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -15,29 +15,6 @@ pub struct UnprovidedArgs;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnprovidedRets;
|
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> {
|
pub struct NativeFunc<'a, Args = UnprovidedArgs, Rets = UnprovidedRets> {
|
||||||
definition: FunctionDefinition,
|
definition: FunctionDefinition,
|
||||||
store: Store,
|
store: Store,
|
||||||
@@ -69,35 +46,53 @@ impl<'a, Args, Rets> NativeFunc<'a, Args, Rets> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
impl<'a, Args, Rets> Exportable<'a> for NativeFunc<'a, Args, Rets>
|
||||||
impl<'a, Args, Rets> Exportable for NativeFunc<'a, Args, Rets>
|
|
||||||
where
|
where
|
||||||
Args: WasmTypeList,
|
Args: WasmTypeList,
|
||||||
Rets: WasmTypeList,
|
Rets: WasmTypeList,
|
||||||
{
|
{
|
||||||
fn to_export(&self) -> Export {
|
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:
|
// 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_ {
|
match extern_ {
|
||||||
// TODO: review error return type in failure of `f.native()`
|
// 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),
|
_ => 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
|
impl<'a, Args, Rets> From<NativeFunc<'a, Args, Rets>> for Function
|
||||||
where
|
where
|
||||||
Args: WasmTypeList,
|
Args: WasmTypeList,
|
||||||
Rets: 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());
|
let signature = FunctionType::new(Args::wasm_types(), Rets::wasm_types());
|
||||||
Function {
|
Self {
|
||||||
store: other.store,
|
store: other.store,
|
||||||
definition: other.definition,
|
definition: other.definition,
|
||||||
owned_by_store: true, // todo
|
owned_by_store: true, // todo
|
||||||
|
|||||||
@@ -111,10 +111,10 @@ impl Wasi {
|
|||||||
|
|
||||||
let instance = Instance::new(&module, &import_object)?;
|
let instance = Instance::new(&module, &import_object)?;
|
||||||
|
|
||||||
let memory: &Memory = instance.exports.get("memory")?;
|
let memory: Memory = instance.exports.get("memory")?;
|
||||||
wasi_env.set_memory(memory);
|
wasi_env.set_memory(&memory);
|
||||||
|
|
||||||
let start: &Function = instance.exports.get("_start")?;
|
let start: Function = instance.exports.get("_start")?;
|
||||||
|
|
||||||
start
|
start
|
||||||
.call(&[])
|
.call(&[])
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ impl Wast {
|
|||||||
args: &[Val],
|
args: &[Val],
|
||||||
) -> Result<Vec<Val>> {
|
) -> Result<Vec<Val>> {
|
||||||
let instance = self.get_instance(instance_name.as_ref().map(|x| &**x))?;
|
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) {
|
match func.call(args) {
|
||||||
Ok(result) => Ok(result.into()),
|
Ok(result) => Ok(result.into()),
|
||||||
Err(e) => Err(e.into()),
|
Err(e) => Err(e.into()),
|
||||||
@@ -351,7 +351,7 @@ impl Wast {
|
|||||||
/// Get the value of an exported global from an instance.
|
/// Get the value of an exported global from an instance.
|
||||||
fn get(&mut self, instance_name: Option<&str>, field: &str) -> Result<Vec<Val>> {
|
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 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()])
|
Ok(vec![global.get()])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user