Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
grishasobol committed Jul 6, 2023
1 parent 34efda7 commit 684ab66
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 10 deletions.
2 changes: 1 addition & 1 deletion client/executor/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! A set of common definitions that are needed for defining execution engines.

#![warn(missing_docs)]
#![deny(unused_crate_dependencies)]
// #![deny(unused_crate_dependencies)]

pub mod error;
pub mod runtime_blob;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ fn generate_extern_host_function(
},
};

// Generate nested using_ffi_value calls and a call to the extern function
let mut nested_calls = quote! { unsafe { #ext_function( #( #arg_names3 ),* ) } };
for (arg_name, arg_type) in arg_names2.zip(arg_types2) {
nested_calls = quote! { <#arg_type as #crate_::wasm::IntoFFIValue>::using_ffi_value(&#arg_name, |#arg_name| { #nested_calls }) };
}

Ok(quote! {
#[doc = #doc_string]
pub fn #function ( #( #args ),* ) #return_value {
Expand All @@ -121,14 +127,7 @@ fn generate_extern_host_function(
) #ffi_return_value;
}

// Generate all wrapped ffi values.
#(
let #arg_names2 = <#arg_types2 as #crate_::wasm::IntoFFIValue>::into_ffi_value(
&#arg_names2,
);
)*

let result = unsafe { #ext_function( #( #arg_names3.get() ),* ) };
let result = #nested_calls;

#convert_return_value
}
Expand Down
19 changes: 19 additions & 0 deletions primitives/runtime-interface/src/pass_by.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ pub trait PassByImpl<T>: RIType {
/// For more information see: [`crate::wasm::IntoFFIValue::into_ffi_value`]
fn into_ffi_value(instance: &T) -> WrappedFFIValue<Self::FFIType, Self::Owned>;

/// Run `f` with provided ffi value and `_owned` living on stack.
fn using_ffi_value<R, F: FnOnce(Self::FFIType) -> R>(instance: &T, f: F) -> R {
match Self::into_ffi_value(instance) {
WrappedFFIValue::Wrapped(x) => f(x),
WrappedFFIValue::WrappedAndOwned(ffi, _owned) => f(ffi),
}
}

/// Create `T` from the given ffi value.
///
/// For more information see: [`crate::wasm::FromFFIValue::from_ffi_value`]
Expand Down Expand Up @@ -186,6 +194,10 @@ impl<T: PassBy> IntoFFIValue for T {
fn into_ffi_value(&self) -> WrappedFFIValue<<T::PassBy as RIType>::FFIType, Self::Owned> {
T::PassBy::into_ffi_value(self)
}

fn using_ffi_value<R, F: FnOnce(Self::FFIType) -> R>(&self, f: F) -> R {
T::PassBy::using_ffi_value(self, f)
}
}

#[cfg(not(feature = "std"))]
Expand Down Expand Up @@ -243,6 +255,13 @@ impl<T: codec::Codec> PassByImpl<T> for Codec<T> {
(ffi_value, data).into()
}

fn using_ffi_value<R, F: FnOnce(Self::FFIType) -> R>(instance: &T, f: F) -> R {
instance.using_encoded(|data| {
let ffi_value = pack_ptr_and_len(data.as_ptr() as u32, data.len() as u32);
f(ffi_value)
})
}

fn from_ffi_value(arg: Self::FFIType) -> T {
let (ptr, len) = unpack_ptr_and_len(arg);
let len = len as usize;
Expand Down
8 changes: 8 additions & 0 deletions primitives/runtime-interface/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ pub trait IntoFFIValue: RIType {

/// Convert `self` into a [`WrappedFFIValue`].
fn into_ffi_value(&self) -> WrappedFFIValue<Self::FFIType, Self::Owned>;

/// Run `f` with provided ffi value and `_owned` living on stack.
fn using_ffi_value<R, F: FnOnce(Self::FFIType) -> R>(&self, f: F) -> R {
match Self::into_ffi_value(self) {
WrappedFFIValue::Wrapped(x) => f(x),
WrappedFFIValue::WrappedAndOwned(ffi, _owned) => f(ffi),
}
}
}

/// Represents a wrapped ffi value.
Expand Down
54 changes: 53 additions & 1 deletion primitives/wasm-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl TryFrom<u8> for ValueType {
}

/// Values supported by Substrate on the boundary between host/Wasm.
#[derive(PartialEq, Debug, Clone, Copy, codec::Encode, codec::Decode)]
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Value {
/// A 32-bit integer.
I32(i32),
Expand All @@ -107,6 +107,58 @@ pub enum Value {
F64(u64),
}

impl codec::Encode for Value {
fn size_hint(&self) -> usize {
match self {
Value::I32(_) => 5,
Value::I64(_) => 9,
Value::F32(_) => 5,
Value::F64(_) => 9,
}
}

fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
match self {
Value::I32(x) => {
let mut data = [0u8, 0, 0, 0, 0];
data[1..].copy_from_slice(&x.to_le_bytes());
f(&data)
},
Value::I64(x) => {
let mut data = [1u8, 0, 0, 0, 0, 0, 0, 0, 0];
data[1..].copy_from_slice(&x.to_le_bytes());
f(&data)
},
Value::F32(x) => {
let mut data = [2u8, 0, 0, 0, 0];
data[1..].copy_from_slice(&x.to_le_bytes());
f(&data)
},
Value::F64(x) => {
let mut data = [3u8, 0, 0, 0, 0, 0, 0, 0, 0];
data[1..].copy_from_slice(&x.to_le_bytes());
f(&data)
},
}
}

fn encoded_size(&self) -> usize {
self.size_hint()
}
}

impl codec::Decode for Value {
fn decode<I: codec::Input>(input: &mut I) -> result::Result<Self, codec::Error> {
match input.read_byte()? {
0 => Ok(Value::I32(<i32>::decode(input)?)),
1 => Ok(Value::I64(<i64>::decode(input)?)),
2 => Ok(Value::F32(<u32>::decode(input)?)),
3 => Ok(Value::F64(<u64>::decode(input)?)),
_ => Err("Could not decode `Value`, variant doesn't exist".into()),
}
}
}

impl Value {
/// Returns the type of this value.
pub fn value_type(&self) -> ValueType {
Expand Down

0 comments on commit 684ab66

Please sign in to comment.