Skip to content

Commit

Permalink
Merge pull request #119 from wasmerio/feat-rename-wasmexterntype
Browse files Browse the repository at this point in the history
 feat(wasm-common) Reimplement `WasmExternType` as `FromToNativeWasmType`
  • Loading branch information
syrusakbary authored Jul 2, 2020
2 parents d40c947 + ea78fe5 commit e400aa8
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 41 deletions.
96 changes: 72 additions & 24 deletions lib/api/src/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::types::Val;
use crate::FunctionType;
use crate::NativeFunc;
use crate::RuntimeError;
pub use inner::{HostFunction, WasmExternType, WasmTypeList, WithEnv, WithoutEnv};
pub use inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, WithoutEnv};
use std::cell::RefCell;
use std::cmp::max;
use wasmer_runtime::{
Expand Down Expand Up @@ -505,43 +505,71 @@ mod inner {
use wasm_common::{FunctionType, NativeWasmType, Type};
use wasmer_runtime::{raise_user_trap, resume_panic, VMFunctionBody};

/// A trait to represent a wasm extern type.
pub unsafe trait WasmExternType: Copy
/// A trait to convert a Rust value to a `WasmNativeType` value,
/// or to convert `WasmNativeType` value to a Rust value.
///
/// This trait should ideally be splitted into two traits:
/// `FromNativeWasmType` and `ToNativeWasmType` but it creates a
/// non-negligeable complexity in the `WasmTypeList`
/// implementation.
pub unsafe trait FromToNativeWasmType: Copy
where
Self: Sized,
{
/// Native wasm type for this `WasmExternType`.
/// Native Wasm type.
type Native: NativeWasmType;

/// Convert from given `Native` type to self.
/// Convert a value of kind `Self::Native` to `Self`.
///
/// # Panics
///
/// This method panics if `native` cannot fit in the `Self`
/// type`.
fn from_native(native: Self::Native) -> Self;

/// Convert self to `Native` type.
/// Convert self to `Self::Native`.
///
/// # Panics
///
/// This method panics if `self` cannot fit in the
/// `Self::Native` type.
fn to_native(self) -> Self::Native;
}

macro_rules! wasm_extern_type {
macro_rules! from_to_native_wasm_type {
( $( $type:ty => $native_type:ty ),* ) => {
$(
#[allow(clippy::use_self)]
unsafe impl WasmExternType for $type {
unsafe impl FromToNativeWasmType for $type {
type Native = $native_type;

#[inline]
fn from_native(native: Self::Native) -> Self {
native as _
native.try_into().expect(concat!(
"out of range type conversion attempt (tried to convert `",
stringify!($native_type),
"` to `",
stringify!($type),
"`)",
))
}

#[inline]
fn to_native(self) -> Self::Native {
self as _
self.try_into().expect(concat!(
"out of range type conversion attempt (tried to convert `",
stringify!($type),
"` to `",
stringify!($native_type),
"`)",
))
}
}
)*
};
}

wasm_extern_type!(
from_to_native_wasm_type!(
i8 => i32,
u8 => i32,
i16 => i32,
Expand All @@ -554,6 +582,26 @@ mod inner {
f64 => f64
);

#[cfg(test)]
mod test_from_to_native_wasm_type {
use super::*;

#[test]
fn test_to_native() {
assert_eq!(7i8.to_native(), 7i32);
}

#[test]
#[should_panic(
expected = "out of range type conversion attempt (tried to convert `u32` to `i32`)"
)]
fn test_to_native_panics() {
use std::{i32, u32};

assert_eq!(u32::MAX.to_native(), i32::MAX);
}
}

/// The `WasmTypeList` trait represents a tuple (list) of Wasm
/// typed values. It is used to get low-level representation of
/// such a tuple.
Expand Down Expand Up @@ -729,9 +777,9 @@ mod inner {
/// A structure with a C-compatible representation that can hold a set of Wasm values.
/// This type is used by `WasmTypeList::CStruct`.
#[repr($c_struct_representation)]
pub struct $c_struct_name< $( $x ),* > ( $( <$x as WasmExternType>::Native ),* )
pub struct $c_struct_name< $( $x ),* > ( $( <$x as FromToNativeWasmType>::Native ),* )
where
$( $x: WasmExternType ),*;
$( $x: FromToNativeWasmType ),*;

// Implement `WasmTypeList` for a specific tuple.
#[allow(unused_parens, dead_code)]
Expand All @@ -740,7 +788,7 @@ mod inner {
for
( $( $x ),* )
where
$( $x: WasmExternType ),*
$( $x: FromToNativeWasmType ),*
{
type CStruct = $c_struct_name< $( $x ),* >;

Expand All @@ -754,7 +802,7 @@ mod inner {
// Build the tuple.
(
$(
WasmExternType::from_native(NativeWasmType::from_binary($x))
FromToNativeWasmType::from_native(NativeWasmType::from_binary($x))
),*
)
}
Expand All @@ -771,7 +819,7 @@ mod inner {
// Build the array.
[
$(
WasmExternType::to_native($x).to_binary()
FromToNativeWasmType::to_native($x).to_binary()
),*
]
}
Expand All @@ -788,7 +836,7 @@ mod inner {

(
$(
WasmExternType::from_native($x)
FromToNativeWasmType::from_native($x)
),*
)
}
Expand All @@ -801,7 +849,7 @@ mod inner {
// Build the C structure.
$c_struct_name(
$(
WasmExternType::to_native($x)
FromToNativeWasmType::to_native($x)
),*
)
}
Expand All @@ -823,7 +871,7 @@ mod inner {
for
Func
where
$( $x: WasmExternType, )*
$( $x: FromToNativeWasmType, )*
Rets: WasmTypeList,
RetsAsResult: IntoResult<Rets>,
Func: Fn($( $x , )*) -> RetsAsResult + 'static + Send,
Expand All @@ -835,14 +883,14 @@ mod inner {
/// runtime.
extern fn func_wrapper<$( $x, )* Rets, RetsAsResult, Func>( _: usize, $($x: $x::Native, )* ) -> Rets::CStruct
where
$( $x: WasmExternType, )*
$( $x: FromToNativeWasmType, )*
Rets: WasmTypeList,
RetsAsResult: IntoResult<Rets>,
Func: Fn( $( $x ),* ) -> RetsAsResult + 'static
{
let func: &Func = unsafe { &*(&() as *const () as *const Func) };
let result = panic::catch_unwind(AssertUnwindSafe(|| {
func( $( WasmExternType::from_native($x) ),* ).into_result()
func( $( FromToNativeWasmType::from_native($x) ),* ).into_result()
}));

match result {
Expand All @@ -862,7 +910,7 @@ mod inner {
for
Func
where
$( $x: WasmExternType, )*
$( $x: FromToNativeWasmType, )*
Rets: WasmTypeList,
RetsAsResult: IntoResult<Rets>,
Env: Sized,
Expand All @@ -875,7 +923,7 @@ mod inner {
/// runtime.
extern fn func_wrapper<$( $x, )* Rets, RetsAsResult, Env, Func>( env: &mut Env, $( $x: $x::Native, )* ) -> Rets::CStruct
where
$( $x: WasmExternType, )*
$( $x: FromToNativeWasmType, )*
Rets: WasmTypeList,
RetsAsResult: IntoResult<Rets>,
Env: Sized,
Expand All @@ -884,7 +932,7 @@ mod inner {
let func: &Func = unsafe { &*(&() as *const () as *const Func) };

let result = panic::catch_unwind(AssertUnwindSafe(|| {
func(env, $( WasmExternType::from_native($x) ),* ).into_result()
func(env, $( FromToNativeWasmType::from_native($x) ),* ).into_result()
}));

match result {
Expand Down
2 changes: 1 addition & 1 deletion lib/api/src/externals/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod memory;
mod table;

pub use self::function::{
Function, HostFunction, WasmExternType, WasmTypeList, WithEnv, WithoutEnv,
FromToNativeWasmType, Function, HostFunction, WasmTypeList, WithEnv, WithoutEnv,
};
pub use self::global::Global;
pub use self::memory::Memory;
Expand Down
2 changes: 1 addition & 1 deletion lib/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub mod internals {

pub use crate::exports::{ExportError, Exportable, Exports, ExportsIterator};
pub use crate::externals::{
Extern, Function, Global, HostFunction, Memory, Table, WasmExternType, WasmTypeList,
Extern, FromToNativeWasmType, Function, Global, HostFunction, Memory, Table, WasmTypeList,
};
pub use crate::import_object::{ImportObject, ImportObjectIterator, LikeNamespace};
pub use crate::instance::Instance;
Expand Down
4 changes: 2 additions & 2 deletions lib/api/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::externals::function::{
FunctionDefinition, HostFunctionDefinition, VMDynamicFunction, VMDynamicFunctionWithEnv,
VMDynamicFunctionWithoutEnv, WasmFunctionDefinition,
};
use crate::{Function, FunctionType, RuntimeError, Store, WasmExternType, WasmTypeList};
use crate::{FromToNativeWasmType, Function, FunctionType, RuntimeError, Store, WasmTypeList};
use std::panic::{catch_unwind, AssertUnwindSafe};
use wasm_common::NativeWasmType;
use wasmer_runtime::{
Expand Down Expand Up @@ -97,7 +97,7 @@ macro_rules! impl_native_traits {
#[allow(unused_parens, non_snake_case)]
impl<'a $( , $x )*, Rets> NativeFunc<'a, ( $( $x ),* ), Rets>
where
$( $x: WasmExternType, )*
$( $x: FromToNativeWasmType, )*
Rets: WasmTypeList,
{
/// Call the typed func and return results.
Expand Down
4 changes: 2 additions & 2 deletions lib/api/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//! Therefore, you should use this abstraction whenever possible to avoid memory
//! related bugs when implementing an ABI.
use crate::{externals::Memory, WasmExternType};
use crate::{externals::Memory, FromToNativeWasmType};
use std::{cell::Cell, fmt, marker::PhantomData, mem};
use wasm_common::ValueType;

Expand Down Expand Up @@ -218,7 +218,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
}
}

unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
unsafe impl<T: Copy, Ty> FromToNativeWasmType for WasmPtr<T, Ty> {
type Native = i32;

fn to_native(self) -> Self::Native {
Expand Down
6 changes: 3 additions & 3 deletions lib/emscripten/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![allow(dead_code)]

use std::{cell::Cell, fmt};
pub use wasmer::{Array, Memory, ValueType, WasmExternType};
pub use wasmer::{Array, FromToNativeWasmType, Memory, ValueType};

#[repr(transparent)]
pub struct WasmPtr<T: Copy, Ty = wasmer::Item>(wasmer::WasmPtr<T, Ty>);
Expand All @@ -26,8 +26,8 @@ impl<T: Copy, Ty> fmt::Debug for WasmPtr<T, Ty> {
}
}

unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
type Native = <wasmer::WasmPtr<T, Ty> as WasmExternType>::Native;
unsafe impl<T: Copy, Ty> FromToNativeWasmType for WasmPtr<T, Ty> {
type Native = <wasmer::WasmPtr<T, Ty> as FromToNativeWasmType>::Native;

fn to_native(self) -> Self::Native {
self.0.to_native()
Expand Down
4 changes: 2 additions & 2 deletions lib/emscripten/src/varargs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::EmEnv;
use std::mem;
use wasmer::WasmExternType;
use wasmer::FromToNativeWasmType;
// use std::ffi::CStr;
use std::os::raw::c_char;

Expand All @@ -26,7 +26,7 @@ impl VarArgs {
}
}

unsafe impl WasmExternType for VarArgs {
unsafe impl FromToNativeWasmType for VarArgs {
type Native = i32;

fn to_native(self) -> Self::Native {
Expand Down
6 changes: 3 additions & 3 deletions lib/wasi/src/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::syscalls::types::{__wasi_errno_t, __WASI_EFAULT};
use std::{cell::Cell, fmt};
pub use wasmer::{Array, Item, Memory, ValueType, WasmExternType, WasmPtr as BaseWasmPtr};
pub use wasmer::{Array, FromToNativeWasmType, Item, Memory, ValueType, WasmPtr as BaseWasmPtr};

#[repr(transparent)]
pub struct WasmPtr<T: Copy, Ty = Item>(BaseWasmPtr<T, Ty>);
Expand All @@ -24,8 +24,8 @@ impl<T: Copy, Ty> fmt::Debug for WasmPtr<T, Ty> {
}
}

unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
type Native = <BaseWasmPtr<T, Ty> as WasmExternType>::Native;
unsafe impl<T: Copy, Ty> FromToNativeWasmType for WasmPtr<T, Ty> {
type Native = <BaseWasmPtr<T, Ty> as FromToNativeWasmType>::Native;

fn to_native(self) -> Self::Native {
self.0.to_native()
Expand Down
Loading

0 comments on commit e400aa8

Please sign in to comment.