Skip to content
Permalink
Browse files
fine-tuning the C API (#75)
  • Loading branch information
YaronWittenstein committed Feb 20, 2020
1 parent c8aaa6f commit bcddf22589f33f3045d7c66df9651f5d5d7489f8
Showing 10 changed files with 366 additions and 149 deletions.
@@ -0,0 +1,19 @@
use crate::{impl_from_svm_byte_array, impl_into_svm_byte_array};

use svm_common::Address;

///
/// # Example
///
/// ```rust
/// use svm_common::Address;
/// use svm_runtime_c_api::svm_byte_array;
///
/// let bytes: svm_byte_array = Address:of("@someone").into();
///
/// let addr: Result<Address, String> = bytes.into();
/// assert_eq!(Address::of("@someone"), addr.unwrap());
/// ```
///
impl_from_svm_byte_array!(Address);
impl_into_svm_byte_array!(Address);
@@ -43,9 +43,9 @@ macro_rules! to_svm_byte_array {
($raw_byte_array:expr, $ptr:expr, $length:expr) => {{
use crate::svm_byte_array;

let byte_array: &mut svm_byte_array = &mut *$raw_byte_array;
byte_array.bytes = $ptr;
byte_array.length = $length as u32;
let bytes: &mut svm_byte_array = &mut *$raw_byte_array;
bytes.bytes = $ptr;
bytes.length = $length as u32;
}};
}

@@ -86,14 +86,13 @@ pub unsafe extern "C" fn svm_imports_alloc(imports: *mut *mut c_void, count: u32
/// // ...
/// }
///
/// let count = 1;
/// let mut imports = std::ptr::null_mut();
/// let _res = unsafe { svm_imports_alloc(&mut imports, count) };
/// // allocate one imports
/// let mut imports = testing::imports_alloc(1);
///
/// let module_name = testing::str_to_svm_byte_array("env");
/// let import_name = testing::str_to_svm_byte_array("foo");
/// let params = testing::svm_value_type_vec_to_array(&vec![]);
/// let returns = testing::svm_value_type_vec_to_array(&vec![]);
/// let module_name = "env".into();
/// let import_name = "foo".into();
/// let params = vec![].into();
/// let returns = vec![].into();
/// let func = foo as *const c_void;
///
/// let res = unsafe { svm_import_func_build(imports, module_name, import_name, func, params, returns) };
@@ -115,7 +114,6 @@ pub unsafe extern "C" fn svm_import_func_build(
assert!(imports.len() < imports.capacity());

let func = NonNull::new(func as *mut c_void);

if func.is_none() {
todo!();
// return svm_result_t::SVM_FAILURE;
@@ -162,13 +160,11 @@ pub unsafe extern "C" fn svm_import_func_build(
/// ```rust, no_run
/// use svm_runtime_c_api::{svm_runtime_create, svm_imports_alloc, testing};
///
/// let count = 0;
/// let mut imports = std::ptr::null_mut();
/// let _res = unsafe { svm_imports_alloc(&mut imports, count) };
///
/// let mut runtime = std::ptr::null_mut();
/// let path = testing::str_to_svm_byte_array("path goes here");
/// let path = "path goes here".into();
/// let host = std::ptr::null_mut();
/// let mut imports = testing::imports_alloc(0);
///
/// let res = unsafe { svm_runtime_create(&mut runtime, path, host, imports) };
/// assert!(res.is_ok());
/// ```
@@ -219,9 +215,7 @@ pub unsafe extern "C" fn svm_runtime_create(
/// use svm_common::Address;
///
/// // allocate imports
/// let count = 0;
/// let mut imports = std::ptr::null_mut();
/// let _res = unsafe { svm_imports_alloc(&mut imports, count) };
/// let mut imports = testing::imports_alloc(0);
///
/// // create runtime
/// let mut kv = std::ptr::null_mut();
@@ -232,10 +226,10 @@ pub unsafe extern "C" fn svm_runtime_create(
///
/// // deploy template
/// let mut template_addr = svm_byte_array::default();
/// let author = Address::of("@author");
/// let author: svm_byte_array = Address::of("@author").into();
/// let host_ctx = svm_byte_array::default();
/// let template = svm_byte_array::default();
/// let res = unsafe { svm_deploy_template(&mut template_addr, runtime, author.as_ptr() as _, host_ctx, template) };
/// let template = vec![0x0C, 0x00, 0x0D, 0x0E].into();
/// let res = unsafe { svm_deploy_template(&mut template_addr, runtime, author, host_ctx, template) };
/// assert!(res.is_ok());
/// ```
///
@@ -244,23 +238,29 @@ pub unsafe extern "C" fn svm_runtime_create(
pub unsafe extern "C" fn svm_deploy_template(
template_addr: *mut svm_byte_array,
runtime: *mut c_void,
author: *const c_void,
author: svm_byte_array,
host_ctx: svm_byte_array,
template: svm_byte_array,
) -> svm_result_t {
debug!("`svm_deploy_template` start`");

let runtime = helpers::cast_to_runtime_mut(runtime);
let author = Address::from(author);
let host_ctx = HostCtx::from_raw_parts(host_ctx.bytes, host_ctx.length);
let bytes = std::slice::from_raw_parts(template.bytes, template.length as usize);
let author: Result<Address, String> = author.into();

if let Err(msg) = author {
todo!()
// return svm_result_t::SVM_FAILURE;
}

let host_ctx = HostCtx::from_raw_parts(host_ctx.bytes, host_ctx.length);
if host_ctx.is_err() {
todo!();
// return svm_result_t::SVM_FAILURE;
}

match runtime.deploy_template(&author, host_ctx.unwrap(), bytes) {
let bytes = std::slice::from_raw_parts(template.bytes, template.length as usize);

match runtime.deploy_template(&author.unwrap(), host_ctx.unwrap(), bytes) {
Ok(addr) => {
// returning deployed `AppTemplate` as `svm_byte_array`
// client should call later `svm_address_destroy`
@@ -287,9 +287,7 @@ pub unsafe extern "C" fn svm_deploy_template(
/// use svm_common::Address;
///
/// // allocate imports
/// let count = 0;
/// let mut imports = std::ptr::null_mut();
/// let _res = unsafe { svm_imports_alloc(&mut imports, count) };
/// let mut imports = testing::imports_alloc(0);
///
/// // create runtime
/// let mut kv = std::ptr::null_mut();
@@ -300,12 +298,12 @@ pub unsafe extern "C" fn svm_deploy_template(
///
/// let mut app_addr = svm_byte_array::default();
/// let mut init_state = svm_byte_array::default();
/// let creator = Address::of("@creator");
/// let creator = Address::of("@creator").into();
/// let mut init_state = svm_byte_array::default();
/// let host_ctx = svm_byte_array::default();
/// let app = svm_byte_array::default();
///
/// let _res = unsafe { svm_spawn_app(&mut app_addr, &mut init_state, runtime, creator.as_ptr() as _, host_ctx, app) };
/// let _res = unsafe { svm_spawn_app(&mut app_addr, &mut init_state, runtime, creator, host_ctx, app) };
/// ```
///
#[must_use]
@@ -314,24 +312,29 @@ pub unsafe extern "C" fn svm_spawn_app(
app_addr: *mut svm_byte_array,
init_state: *mut svm_byte_array,
runtime: *mut c_void,
creator: *const c_void,
creator: svm_byte_array,
host_ctx: svm_byte_array,
app: svm_byte_array,
) -> svm_result_t {
debug!("`svm_spawn_app` start");

let runtime = helpers::cast_to_runtime_mut(runtime);
let creator = Address::from(creator);
let host_ctx = HostCtx::from_raw_parts(host_ctx.bytes, host_ctx.length);
let creator: Result<Address, String> = creator.into();

if let Err(msg) = creator {
todo!();
// return svm_result_t::SVM_FAILURE;
}

let host_ctx = HostCtx::from_raw_parts(host_ctx.bytes, host_ctx.length);
if host_ctx.is_err() {
todo!();
// return svm_result_t::SVM_FAILURE;
}

let bytes = std::slice::from_raw_parts(app.bytes, app.length as usize);

match runtime.spawn_app(&creator, host_ctx.unwrap(), bytes) {
match runtime.spawn_app(&creator.unwrap(), host_ctx.unwrap(), bytes) {
Ok((addr, state)) => {
// returning spawned app `Address` as `svm_byte_array`
// client should call later `svm_address_destroy`
@@ -362,9 +365,7 @@ pub unsafe extern "C" fn svm_spawn_app(
/// use svm_common::Address;
///
/// // allocate imports
/// let count = 0;
/// let mut imports = std::ptr::null_mut();
/// let _res = unsafe { svm_imports_alloc(&mut imports, count) };
/// let mut imports = testing::imports_alloc(0);
///
/// // create runtime
/// let mut kv = std::ptr::null_mut();
@@ -374,26 +375,31 @@ pub unsafe extern "C" fn svm_spawn_app(
/// let _res = unsafe { testing::svm_memory_runtime_create(&mut runtime, kv, host, imports) };
///
/// let mut app_tx = std::ptr::null_mut();
/// let sender = Address::of("@sender");
/// let tx = svm_byte_array::default();
/// let _res = unsafe { svm_parse_exec_app(&mut app_tx, runtime, sender.as_ptr() as _, tx) };
/// let sender = Address::of("@sender").into();
/// let tx = vec![0x00, 0x01, 0x2, 0x3].into();
/// let _res = unsafe { svm_parse_exec_app(&mut app_tx, runtime, sender, tx) };
/// ```
///
#[must_use]
#[no_mangle]
pub unsafe extern "C" fn svm_parse_exec_app(
app_tx: *mut *mut c_void,
runtime: *const c_void,
sender: *const c_void,
sender: svm_byte_array,
tx: svm_byte_array,
) -> svm_result_t {
debug!("`svm_parse_exec_app` start");

let runtime = helpers::cast_to_runtime(runtime);
let sender = Address::from(sender);
let sender: Result<Address, String> = sender.into();

if let Err(msg) = sender {
todo!();
}

let bytes = std::slice::from_raw_parts(tx.bytes, tx.length as usize);

match runtime.parse_exec_app(&sender, bytes) {
match runtime.parse_exec_app(&sender.unwrap(), bytes) {
Ok(tx) => {
// `AppTransaction` will be freed later as part `svm_exec_app`
*app_tx = svm_common::into_raw_mut(tx);
@@ -421,9 +427,7 @@ pub unsafe extern "C" fn svm_parse_exec_app(
/// use svm_common::{State, Address};
///
/// // allocate imports
/// let count = 0;
/// let mut imports = std::ptr::null_mut();
/// let _res = unsafe { svm_imports_alloc(&mut imports, count) };
/// let mut imports = testing::imports_alloc(0);
///
/// // create runtime
/// let mut kv = std::ptr::null_mut();
@@ -442,19 +446,19 @@ pub unsafe extern "C" fn svm_parse_exec_app(
/// };
///
/// let app_tx_ptr = &app_tx as *const AppTransaction as *const c_void;
/// let state = State::empty();
/// let state = State::empty().into();
/// let mut receipt = svm_byte_array::default();
/// let host_ctx = svm_byte_array::default();
/// let _res = unsafe { svm_exec_app(&mut receipt, runtime, app_tx_ptr, state.as_ptr() as _, host_ctx) };
/// let _res = unsafe { svm_exec_app(&mut receipt, runtime, app_tx_ptr, state, host_ctx) };
/// ```
///
#[must_use]
#[no_mangle]
pub unsafe extern "C" fn svm_exec_app(
encoded_receipt: *mut svm_byte_array,
receipt: *mut svm_byte_array,
runtime: *mut c_void,
app_tx: *const c_void,
state: *const c_void,
state: svm_byte_array,
host_ctx: svm_byte_array,
) -> svm_result_t {
debug!("`svm_exec_app` start");
@@ -471,15 +475,19 @@ pub unsafe extern "C" fn svm_exec_app(
let host_ctx = host_ctx.unwrap();
let app_tx = *Box::from_raw(app_tx as *mut AppTransaction);
let runtime = helpers::cast_to_runtime_mut(runtime);
let state = State::from(state);
let state: Result<State, String> = state.into();

match runtime.exec_app(app_tx, state, host_ctx) {
Ok(ref receipt) => {
let mut bytes = crate::receipt::encode_receipt(receipt);
if let Err(msg) = state {
todo!();
}

match runtime.exec_app(app_tx, state.unwrap(), host_ctx) {
Ok(ref native_receipt) => {
let mut bytes = crate::receipt::encode_receipt(native_receipt);

// returning encoded `Receipt` as `svm_byte_array`
// should call later `svm_receipt_destroy`
vec_to_svm_byte_array!(encoded_receipt, bytes);
vec_to_svm_byte_array!(receipt, bytes);

debug!("`svm_exec_app` returns `SVM_SUCCESS`");
svm_result_t::SVM_SUCCESS
@@ -513,9 +521,7 @@ pub unsafe extern "C" fn svm_instance_context_host_get(ctx: *mut c_void) -> *mut
/// use svm_common::Address;
///
/// // allocate imports
/// let count = 0;
/// let mut imports = std::ptr::null_mut();
/// let _res = unsafe { svm_imports_alloc(&mut imports, count) };
/// let mut imports = testing::imports_alloc(0);
///
/// // create runtime
/// let mut kv = std::ptr::null_mut();

0 comments on commit bcddf22

Please sign in to comment.