Skip to content

Commit

Permalink
simplify the logic by using owned results
Browse files Browse the repository at this point in the history
  • Loading branch information
cpetig committed Aug 1, 2024
1 parent df019cf commit a2d05a7
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 109 deletions.
8 changes: 3 additions & 5 deletions crates/cpp/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,9 @@ For now for functions the following convention is used in both directions:
- (unchanged) If there are too many (>1) flat results, a local
uninitialized ret_area is passed via the last argument

- (change) Returned strings and lists become views, valid until a
cabi_post on the ret_area ptr which was passed to the first call.
This is mostly a concession to functional safety, avoiding all
allocations in the hot path. Caller provided buffers or custom realloc
would solve this in a different way.
- (unchanged) Returned objects are owned.
For functional safety, i.e. avoiding all
allocations in the hot path, the hope is with #385.

- The imported resource ABI is used also for exporting
with one modification:
Expand Down
32 changes: 2 additions & 30 deletions crates/cpp/tests/meshless_strings/component_a/the_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,9 @@ fooX3AfooX2FstringsX00a(uint8_t *, size_t);
extern "C" __attribute__((import_module("foo:foo/strings")))
__attribute__((import_name("b"))) void
fooX3AfooX2FstringsX00b(uint8_t *);
extern "C" __attribute__((import_module("cabi_post_foo:foo/strings")))
__attribute__((import_name("b"))) void
cabi_post_fooX3AfooX2FstringsX00b(uint8_t *);
extern "C" __attribute__((import_module("foo:foo/strings")))
__attribute__((import_name("c"))) void
fooX3AfooX2FstringsX00c(uint8_t *, size_t, uint8_t *, size_t, uint8_t *);
extern "C" __attribute__((import_module("cabi_post_foo:foo/strings")))
__attribute__((import_name("c"))) void
cabi_post_fooX3AfooX2FstringsX00c(uint8_t *);
void comp_a::foo::foo::strings::A(std::string_view x) {
auto const &vec0 = x;
auto ptr0 = (uint8_t *)(vec0.data());
Expand All @@ -53,10 +47,7 @@ wit::string comp_a::foo::foo::strings::B() {
fooX3AfooX2FstringsX00b(ptr0);
auto len1 = *((size_t *)(ptr0 + sizeof(void *)));

auto string1 = wit::string::from_view(
std::string_view((char const *)(*((uint8_t **)(ptr0 + 0))), len1));

cabi_post_fooX3AfooX2FstringsX00b(ptr0);
auto string1 = wit::string((char const *)(*((uint8_t **)(ptr0 + 0))), len1);
return string1;
}
wit::string comp_a::foo::foo::strings::C(std::string_view a,
Expand All @@ -73,10 +64,7 @@ wit::string comp_a::foo::foo::strings::C(std::string_view a,
fooX3AfooX2FstringsX00c(ptr0, len0, ptr1, len1, ptr2);
auto len3 = *((size_t *)(ptr2 + sizeof(void *)));

auto string3 = wit::string::from_view(
std::string_view((char const *)(*((uint8_t **)(ptr2 + 0))), len3));

cabi_post_fooX3AfooX2FstringsX00c(ptr2);
auto string3 = wit::string((char const *)(*((uint8_t **)(ptr2 + 0))), len3);
return string3;
}
extern "C" __attribute__((__export_name__("foo:foo/strings#a"))) void
Expand All @@ -99,14 +87,6 @@ a_fooX3AfooX2FstringsX00b(uint8_t *arg0) {
*((size_t *)(arg0 + sizeof(void *))) = len1;
*((uint8_t **)(arg0 + 0)) = ptr1;
}
extern "C"
__attribute__((__weak__,
__export_name__("cabi_post_fooX3AfooX2FstringsX00b"))) void
a_cabi_post_fooX3AfooX2FstringsX00b(uint8_t *retptr) {
if ((*((size_t *)(retptr + sizeof(void *)))) > 0) {
wit::string::drop_raw((void *)(*((uint8_t **)(retptr + 0))));
}
}
extern "C" __attribute__((__export_name__("foo:foo/strings#c"))) void
a_fooX3AfooX2FstringsX00c(uint8_t *arg0, size_t arg1, uint8_t *arg2, size_t arg3,
uint8_t *arg4) {
Expand All @@ -130,13 +110,5 @@ a_fooX3AfooX2FstringsX00c(uint8_t *arg0, size_t arg1, uint8_t *arg2, size_t arg3
*((size_t *)(arg4 + sizeof(void *))) = len3;
*((uint8_t **)(arg4 + 0)) = ptr3;
}
extern "C"
__attribute__((__weak__,
__export_name__("cabi_post_fooX3AfooX2FstringsX00c"))) void
a_cabi_post_fooX3AfooX2FstringsX00c(uint8_t *retptr) {
if ((*((size_t *)(retptr + sizeof(void *)))) > 0) {
wit::string::drop_raw((void *)(*((uint8_t **)(retptr + 0))));
}
}

// Component Adapters
32 changes: 2 additions & 30 deletions crates/cpp/tests/meshless_strings/component_b/the_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,9 @@ a_fooX3AfooX2FstringsX00a(uint8_t *, size_t);
extern "C" __attribute__((import_module("foo:foo/strings")))
__attribute__((import_name("b"))) void
a_fooX3AfooX2FstringsX00b(uint8_t *);
extern "C" __attribute__((import_module("cabi_post_foo:foo/strings")))
__attribute__((import_name("b"))) void
a_cabi_post_fooX3AfooX2FstringsX00b(uint8_t *);
extern "C" __attribute__((import_module("foo:foo/strings")))
__attribute__((import_name("c"))) void
a_fooX3AfooX2FstringsX00c(uint8_t *, size_t, uint8_t *, size_t, uint8_t *);
extern "C" __attribute__((import_module("cabi_post_foo:foo/strings")))
__attribute__((import_name("c"))) void
a_cabi_post_fooX3AfooX2FstringsX00c(uint8_t *);
void foo::foo::strings::A(std::string_view x) {
auto const &vec0 = x;
auto ptr0 = (uint8_t *)(vec0.data());
Expand All @@ -53,10 +47,7 @@ wit::string foo::foo::strings::B() {
a_fooX3AfooX2FstringsX00b(ptr0);
auto len1 = *((size_t *)(ptr0 + sizeof(void *)));

auto string1 = wit::string::from_view(
std::string_view((char const *)(*((uint8_t **)(ptr0 + 0))), len1));

a_cabi_post_fooX3AfooX2FstringsX00b(ptr0);
auto string1 = wit::string((char const *)(*((uint8_t **)(ptr0 + 0))), len1);
return string1;
}
wit::string foo::foo::strings::C(std::string_view a, std::string_view b) {
Expand All @@ -72,10 +63,7 @@ wit::string foo::foo::strings::C(std::string_view a, std::string_view b) {
a_fooX3AfooX2FstringsX00c(ptr0, len0, ptr1, len1, ptr2);
auto len3 = *((size_t *)(ptr2 + sizeof(void *)));

auto string3 = wit::string::from_view(
std::string_view((char const *)(*((uint8_t **)(ptr2 + 0))), len3));

a_cabi_post_fooX3AfooX2FstringsX00c(ptr2);
auto string3 = wit::string((char const *)(*((uint8_t **)(ptr2 + 0))), len3);
return string3;
}
extern "C" __attribute__((__export_name__("foo:foo/strings#a"))) void
Expand All @@ -98,14 +86,6 @@ fooX3AfooX2FstringsX00b(uint8_t *arg0) {
*((size_t *)(arg0 + sizeof(void *))) = len1;
*((uint8_t **)(arg0 + 0)) = ptr1;
}
extern "C"
__attribute__((__weak__,
__export_name__("cabi_post_fooX3AfooX2FstringsX00b"))) void
cabi_post_fooX3AfooX2FstringsX00b(uint8_t *retptr) {
if ((*((size_t *)(retptr + sizeof(void *)))) > 0) {
wit::string::drop_raw((void *)(*((uint8_t **)(retptr + 0))));
}
}
extern "C" __attribute__((__export_name__("foo:foo/strings#c"))) void
fooX3AfooX2FstringsX00c(uint8_t *arg0, size_t arg1, uint8_t *arg2, size_t arg3,
uint8_t *arg4) {
Expand All @@ -129,13 +109,5 @@ fooX3AfooX2FstringsX00c(uint8_t *arg0, size_t arg1, uint8_t *arg2, size_t arg3,
*((size_t *)(arg4 + sizeof(void *))) = len3;
*((uint8_t **)(arg4 + 0)) = ptr3;
}
extern "C"
__attribute__((__weak__,
__export_name__("cabi_post_fooX3AfooX2FstringsX00c"))) void
cabi_post_fooX3AfooX2FstringsX00c(uint8_t *retptr) {
if ((*((size_t *)(retptr + sizeof(void *)))) > 0) {
wit::string::drop_raw((void *)(*((uint8_t **)(retptr + 0))));
}
}

// Component Adapters
55 changes: 11 additions & 44 deletions crates/cpp/tests/meshless_strings/rust_comp_a/src/the_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,8 @@ pub mod foo {
let l1 = *ptr0.add(0).cast::<*mut u8>();
let l2 = *ptr0.add(core::mem::size_of::<*const u8>()).cast::<usize>();
let len3 = l2;
let string3 = String::from(
std::str::from_utf8(std::slice::from_raw_parts(l1, len3)).unwrap(),
);

#[link(wasm_import_module = "cabi_post_foo:foo/strings")]
extern "C" {
#[cfg_attr(target_arch = "wasm32", link_name = "b")]
fn cabi_post_fooX3AfooX2FstringsX00b(_: *mut u8);
}
cabi_post_fooX3AfooX2FstringsX00b(ptr0);
let bytes3 = _rt::Vec::from_raw_parts(l1.cast(), len3, len3);
let string3 = _rt::string_lift(bytes3);
string3
}
}
Expand Down Expand Up @@ -96,16 +88,8 @@ pub mod foo {
let l3 = *ptr2.add(0).cast::<*mut u8>();
let l4 = *ptr2.add(core::mem::size_of::<*const u8>()).cast::<usize>();
let len5 = l4;
let string5 = String::from(
std::str::from_utf8(std::slice::from_raw_parts(l3, len5)).unwrap(),
);

#[link(wasm_import_module = "cabi_post_foo:foo/strings")]
extern "C" {
#[cfg_attr(target_arch = "wasm32", link_name = "c")]
fn cabi_post_fooX3AfooX2FstringsX00c(_: *mut u8);
}
cabi_post_fooX3AfooX2FstringsX00c(ptr2);
let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5);
let string5 = _rt::string_lift(bytes5);
string5
}
}
Expand Down Expand Up @@ -152,13 +136,6 @@ pub mod exports {
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub unsafe fn __post_return_b<T: Guest>(arg0: *mut u8) {
let l0 = *arg0.add(0).cast::<*mut u8>();
let l1 = *arg0.add(core::mem::size_of::<*const u8>()).cast::<usize>();
_rt::cabi_dealloc(l0, l1, 1);
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub unsafe fn _export_c_cabi<T: Guest>(
arg0: *mut u8,
arg1: usize,
Expand All @@ -184,13 +161,6 @@ pub mod exports {
*arg4.add(core::mem::size_of::<*const u8>()).cast::<usize>() = len3;
*arg4.add(0).cast::<*mut u8>() = ptr3.cast_mut();
}
#[doc(hidden)]
#[allow(non_snake_case)]
pub unsafe fn __post_return_c<T: Guest>(arg0: *mut u8) {
let l0 = *arg0.add(0).cast::<*mut u8>();
let l1 = *arg0.add(core::mem::size_of::<*const u8>()).cast::<usize>();
_rt::cabi_dealloc(l0, l1, 1);
}
pub trait Guest {
fn a(x: _rt::String) -> ();
fn b() -> _rt::String;
Expand All @@ -211,21 +181,11 @@ pub mod exports {
unsafe extern "C" fn a_fooX3AfooX2FstringsX00b(ptr: *mut u8) {
$($path_to_types)*::_export_b_cabi::<$ty>(ptr)
}
#[cfg_attr(target_arch = "wasm32", export_name = "cabi_post_foo:foo/strings#b")]
#[cfg_attr(not(target_arch = "wasm32"), no_mangle)]
unsafe extern "C" fn a_cabi_post_fooX3AfooX2FstringsX00b(arg0: *mut u8,) {
$($path_to_types)*::__post_return_b::<$ty>(arg0)
}
#[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#c")]
#[cfg_attr(not(target_arch = "wasm32"), no_mangle)]
unsafe extern "C" fn a_fooX3AfooX2FstringsX00c(arg0: *mut u8,arg1: usize,arg2: *mut u8,arg3: usize, arg4: *mut u8) {
$($path_to_types)*::_export_c_cabi::<$ty>(arg0, arg1, arg2, arg3, arg4)
}
#[cfg_attr(target_arch = "wasm32", export_name = "cabi_post_foo:foo/strings#c")]
#[cfg_attr(not(target_arch = "wasm32"), no_mangle)]
unsafe extern "C" fn a_cabi_post_fooX3AfooX2FstringsX00c(arg0: *mut u8,) {
$($path_to_types)*::__post_return_c::<$ty>(arg0)
}
};);
}
#[doc(hidden)]
Expand All @@ -237,6 +197,13 @@ pub mod exports {
mod _rt {
pub use alloc_crate::string::String;
pub use alloc_crate::vec::Vec;
pub unsafe fn string_lift(bytes: Vec<u8>) -> String {
if cfg!(debug_assertions) {
String::from_utf8(bytes).unwrap()
} else {
String::from_utf8_unchecked(bytes)
}
}

#[cfg(target_arch = "wasm32")]
pub fn run_ctors_once() {
Expand Down

0 comments on commit a2d05a7

Please sign in to comment.