Merge remote-tracking branch 'origin/master' into feature/polymorphic-v2

This commit is contained in:
losfair
2020-02-25 00:56:46 +08:00
92 changed files with 2342 additions and 975 deletions

View File

@ -51,6 +51,8 @@ pub struct Wasm {
pub(crate) invoke_env: Option<NonNull<c_void>>,
}
impl Kind for Wasm {}
impl Wasm {
/// Create new `Wasm` from given parts.
pub unsafe fn from_raw_parts(
@ -70,7 +72,6 @@ impl Wasm {
/// by the host.
pub struct Host(());
impl Kind for Wasm {}
impl Kind for Host {}
/// Represents a list of WebAssembly values.
@ -110,14 +111,15 @@ pub trait WasmTypeList {
Rets: WasmTypeList;
}
/// Empty trait to specify the kind of `ExternalFunction`: With or
/// Empty trait to specify the kind of `HostFunction`: With or
/// without a `vm::Ctx` argument. See the `ExplicitVmCtx` and the
/// `ImplicitVmCtx` structures.
///
/// This type is never aimed to be used by a user. It is used by the
/// This trait is never aimed to be used by a user. It is used by the
/// trait system to automatically generate an appropriate `wrap`
/// function.
pub trait ExternalFunctionKind {}
#[doc(hidden)]
pub trait HostFunctionKind {}
/// This empty structure indicates that an external function must
/// contain an explicit `vm::Ctx` argument (at first position).
@ -127,8 +129,11 @@ pub trait ExternalFunctionKind {}
/// x + 1
/// }
/// ```
#[doc(hidden)]
pub struct ExplicitVmCtx {}
impl HostFunctionKind for ExplicitVmCtx {}
/// This empty structure indicates that an external function has no
/// `vm::Ctx` argument (at first position). Its signature is:
///
@ -139,14 +144,13 @@ pub struct ExplicitVmCtx {}
/// ```
pub struct ImplicitVmCtx {}
impl ExternalFunctionKind for ExplicitVmCtx {}
impl ExternalFunctionKind for ImplicitVmCtx {}
impl HostFunctionKind for ImplicitVmCtx {}
/// Represents a function that can be converted to a `vm::Func`
/// (function pointer) that can be called within WebAssembly.
pub trait ExternalFunction<Kind, Args, Rets>
pub trait HostFunction<Kind, Args, Rets>
where
Kind: ExternalFunctionKind,
Kind: HostFunctionKind,
Args: WasmTypeList,
Rets: WasmTypeList,
{
@ -240,8 +244,8 @@ where
/// Creates a new `Func`.
pub fn new<F, Kind>(func: F) -> Self
where
Kind: ExternalFunctionKind,
F: ExternalFunction<Kind, Args, Rets>,
Kind: HostFunctionKind,
F: HostFunction<Kind, Args, Rets>,
{
let (func, func_env) = func.to_raw();
@ -401,6 +405,7 @@ macro_rules! impl_traits {
where
$( $x: WasmExternType ),*;
#[allow(unused_parens)]
impl< $( $x ),* > WasmTypeList for ( $( $x ),* )
where
$( $x: WasmExternType ),*
@ -471,7 +476,8 @@ macro_rules! impl_traits {
}
}
impl< $( $x, )* Rets, Trap, FN > ExternalFunction<ExplicitVmCtx, ( $( $x ),* ), Rets> for FN
#[allow(unused_parens)]
impl< $( $x, )* Rets, Trap, FN > HostFunction<ExplicitVmCtx, ( $( $x ),* ), Rets> for FN
where
$( $x: WasmExternType, )*
Rets: WasmTypeList,
@ -586,7 +592,8 @@ macro_rules! impl_traits {
}
}
impl< $( $x, )* Rets, Trap, FN > ExternalFunction<ImplicitVmCtx, ( $( $x ),* ), Rets> for FN
#[allow(unused_parens)]
impl< $( $x, )* Rets, Trap, FN > HostFunction<ImplicitVmCtx, ( $( $x ),* ), Rets> for FN
where
$( $x: WasmExternType, )*
Rets: WasmTypeList,
@ -698,6 +705,7 @@ macro_rules! impl_traits {
}
}
#[allow(unused_parens)]
impl<'a $( , $x )*, Rets> Func<'a, ( $( $x ),* ), Rets, Wasm>
where
$( $x: WasmExternType, )*

View File

@ -2,7 +2,7 @@
//! convert to other represenations.
use crate::{memory::MemoryType, module::ModuleInfo, structures::TypedIndex, units::Pages};
use std::borrow::Cow;
use std::{borrow::Cow, convert::TryFrom};
/// Represents a WebAssembly type.
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -67,35 +67,32 @@ impl Value {
}
}
impl From<i32> for Value {
fn from(i: i32) -> Self {
Value::I32(i)
}
macro_rules! value_conversions {
($native_type:ty, $value_variant:ident) => {
impl From<$native_type> for Value {
fn from(n: $native_type) -> Self {
Self::$value_variant(n)
}
}
impl TryFrom<&Value> for $native_type {
type Error = &'static str;
fn try_from(value: &Value) -> Result<Self, Self::Error> {
match value {
Value::$value_variant(value) => Ok(*value),
_ => Err("Invalid cast."),
}
}
}
};
}
impl From<i64> for Value {
fn from(i: i64) -> Self {
Value::I64(i)
}
}
impl From<f32> for Value {
fn from(f: f32) -> Self {
Value::F32(f)
}
}
impl From<f64> for Value {
fn from(f: f64) -> Self {
Value::F64(f)
}
}
impl From<u128> for Value {
fn from(v: u128) -> Self {
Value::V128(v)
}
}
value_conversions!(i32, I32);
value_conversions!(i64, I64);
value_conversions!(f32, F32);
value_conversions!(f64, F64);
value_conversions!(u128, V128);
/// Represents a native wasm type.
pub unsafe trait NativeWasmType: Copy + Into<Value>
@ -104,44 +101,57 @@ where
{
/// Type for this `NativeWasmType`.
const TYPE: Type;
/// Convert from u64 bites to self.
fn from_binary(bits: u64) -> Self;
/// Convert self to u64 binary representation.
fn to_binary(self) -> u64;
}
unsafe impl NativeWasmType for i32 {
const TYPE: Type = Type::I32;
fn from_binary(bits: u64) -> Self {
bits as _
}
fn to_binary(self) -> u64 {
self as _
}
}
unsafe impl NativeWasmType for i64 {
const TYPE: Type = Type::I64;
fn from_binary(bits: u64) -> Self {
bits as _
}
fn to_binary(self) -> u64 {
self as _
}
}
unsafe impl NativeWasmType for f32 {
const TYPE: Type = Type::F32;
fn from_binary(bits: u64) -> Self {
f32::from_bits(bits as u32)
}
fn to_binary(self) -> u64 {
self.to_bits() as _
}
}
unsafe impl NativeWasmType for f64 {
const TYPE: Type = Type::F64;
fn from_binary(bits: u64) -> Self {
f64::from_bits(bits)
}
fn to_binary(self) -> u64 {
self.to_bits()
}
@ -154,103 +164,41 @@ where
{
/// Native wasm type for this `WasmExternType`.
type Native: NativeWasmType;
/// Convert from given `Native` type to self.
fn from_native(native: Self::Native) -> Self;
/// Convert self to `Native` type.
fn to_native(self) -> Self::Native;
}
unsafe impl WasmExternType for i8 {
type Native = i32;
fn from_native(native: Self::Native) -> Self {
native as _
}
fn to_native(self) -> Self::Native {
self as _
}
}
unsafe impl WasmExternType for u8 {
type Native = i32;
fn from_native(native: Self::Native) -> Self {
native as _
}
fn to_native(self) -> Self::Native {
self as _
}
}
unsafe impl WasmExternType for i16 {
type Native = i32;
fn from_native(native: Self::Native) -> Self {
native as _
}
fn to_native(self) -> Self::Native {
self as _
}
}
unsafe impl WasmExternType for u16 {
type Native = i32;
fn from_native(native: Self::Native) -> Self {
native as _
}
fn to_native(self) -> Self::Native {
self as _
}
}
unsafe impl WasmExternType for i32 {
type Native = i32;
fn from_native(native: Self::Native) -> Self {
native
}
fn to_native(self) -> Self::Native {
self
}
}
unsafe impl WasmExternType for u32 {
type Native = i32;
fn from_native(native: Self::Native) -> Self {
native as _
}
fn to_native(self) -> Self::Native {
self as _
}
}
unsafe impl WasmExternType for i64 {
type Native = i64;
fn from_native(native: Self::Native) -> Self {
native
}
fn to_native(self) -> Self::Native {
self
}
}
unsafe impl WasmExternType for u64 {
type Native = i64;
fn from_native(native: Self::Native) -> Self {
native as _
}
fn to_native(self) -> Self::Native {
self as _
}
}
unsafe impl WasmExternType for f32 {
type Native = f32;
fn from_native(native: Self::Native) -> Self {
native
}
fn to_native(self) -> Self::Native {
self
}
}
unsafe impl WasmExternType for f64 {
type Native = f64;
fn from_native(native: Self::Native) -> Self {
native
}
fn to_native(self) -> Self::Native {
self
}
macro_rules! wasm_extern_type {
($type:ty => $native_type:ty) => {
unsafe impl WasmExternType for $type {
type Native = $native_type;
fn from_native(native: Self::Native) -> Self {
native as _
}
fn to_native(self) -> Self::Native {
self as _
}
}
};
}
wasm_extern_type!(i8 => i32);
wasm_extern_type!(u8 => i32);
wasm_extern_type!(i16 => i32);
wasm_extern_type!(u16 => i32);
wasm_extern_type!(i32 => i32);
wasm_extern_type!(u32 => i32);
wasm_extern_type!(i64 => i64);
wasm_extern_type!(u64 => i64);
wasm_extern_type!(f32 => f32);
wasm_extern_type!(f64 => f64);
// pub trait IntegerAtomic
// where
// Self: Sized