Skip to content

Commit

Permalink
write macro for ffi-safe bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
iFrostizz committed Apr 26, 2024
1 parent 0412593 commit 960bb98
Showing 1 changed file with 58 additions and 37 deletions.
95 changes: 58 additions & 37 deletions x/programs/rust/wasmlanche-sdk/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,19 +117,57 @@ impl Key {
}
}

macro_rules! ffi_linker {
($mod:literal, $link:literal, $caller:ident, $key:ident) => {
#[link(wasm_import_module = $mod)]
extern "C" {
#[link_name = $link]
fn ffi(caller: i64, key: i64) -> i64;
}

let $caller = to_host_ptr($caller.id())?;
let $key = to_host_ptr($key)?;
};
($mod:literal, $link:literal, $caller:ident, $key:ident, $value:ident) => {
#[link(wasm_import_module = $mod)]
extern "C" {
#[link_name = $link]
fn ffi(caller: i64, key: i64, value: i64) -> i64;
}

let $caller = to_host_ptr($caller.id())?;
let $key = to_host_ptr($key)?;
let value_bytes = borsh::to_vec($value).map_err(|_| Error::Serialization)?;
let $value = to_host_ptr(&value_bytes)?;
};
}

macro_rules! call_host_fn {
(
wasm_import_module = $mod:literal
link_name = $link:literal
args = ($($arg:ident),+)
) => {
todo!()
};
args = ($caller:ident, $key:ident)
) => {{
ffi_linker!($mod, $link, $caller, $key);

unsafe { ffi($caller, $key) }
}};

(
wasm_import_module = $mod:literal
args = ($($arg:ident),+)
) => {
link_name = $link:literal
args = ($caller:ident, $key:ident, $value:ident)
) => {{
ffi_linker!($mod, $link, $caller, $key, $value);

unsafe { ffi($caller, $key, $value) }
}};

($mod:literal, ($caller:ident, $key:ident)) => {
todo!()
};

($mod:literal, ($caller:ident, $key:ident, $value:ident)) => {
todo!()
};
}
Expand All @@ -138,54 +176,37 @@ mod host {
use super::{BorshSerialize, Key, Program};
use crate::{memory::to_host_ptr, state::Error};

#[link(wasm_import_module = "state")]
extern "C" {
#[link_name = "put"]
fn _put(caller: i64, key: i64, value: i64) -> i64;

#[link_name = "get"]
fn _get(caller: i64, key: i64) -> i64;

#[link_name = "delete"]
fn _delete(caller: i64, key: i64) -> i64;
}

/// Persists the bytes at `value` at key on the host storage.
pub(super) unsafe fn put_bytes<V>(caller: &Program, key: &Key, value: &V) -> Result<(), Error>
where
V: BorshSerialize,
{
// let value_bytes = borsh::to_vec(value).map_err(|_| Error::Serialization)?;
// // prepend length to both key & value
// let caller = to_host_ptr(caller.id())?;
// let value = to_host_ptr(&value_bytes)?;
// let key = to_host_ptr(key)?;

// match unsafe { _put(caller, key, value) } {
// 0 => Ok(()),
// _ => Err(Error::Write),
// }

call_host_fn! {
match call_host_fn! {
wasm_import_module = "state"
link_name = "put"
args = (caller, key, value)
} {
0 => Ok(()),
_ => Err(Error::Write),
}
}

/// Gets the bytes associated with the key from the host.
pub(super) unsafe fn get_bytes(caller: &Program, key: &Key) -> Result<i64, Error> {
// prepend length to key
let caller = to_host_ptr(caller.id())?;
let key = to_host_ptr(key)?;
Ok(unsafe { _get(caller, key) })
Ok(call_host_fn! {
wasm_import_module = "state"
link_name = "get"
args = (caller, key)
})
}

/// Deletes the bytes at key ptr from the host storage
pub(super) unsafe fn delete_bytes(caller: &Program, key: &Key) -> Result<(), Error> {
let caller = to_host_ptr(caller.id())?;
let key = to_host_ptr(key)?;
match unsafe { _delete(caller, key) } {
match call_host_fn! {
wasm_import_module = "state"
link_name = "delete"
args = (caller, key)
} {
0 => Ok(()),
_ => Err(Error::Delete),
}
Expand Down

0 comments on commit 960bb98

Please sign in to comment.