From 95cda46a5898c0c2a13813c1dcaced7d6e68d6c6 Mon Sep 17 00:00:00 2001 From: 0vygvn Date: Thu, 23 May 2024 10:05:03 +0530 Subject: [PATCH 1/8] separate guest import and export code Signed-off-by: Pradeep Kumar K J --- crates/cpp/tests/native_strings/Makefile | 12 +- .../{guest.cpp => guest_exports.cpp} | 9 +- .../tests/native_strings/guest_imports.cpp | 20 + crates/cpp/tests/native_strings/main.cpp | 13 - .../cpp/tests/native_strings/rust/src/lib.rs | 2 + .../native_strings/rust/src/the_world.rs | 364 +++++++++--------- crates/cpp/tests/native_strings/the_world.cpp | 2 +- .../tests/native_strings/the_world_native.cpp | 3 +- 8 files changed, 228 insertions(+), 197 deletions(-) rename crates/cpp/tests/native_strings/{guest.cpp => guest_exports.cpp} (67%) create mode 100644 crates/cpp/tests/native_strings/guest_imports.cpp diff --git a/crates/cpp/tests/native_strings/Makefile b/crates/cpp/tests/native_strings/Makefile index 54cdcdf09..0be82d7aa 100644 --- a/crates/cpp/tests/native_strings/Makefile +++ b/crates/cpp/tests/native_strings/Makefile @@ -1,26 +1,26 @@ -CXXFLAGS=-g -O0 -I../../helper-types +CXXFLAGS=-g -O0 -I../../helper-types --std=c++17 WIT_BINDGEN=../../../../target/debug/wit-bindgen all: libstrings.so app-strings -libstrings.so: the_world.pie.o guest.pie.o +libstrings.so: the_world.pie.o guest_exports.pie.o $(CXX) $(CXXFLAGS) -shared -o $@ $^ -Wl,--version-script=guest.lds %.pie.o: %.cpp $(CXX) $(CXXFLAGS) -fPIE -o $@ -c $^ -app-strings: the_world_native.o main.o - $(CXX) $(CXXFLAGS) -o $@ $^ -L. -lstrings +app-strings: the_world_native.o main.o guest_imports.o + $(CXX) $(CXXFLAGS) -o $@ $^ -g -L. -lstrings bindgen: wit/strings.wit $(WIT_BINDGEN) cpp wit --wasm64 --format $(WIT_BINDGEN) cpp wit --wasm64 --format --direct cd rust/src ; ../../$(WIT_BINDGEN) rust ../../wit --wasm64 -guest.wasm: the_world.cpp guest.cpp +guest.wasm: the_world.cpp guest_exports.cpp /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) -guest_release.wasm: the_world.cpp guest.cpp +guest_release.wasm: the_world.cpp guest_exports.cpp /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) -g0 -O3 clean: diff --git a/crates/cpp/tests/native_strings/guest.cpp b/crates/cpp/tests/native_strings/guest_exports.cpp similarity index 67% rename from crates/cpp/tests/native_strings/guest.cpp rename to crates/cpp/tests/native_strings/guest_exports.cpp index 90fa6258d..6d2938f1a 100644 --- a/crates/cpp/tests/native_strings/guest.cpp +++ b/crates/cpp/tests/native_strings/guest_exports.cpp @@ -1,13 +1,16 @@ #include "the_world_cpp.h" -void exports::foo::foo::strings::A(wit::string &&x) { +void exports::foo::foo::strings::A(wit::string &&x) +{ ::foo::foo::strings::A(x.get_view()); } -wit::string exports::foo::foo::strings::B() { +wit::string exports::foo::foo::strings::B() +{ return ::foo::foo::strings::B(); } -wit::string exports::foo::foo::strings::C(wit::string &&x, wit::string &&b) { +wit::string exports::foo::foo::strings::C(wit::string &&x, wit::string &&b) +{ return ::foo::foo::strings::C(x.get_view(), b.get_view()); } diff --git a/crates/cpp/tests/native_strings/guest_imports.cpp b/crates/cpp/tests/native_strings/guest_imports.cpp new file mode 100644 index 000000000..ce4cc515e --- /dev/null +++ b/crates/cpp/tests/native_strings/guest_imports.cpp @@ -0,0 +1,20 @@ +#include "the_world_cpp_native.h" +#include + +using namespace std; + +void foo::foo::strings::A(std::string_view x) +{ + std::cout << x << std::endl; +} +wit::string foo::foo::strings::B() +{ + wit::string b = wit::string::from_view(std::string_view("hello B")); + return b; +} +wit::string foo::foo::strings::C(std::string_view a, std::string_view b) +{ + std::cout << a << '|' << b << std::endl; + wit::string c = wit::string::from_view(std::string_view("hello C")); + return c; +} \ No newline at end of file diff --git a/crates/cpp/tests/native_strings/main.cpp b/crates/cpp/tests/native_strings/main.cpp index 0f86198e5..faef32df4 100644 --- a/crates/cpp/tests/native_strings/main.cpp +++ b/crates/cpp/tests/native_strings/main.cpp @@ -2,19 +2,6 @@ #include "the_world_cpp_native.h" #include -void foo::foo::strings::A(std::string_view x) { - std::cout << x << std::endl; -} -wit::string foo::foo::strings::B() { - wit::string b = wit::string::from_view(std::string_view("hello B")); - return b; -} -wit::string foo::foo::strings::C(std::string_view a, std::string_view b) { - std::cout << a << '|' << b << std::endl; - wit::string c = wit::string::from_view(std::string_view("hello C")); - return c; -} - int main() { wit::string a = wit::string::from_view(std::string_view("hello A")); exports::foo::foo::strings::A(a); diff --git a/crates/cpp/tests/native_strings/rust/src/lib.rs b/crates/cpp/tests/native_strings/rust/src/lib.rs index 0fb041a18..4ab10ffe0 100644 --- a/crates/cpp/tests/native_strings/rust/src/lib.rs +++ b/crates/cpp/tests/native_strings/rust/src/lib.rs @@ -3,6 +3,7 @@ use std::alloc::Layout; use the_world::exports::foo::foo::strings::Guest; mod the_world; +mod the_world_native; struct MyWorld; @@ -22,6 +23,7 @@ impl Guest for MyWorld { the_world::export!(MyWorld with_types_in the_world); + // the crate wit-bindgen-rt doesn't work on native #[no_mangle] pub unsafe extern "C" fn cabi_realloc( diff --git a/crates/cpp/tests/native_strings/rust/src/the_world.rs b/crates/cpp/tests/native_strings/rust/src/the_world.rs index 5c05d404b..9f53259ca 100644 --- a/crates/cpp/tests/native_strings/rust/src/the_world.rs +++ b/crates/cpp/tests/native_strings/rust/src/the_world.rs @@ -1,159 +1,180 @@ // Generated by `wit-bindgen` 0.24.0. DO NOT EDIT! // Options used: + #[allow(dead_code)] pub mod foo { - #[allow(dead_code)] - pub mod foo { - #[allow(dead_code, clippy::all)] - pub mod strings { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - #[allow(unused_unsafe, clippy::all)] - pub fn a(x: &str,){ - unsafe { - let vec0 = x; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); + #[allow(dead_code)] + pub mod foo { + #[allow(dead_code, clippy::all)] + pub mod strings { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + use crate::the_world_native; - #[link(wasm_import_module = "foo:foo/strings")] - extern "C" { - #[cfg_attr(target_arch = "wasm32", link_name = "a")] - fn fooX3AfooX2FstringsX00a(_: *mut u8, _: usize, ); - } - fooX3AfooX2FstringsX00a(ptr0.cast_mut(), len0); - } - } - #[allow(unused_unsafe, clippy::all)] - pub fn b() -> _rt::String{ - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit::; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[link(wasm_import_module = "foo:foo/strings")] - extern "C" { - #[cfg_attr(target_arch = "wasm32", link_name = "b")] - fn fooX3AfooX2FstringsX00b(_: *mut u8, ); - } - fooX3AfooX2FstringsX00b(ptr0); - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(8).cast::(); - let len3 = l2; - let bytes3 = _rt::Vec::from_raw_parts(l1.cast(), len3, len3); - _rt::string_lift(bytes3) - } - } - #[allow(unused_unsafe, clippy::all)] - pub fn c(a: &str,b: &str,) -> _rt::String{ - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit::; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let vec0 = a; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let vec1 = b; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let ptr2 = ret_area.0.as_mut_ptr().cast::(); - #[link(wasm_import_module = "foo:foo/strings")] - extern "C" { - #[cfg_attr(target_arch = "wasm32", link_name = "c")] - fn fooX3AfooX2FstringsX00c(_: *mut u8, _: usize, _: *mut u8, _: usize, _: *mut u8, ); - } - fooX3AfooX2FstringsX00c(ptr0.cast_mut(), len0, ptr1.cast_mut(), len1, ptr2); - let l3 = *ptr2.add(0).cast::<*mut u8>(); - let l4 = *ptr2.add(8).cast::(); - let len5 = l4; - let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); - _rt::string_lift(bytes5) - } - } + use super::super::super::_rt; + #[allow(unused_unsafe, clippy::all)] + pub fn a(x: &str) { + unsafe { + let vec0 = x; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + #[link(wasm_import_module = "foo:foo/strings")] + extern "C" { + #[cfg_attr(target_arch = "wasm32", link_name = "a")] + fn fooX3AfooX2FstringsX00a(_: *mut u8, _: usize); + } + the_world_native::fooX3AfooX2FstringsX00a(ptr0.cast_mut(), len0); + } + } + #[allow(unused_unsafe, clippy::all)] + pub fn b() -> _rt::String { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 16]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[link(wasm_import_module = "foo:foo/strings")] + extern "C" { + #[cfg_attr(target_arch = "wasm32", link_name = "b")] + fn fooX3AfooX2FstringsX00b(_: *mut u8); + } + fooX3AfooX2FstringsX00b(ptr0); + let l1 = *ptr0.add(0).cast::<*mut u8>(); + let l2 = *ptr0.add(8).cast::(); + let len3 = l2; + let bytes3 = _rt::Vec::from_raw_parts(l1.cast(), len3, len3); + _rt::string_lift(bytes3) + } + } + #[allow(unused_unsafe, clippy::all)] + pub fn c(a: &str, b: &str) -> _rt::String { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 16]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); + let vec0 = a; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + let vec1 = b; + let ptr1 = vec1.as_ptr().cast::(); + let len1 = vec1.len(); + let ptr2 = ret_area.0.as_mut_ptr().cast::(); + #[link(wasm_import_module = "foo:foo/strings")] + extern "C" { + #[cfg_attr(target_arch = "wasm32", link_name = "c")] + fn fooX3AfooX2FstringsX00c( + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: *mut u8, + ); + } + fooX3AfooX2FstringsX00c(ptr0.cast_mut(), len0, ptr1.cast_mut(), len1, ptr2); + let l3 = *ptr2.add(0).cast::<*mut u8>(); + let l4 = *ptr2.add(8).cast::(); + let len5 = l4; + let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); + _rt::string_lift(bytes5) + } + } + } } - - } } #[allow(dead_code)] pub mod exports { - #[allow(dead_code)] - pub mod foo { #[allow(dead_code)] pub mod foo { - #[allow(dead_code, clippy::all)] - pub mod strings { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_custom_section_describing_imports; - use super::super::super::super::_rt; - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn _export_a_cabi(arg0: *mut u8,arg1: usize,) {#[cfg(target_arch="wasm32")] - _rt::run_ctors_once();let len0 = arg1; - let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); - T::a(_rt::string_lift(bytes0)); - } - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn _export_b_cabi() -> *mut u8 {#[cfg(target_arch="wasm32")] - _rt::run_ctors_once();let result0 = T::b(); - let ptr1 = _RET_AREA.0.as_mut_ptr().cast::(); - let vec2 = (result0.into_bytes()).into_boxed_slice(); - let ptr2 = vec2.as_ptr().cast::(); - let len2 = vec2.len(); - ::core::mem::forget(vec2); - *ptr1.add(8).cast::() = len2; - *ptr1.add(0).cast::<*mut u8>() = ptr2.cast_mut(); - ptr1 - } - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn __post_return_b(arg0: *mut u8,) { - let l0 = *arg0.add(0).cast::<*mut u8>(); - let l1 = *arg0.add(8).cast::(); - _rt::cabi_dealloc(l0, l1, 1); - } - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn _export_c_cabi(arg0: *mut u8,arg1: usize,arg2: *mut u8,arg3: usize,) -> *mut u8 {#[cfg(target_arch="wasm32")] - _rt::run_ctors_once();let len0 = arg1; - let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); - let len1 = arg3; - let bytes1 = _rt::Vec::from_raw_parts(arg2.cast(), len1, len1); - let result2 = T::c(_rt::string_lift(bytes0), _rt::string_lift(bytes1)); - let ptr3 = _RET_AREA.0.as_mut_ptr().cast::(); - let vec4 = (result2.into_bytes()).into_boxed_slice(); - let ptr4 = vec4.as_ptr().cast::(); - let len4 = vec4.len(); - ::core::mem::forget(vec4); - *ptr3.add(8).cast::() = len4; - *ptr3.add(0).cast::<*mut u8>() = ptr4.cast_mut(); - ptr3 - } - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn __post_return_c(arg0: *mut u8,) { - let l0 = *arg0.add(0).cast::<*mut u8>(); - let l1 = *arg0.add(8).cast::(); - _rt::cabi_dealloc(l0, l1, 1); - } - pub trait Guest { - fn a(x: _rt::String,); - fn b() -> _rt::String; - fn c(a: _rt::String,b: _rt::String,) -> _rt::String; - } - #[doc(hidden)] - - macro_rules! __export_foo_foo_strings_cabi{ + #[allow(dead_code)] + pub mod foo { + #[allow(dead_code, clippy::all)] + pub mod strings { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::super::__link_custom_section_describing_imports; + use super::super::super::super::_rt; + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_a_cabi(arg0: *mut u8, arg1: usize) { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let len0 = arg1; + let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); + T::a(_rt::string_lift(bytes0)); + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_b_cabi() -> *mut u8 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let result0 = T::b(); + let ptr1 = _RET_AREA.0.as_mut_ptr().cast::(); + let vec2 = (result0.into_bytes()).into_boxed_slice(); + let ptr2 = vec2.as_ptr().cast::(); + let len2 = vec2.len(); + ::core::mem::forget(vec2); + *ptr1.add(8).cast::() = len2; + *ptr1.add(0).cast::<*mut u8>() = ptr2.cast_mut(); + ptr1 + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_b(arg0: *mut u8) { + let l0 = *arg0.add(0).cast::<*mut u8>(); + let l1 = *arg0.add(8).cast::(); + _rt::cabi_dealloc(l0, l1, 1); + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_c_cabi( + arg0: *mut u8, + arg1: usize, + arg2: *mut u8, + arg3: usize, + ) -> *mut u8 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let len0 = arg1; + let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); + let len1 = arg3; + let bytes1 = _rt::Vec::from_raw_parts(arg2.cast(), len1, len1); + let result2 = T::c(_rt::string_lift(bytes0), _rt::string_lift(bytes1)); + let ptr3 = _RET_AREA.0.as_mut_ptr().cast::(); + let vec4 = (result2.into_bytes()).into_boxed_slice(); + let ptr4 = vec4.as_ptr().cast::(); + let len4 = vec4.len(); + ::core::mem::forget(vec4); + *ptr3.add(8).cast::() = len4; + *ptr3.add(0).cast::<*mut u8>() = ptr4.cast_mut(); + ptr3 + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_c(arg0: *mut u8) { + let l0 = *arg0.add(0).cast::<*mut u8>(); + let l1 = *arg0.add(8).cast::(); + _rt::cabi_dealloc(l0, l1, 1); + } + pub trait Guest { + fn a(x: _rt::String); + fn b() -> _rt::String; + fn c(a: _rt::String, b: _rt::String) -> _rt::String; + } + #[doc(hidden)] + #[macro_export] + macro_rules! __export_foo_foo_strings_cabi{ ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#a")] #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] - unsafe extern "C" fn fooX3AfooX2FstringsX23a(arg0: *mut u8,arg1: usize,) { + pub unsafe extern "C" fn fooX3AfooX2FstringsX23a(arg0: *mut u8,arg1: usize,) { + println!("fooX3AfooX2FstringsX23a"); $($path_to_types)*::_export_a_cabi::<$ty>(arg0, arg1) } #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#b")] @@ -178,41 +199,39 @@ pub mod exports { } };); } - #[doc(hidden)] - pub(crate) use __export_foo_foo_strings_cabi; - #[repr(align(8))] - struct _RetArea([::core::mem::MaybeUninit::; 16]); - static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); 16]); - -} - -} -} + #[doc(hidden)] + pub(crate) use __export_foo_foo_strings_cabi; + #[repr(align(8))] + struct _RetArea([::core::mem::MaybeUninit; 16]); + static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); 16]); + } + } + } } mod _rt { - pub use alloc_crate::string::String; - pub use alloc_crate::vec::Vec; - pub unsafe fn string_lift(bytes: Vec) -> String { - if cfg!(debug_assertions) { - String::from_utf8(bytes).unwrap() - } else { - String::from_utf8_unchecked(bytes) + pub use alloc_crate::string::String; + pub use alloc_crate::vec::Vec; + pub unsafe fn string_lift(bytes: Vec) -> 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() { - wit_bindgen::rt::run_ctors_once(); - } - pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) { - if size == 0 { - return; + + #[cfg(target_arch = "wasm32")] + pub fn run_ctors_once() { + wit_bindgen::rt::run_ctors_once(); } - let layout = alloc::Layout::from_size_align_unchecked(size, align); - alloc::dealloc(ptr as *mut u8, layout); - } - extern crate alloc as alloc_crate; - pub use alloc_crate::alloc; + pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) { + if size == 0 { + return; + } + let layout = alloc::Layout::from_size_align_unchecked(size, align); + alloc::dealloc(ptr as *mut u8, layout); + } + extern crate alloc as alloc_crate; + pub use alloc_crate::alloc; } /// Generates `#[no_mangle]` functions to export the specified type as the @@ -259,6 +278,5 @@ processed-by\x02\x0dwit-component\x070.207.0\x10wit-bindgen-rust\x060.24.0"; #[doc(hidden)] #[cfg(target_arch = "wasm32")] pub fn __link_custom_section_describing_imports() { - wit_bindgen::rt::maybe_link_cabi_realloc(); + wit_bindgen::rt::maybe_link_cabi_realloc(); } - diff --git a/crates/cpp/tests/native_strings/the_world.cpp b/crates/cpp/tests/native_strings/the_world.cpp index 9ab7b9c5c..d7538bb90 100644 --- a/crates/cpp/tests/native_strings/the_world.cpp +++ b/crates/cpp/tests/native_strings/the_world.cpp @@ -63,7 +63,7 @@ wit::string foo::foo::strings::C(std::string_view a, std::string_view b) { return wit::string((char const *)(*((uint8_t **)(ptr2 + 0))), len3); } extern "C" __attribute__((__export_name__("foo:foo/strings#a"))) void -fooX3AfooX2FstringsX23a(uint8_t *arg0, size_t arg1) { +fooX3AfooX2FstringsX23a(uint8_t *arg0, size_t arg1) { auto len0 = arg1; exports::foo::foo::strings::A(wit::string((char const *)(arg0), len0)); diff --git a/crates/cpp/tests/native_strings/the_world_native.cpp b/crates/cpp/tests/native_strings/the_world_native.cpp index 2ba8a4083..9284ff6ca 100644 --- a/crates/cpp/tests/native_strings/the_world_native.cpp +++ b/crates/cpp/tests/native_strings/the_world_native.cpp @@ -44,11 +44,12 @@ extern "C" void fooX3AfooX2FstringsX00c(uint8_t *arg0, size_t arg1, *((size_t *)(arg4 + 8)) = len3; *((uint8_t **)(arg4 + 0)) = ptr3; } -void exports::foo::foo::strings::A(wit::string x) { +void exports::foo::foo::strings::A(wit::string x) { auto const &vec0 = x; auto ptr0 = vec0.data(); auto len0 = vec0.size(); fooX3AfooX2FstringsX23a(ptr0, len0); + } wit::guest_owned exports::foo::foo::strings::B() { auto ret = fooX3AfooX2FstringsX23b(); From e7d250896423b45df4e4d2983c9bc696408cc518 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar K J Date: Thu, 23 May 2024 16:53:21 +0530 Subject: [PATCH 2/8] rename file and add README Signed-off-by: Pradeep Kumar K J --- crates/cpp/tests/native_strings/Makefile | 8 ++++---- crates/cpp/tests/native_strings/README.md | 13 +++++++++++++ .../{guest_exports.cpp => guest_1.cpp} | 0 .../{guest_imports.cpp => guest_2.cpp} | 3 ++- crates/cpp/tests/native_strings/the_world.cpp | 5 ++--- .../cpp/tests/native_strings/the_world_native.cpp | 5 ++--- 6 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 crates/cpp/tests/native_strings/README.md rename crates/cpp/tests/native_strings/{guest_exports.cpp => guest_1.cpp} (100%) rename crates/cpp/tests/native_strings/{guest_imports.cpp => guest_2.cpp} (89%) diff --git a/crates/cpp/tests/native_strings/Makefile b/crates/cpp/tests/native_strings/Makefile index 0be82d7aa..0bfb02ebb 100644 --- a/crates/cpp/tests/native_strings/Makefile +++ b/crates/cpp/tests/native_strings/Makefile @@ -3,13 +3,13 @@ WIT_BINDGEN=../../../../target/debug/wit-bindgen all: libstrings.so app-strings -libstrings.so: the_world.pie.o guest_exports.pie.o +libstrings.so: the_world.pie.o guest_1.pie.o $(CXX) $(CXXFLAGS) -shared -o $@ $^ -Wl,--version-script=guest.lds %.pie.o: %.cpp $(CXX) $(CXXFLAGS) -fPIE -o $@ -c $^ -app-strings: the_world_native.o main.o guest_imports.o +app-strings: the_world_native.o main.o guest_2.o $(CXX) $(CXXFLAGS) -o $@ $^ -g -L. -lstrings bindgen: wit/strings.wit @@ -17,10 +17,10 @@ bindgen: wit/strings.wit $(WIT_BINDGEN) cpp wit --wasm64 --format --direct cd rust/src ; ../../$(WIT_BINDGEN) rust ../../wit --wasm64 -guest.wasm: the_world.cpp guest_exports.cpp +guest.wasm: the_world.cpp guest_1.cpp /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) -guest_release.wasm: the_world.cpp guest_exports.cpp +guest_release.wasm: the_world.cpp guest_1.cpp /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) -g0 -O3 clean: diff --git a/crates/cpp/tests/native_strings/README.md b/crates/cpp/tests/native_strings/README.md new file mode 100644 index 000000000..33f7c14d9 --- /dev/null +++ b/crates/cpp/tests/native_strings/README.md @@ -0,0 +1,13 @@ +# Native string example + +In this example there are two guests, guest_1 and guest_2 +They use the mesh/native-host code to communicate to each other + +The wit-bindgen creates the guest bindings and native-host code + +This is how the example works, call graph for the function `A` (communication between the guest_1 and guest_2 using the mesh/native host code) + +guest_1->exports::foo::foo::strings::A(a){native host export call}->fooX3AfooX2FstringsX23a(){guest export binding} +-> exports::foo::foo::strings::A(wit::string &&x){guest_1 export implementation} +-> foo::foo::strings::A(std::string_view x){guest import call}->fooX3AfooX2FstringsX00a() {guest import binding} +-> foo::foo::strings::A(std::string_view x) { guest_2 import implementation} diff --git a/crates/cpp/tests/native_strings/guest_exports.cpp b/crates/cpp/tests/native_strings/guest_1.cpp similarity index 100% rename from crates/cpp/tests/native_strings/guest_exports.cpp rename to crates/cpp/tests/native_strings/guest_1.cpp diff --git a/crates/cpp/tests/native_strings/guest_imports.cpp b/crates/cpp/tests/native_strings/guest_2.cpp similarity index 89% rename from crates/cpp/tests/native_strings/guest_imports.cpp rename to crates/cpp/tests/native_strings/guest_2.cpp index ce4cc515e..6d9acd097 100644 --- a/crates/cpp/tests/native_strings/guest_imports.cpp +++ b/crates/cpp/tests/native_strings/guest_2.cpp @@ -4,7 +4,8 @@ using namespace std; void foo::foo::strings::A(std::string_view x) -{ +{ + std::cout << "strings import call" << std::endl; std::cout << x << std::endl; } wit::string foo::foo::strings::B() diff --git a/crates/cpp/tests/native_strings/the_world.cpp b/crates/cpp/tests/native_strings/the_world.cpp index d7538bb90..f09af0793 100644 --- a/crates/cpp/tests/native_strings/the_world.cpp +++ b/crates/cpp/tests/native_strings/the_world.cpp @@ -34,7 +34,7 @@ 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 *); -void foo::foo::strings::A(std::string_view x) { +void foo::foo::strings::A(std::string_view x) { auto const &vec0 = x; auto ptr0 = (uint8_t *)(vec0.data()); auto len0 = (size_t)(vec0.size()); @@ -64,8 +64,7 @@ wit::string foo::foo::strings::C(std::string_view a, std::string_view b) { } extern "C" __attribute__((__export_name__("foo:foo/strings#a"))) void fooX3AfooX2FstringsX23a(uint8_t *arg0, size_t arg1) { - auto len0 = arg1; - + auto len0 = arg1; exports::foo::foo::strings::A(wit::string((char const *)(arg0), len0)); } extern "C" __attribute__((__export_name__("foo:foo/strings#b"))) uint8_t * diff --git a/crates/cpp/tests/native_strings/the_world_native.cpp b/crates/cpp/tests/native_strings/the_world_native.cpp index 9284ff6ca..66e35da68 100644 --- a/crates/cpp/tests/native_strings/the_world_native.cpp +++ b/crates/cpp/tests/native_strings/the_world_native.cpp @@ -15,7 +15,7 @@ fooX3AfooX2FstringsX23c(uint8_t *, size_t, uint8_t *, size_t); extern "C" __attribute__((import_module("cabi_post_foo:foo/strings"))) __attribute__((import_name("c"))) void cabi_post_fooX3AfooX2FstringsX23c(uint8_t *); -extern "C" void fooX3AfooX2FstringsX00a(uint8_t *arg0, size_t arg1) { +extern "C" void fooX3AfooX2FstringsX00a(uint8_t *arg0, size_t arg1) { auto len0 = arg1; foo::foo::strings::A(std::string_view((char const *)(arg0), len0)); @@ -47,9 +47,8 @@ extern "C" void fooX3AfooX2FstringsX00c(uint8_t *arg0, size_t arg1, void exports::foo::foo::strings::A(wit::string x) { auto const &vec0 = x; auto ptr0 = vec0.data(); - auto len0 = vec0.size(); + auto len0 = vec0.size(); fooX3AfooX2FstringsX23a(ptr0, len0); - } wit::guest_owned exports::foo::foo::strings::B() { auto ret = fooX3AfooX2FstringsX23b(); From de08afb837e3ff5bdcc572d8a8972c0c59bd9ee3 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar K J Date: Mon, 27 May 2024 10:51:42 +0530 Subject: [PATCH 3/8] re-structured the source code Signed-off-by: Pradeep Kumar K J --- crates/cpp/tests/native_strings/Makefile | 18 +++++----- crates/cpp/tests/native_strings/README.md | 4 +-- .../tests/native_strings/cpp_host/Makefile | 10 ++++++ .../{ => cpp_host}/the_world_cpp_native.h | 0 .../{ => cpp_host}/the_world_native.cpp | 0 .../cpp/tests/native_strings/guest/Makefile | 35 +++++++++++++++++++ .../{guest_1.cpp => guest/guest.cpp} | 0 .../native_strings/{ => guest}/guest.lds | 0 .../native_strings/{ => guest}/the_world.cpp | 0 .../{ => guest}/the_world_cpp.h | 0 .../{guest_2.cpp => guest_imported_fns.cpp} | 5 ++- crates/cpp/tests/native_strings/main.cpp | 2 +- .../cpp/tests/native_strings/rust/src/lib.rs | 4 +++ 13 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 crates/cpp/tests/native_strings/cpp_host/Makefile rename crates/cpp/tests/native_strings/{ => cpp_host}/the_world_cpp_native.h (100%) rename crates/cpp/tests/native_strings/{ => cpp_host}/the_world_native.cpp (100%) create mode 100644 crates/cpp/tests/native_strings/guest/Makefile rename crates/cpp/tests/native_strings/{guest_1.cpp => guest/guest.cpp} (100%) rename crates/cpp/tests/native_strings/{ => guest}/guest.lds (100%) rename crates/cpp/tests/native_strings/{ => guest}/the_world.cpp (100%) rename crates/cpp/tests/native_strings/{ => guest}/the_world_cpp.h (100%) rename crates/cpp/tests/native_strings/{guest_2.cpp => guest_imported_fns.cpp} (83%) diff --git a/crates/cpp/tests/native_strings/Makefile b/crates/cpp/tests/native_strings/Makefile index 0bfb02ebb..edfd7779c 100644 --- a/crates/cpp/tests/native_strings/Makefile +++ b/crates/cpp/tests/native_strings/Makefile @@ -1,16 +1,16 @@ -CXXFLAGS=-g -O0 -I../../helper-types --std=c++17 +CXXFLAGS=-g -O0 -I../../helper-types -I../../cpp_host -I../../guest --std=c++17 WIT_BINDGEN=../../../../target/debug/wit-bindgen all: libstrings.so app-strings -libstrings.so: the_world.pie.o guest_1.pie.o - $(CXX) $(CXXFLAGS) -shared -o $@ $^ -Wl,--version-script=guest.lds +libstrings.so: + cd guest && make $@ -%.pie.o: %.cpp - $(CXX) $(CXXFLAGS) -fPIE -o $@ -c $^ +app-strings: ./cpp_host/the_world_native.o main.o guest_imported_fns.o + $(CXX) $(CXXFLAGS) -o $@ $^ -g -L./guest -lstrings -app-strings: the_world_native.o main.o guest_2.o - $(CXX) $(CXXFLAGS) -o $@ $^ -g -L. -lstrings +the_world_native.o: + cd cpp_host && make $@ bindgen: wit/strings.wit $(WIT_BINDGEN) cpp wit --wasm64 --format @@ -24,7 +24,9 @@ guest_release.wasm: the_world.cpp guest_1.cpp /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) -g0 -O3 clean: - -rm *.o libstrings.so app-strings + -rm *.o app-strings + cd guest && make clean + cd cpp_host && make clean run: LD_LIBRARY_PATH=. ./app-strings diff --git a/crates/cpp/tests/native_strings/README.md b/crates/cpp/tests/native_strings/README.md index 33f7c14d9..d7641606f 100644 --- a/crates/cpp/tests/native_strings/README.md +++ b/crates/cpp/tests/native_strings/README.md @@ -7,7 +7,7 @@ The wit-bindgen creates the guest bindings and native-host code This is how the example works, call graph for the function `A` (communication between the guest_1 and guest_2 using the mesh/native host code) -guest_1->exports::foo::foo::strings::A(a){native host export call}->fooX3AfooX2FstringsX23a(){guest export binding} +guest_1->exports::foo::foo::strings::A(a){native host export call}->fooX3AfooX2FstringsX23a(){native host export binding(lifting)} -> exports::foo::foo::strings::A(wit::string &&x){guest_1 export implementation} --> foo::foo::strings::A(std::string_view x){guest import call}->fooX3AfooX2FstringsX00a() {guest import binding} +-> foo::foo::strings::A(std::string_view x){guest import call}->fooX3AfooX2FstringsX00a() {native host import binding(lowering)} -> foo::foo::strings::A(std::string_view x) { guest_2 import implementation} diff --git a/crates/cpp/tests/native_strings/cpp_host/Makefile b/crates/cpp/tests/native_strings/cpp_host/Makefile new file mode 100644 index 000000000..39f346a18 --- /dev/null +++ b/crates/cpp/tests/native_strings/cpp_host/Makefile @@ -0,0 +1,10 @@ +CXXFLAGS=-g -O0 -I../../../helper-types --std=c++17 +WIT_BINDGEN=../../../../target/debug/wit-bindgen + +all: the_world_native.o + +the_world_native.o: + $(CXX) $(CXXFLAGS) -fPIE -o $@ -c the_world_native.cpp + +clean: + -rm *.o \ No newline at end of file diff --git a/crates/cpp/tests/native_strings/the_world_cpp_native.h b/crates/cpp/tests/native_strings/cpp_host/the_world_cpp_native.h similarity index 100% rename from crates/cpp/tests/native_strings/the_world_cpp_native.h rename to crates/cpp/tests/native_strings/cpp_host/the_world_cpp_native.h diff --git a/crates/cpp/tests/native_strings/the_world_native.cpp b/crates/cpp/tests/native_strings/cpp_host/the_world_native.cpp similarity index 100% rename from crates/cpp/tests/native_strings/the_world_native.cpp rename to crates/cpp/tests/native_strings/cpp_host/the_world_native.cpp diff --git a/crates/cpp/tests/native_strings/guest/Makefile b/crates/cpp/tests/native_strings/guest/Makefile new file mode 100644 index 000000000..33379b5fc --- /dev/null +++ b/crates/cpp/tests/native_strings/guest/Makefile @@ -0,0 +1,35 @@ +CXXFLAGS=-g -O0 -I../../../helper-types --std=c++17 +WIT_BINDGEN=../../../../target/debug/wit-bindgen + +all: libstrings.so + +libstrings.so: the_world.pie.o guest.pie.o + $(CXX) $(CXXFLAGS) -shared -o $@ $^ -Wl,--version-script=guest.lds + +%.pie.o: %.cpp + $(CXX) $(CXXFLAGS) -fPIE -o $@ -c $^ + +bindgen: wit/strings.wit + $(WIT_BINDGEN) cpp wit --wasm64 --format + cd cpp_host + $(WIT_BINDGEN) cpp wit --wasm64 --format --direct + cd - + cd rust/src ; ../../$(WIT_BINDGEN) rust ../../wit --wasm64 + +guest.wasm: the_world.cpp guest.cpp + /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) + +guest_release.wasm: the_world.cpp guest.cpp + /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) -g0 -O3 + +clean: + -rm *.o libstrings.so app-strings + +run: + LD_LIBRARY_PATH=. ./app-strings + +valgrind: + LD_LIBRARY_PATH=. valgrind ./app-strings + +w2c2_guest.c: guest_release.wasm + w2c2 $^ $@ diff --git a/crates/cpp/tests/native_strings/guest_1.cpp b/crates/cpp/tests/native_strings/guest/guest.cpp similarity index 100% rename from crates/cpp/tests/native_strings/guest_1.cpp rename to crates/cpp/tests/native_strings/guest/guest.cpp diff --git a/crates/cpp/tests/native_strings/guest.lds b/crates/cpp/tests/native_strings/guest/guest.lds similarity index 100% rename from crates/cpp/tests/native_strings/guest.lds rename to crates/cpp/tests/native_strings/guest/guest.lds diff --git a/crates/cpp/tests/native_strings/the_world.cpp b/crates/cpp/tests/native_strings/guest/the_world.cpp similarity index 100% rename from crates/cpp/tests/native_strings/the_world.cpp rename to crates/cpp/tests/native_strings/guest/the_world.cpp diff --git a/crates/cpp/tests/native_strings/the_world_cpp.h b/crates/cpp/tests/native_strings/guest/the_world_cpp.h similarity index 100% rename from crates/cpp/tests/native_strings/the_world_cpp.h rename to crates/cpp/tests/native_strings/guest/the_world_cpp.h diff --git a/crates/cpp/tests/native_strings/guest_2.cpp b/crates/cpp/tests/native_strings/guest_imported_fns.cpp similarity index 83% rename from crates/cpp/tests/native_strings/guest_2.cpp rename to crates/cpp/tests/native_strings/guest_imported_fns.cpp index 6d9acd097..54060d9bd 100644 --- a/crates/cpp/tests/native_strings/guest_2.cpp +++ b/crates/cpp/tests/native_strings/guest_imported_fns.cpp @@ -1,11 +1,10 @@ -#include "the_world_cpp_native.h" +#include "./cpp_host/the_world_cpp_native.h" #include using namespace std; void foo::foo::strings::A(std::string_view x) -{ - std::cout << "strings import call" << std::endl; +{ std::cout << x << std::endl; } wit::string foo::foo::strings::B() diff --git a/crates/cpp/tests/native_strings/main.cpp b/crates/cpp/tests/native_strings/main.cpp index faef32df4..64b55bb4c 100644 --- a/crates/cpp/tests/native_strings/main.cpp +++ b/crates/cpp/tests/native_strings/main.cpp @@ -1,5 +1,5 @@ -#include "the_world_cpp_native.h" +#include "./cpp_host/the_world_cpp_native.h" #include int main() { diff --git a/crates/cpp/tests/native_strings/rust/src/lib.rs b/crates/cpp/tests/native_strings/rust/src/lib.rs index 4ab10ffe0..95e30c643 100644 --- a/crates/cpp/tests/native_strings/rust/src/lib.rs +++ b/crates/cpp/tests/native_strings/rust/src/lib.rs @@ -2,6 +2,8 @@ use std::alloc::Layout; use the_world::exports::foo::foo::strings::Guest; +use the_world::exports::foo::foo::strings; +#[macro_use] mod the_world; mod the_world_native; @@ -23,6 +25,8 @@ impl Guest for MyWorld { the_world::export!(MyWorld with_types_in the_world); +__export_foo_foo_strings_cabi!(MyWorld with_types_in strings); + // the crate wit-bindgen-rt doesn't work on native #[no_mangle] From eb016b7b6953d8b242a372d0c21b15f2ae5fdcee Mon Sep 17 00:00:00 2001 From: Pradeep Kumar K J Date: Mon, 27 May 2024 11:45:00 +0530 Subject: [PATCH 4/8] update the readme Signed-off-by: Pradeep Kumar K J --- crates/cpp/tests/native_strings/README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/crates/cpp/tests/native_strings/README.md b/crates/cpp/tests/native_strings/README.md index d7641606f..d32cf1837 100644 --- a/crates/cpp/tests/native_strings/README.md +++ b/crates/cpp/tests/native_strings/README.md @@ -1,9 +1,21 @@ # Native string example -In this example there are two guests, guest_1 and guest_2 -They use the mesh/native-host code to communicate to each other +In this example, there is a guest, a native host (cpp_host) and an application. +The `guest + native host` together form the actual `guest` code, which exports some APIs. +Now the application which is `host`, will use the guest exported calls. +The application/host also imports some calls, those are part of the `guest_imported_functions.cpp` -The wit-bindgen creates the guest bindings and native-host code +The directory strucutre is as below: +``` +├── cpp_host (Native host code) +├── guest (Guest code) +├── guest_imported_fns.cpp ( host application imported calls) +├── main.cpp (Application) +└── wit (Wit file that is used for generating the code) + +``` + +# Call-graph for a function This is how the example works, call graph for the function `A` (communication between the guest_1 and guest_2 using the mesh/native host code) From 909498635be8bbe7a14ddf954182fdaaf98a2710 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar K J Date: Wed, 29 May 2024 11:38:52 +0530 Subject: [PATCH 5/8] move guest imported into host Signed-off-by: Pradeep Kumar K J --- crates/cpp/tests/native_strings/Makefile | 2 +- crates/cpp/tests/native_strings/cpp_host/Makefile | 6 +++++- .../native_strings/{ => cpp_host}/guest_imported_fns.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) rename crates/cpp/tests/native_strings/{ => cpp_host}/guest_imported_fns.cpp (91%) diff --git a/crates/cpp/tests/native_strings/Makefile b/crates/cpp/tests/native_strings/Makefile index edfd7779c..172ae383a 100644 --- a/crates/cpp/tests/native_strings/Makefile +++ b/crates/cpp/tests/native_strings/Makefile @@ -6,7 +6,7 @@ all: libstrings.so app-strings libstrings.so: cd guest && make $@ -app-strings: ./cpp_host/the_world_native.o main.o guest_imported_fns.o +app-strings: ./cpp_host/the_world_native.o main.o ./cpp_host/guest_imported_fns.o $(CXX) $(CXXFLAGS) -o $@ $^ -g -L./guest -lstrings the_world_native.o: diff --git a/crates/cpp/tests/native_strings/cpp_host/Makefile b/crates/cpp/tests/native_strings/cpp_host/Makefile index 39f346a18..4f059305b 100644 --- a/crates/cpp/tests/native_strings/cpp_host/Makefile +++ b/crates/cpp/tests/native_strings/cpp_host/Makefile @@ -1,10 +1,14 @@ CXXFLAGS=-g -O0 -I../../../helper-types --std=c++17 WIT_BINDGEN=../../../../target/debug/wit-bindgen -all: the_world_native.o +all: the_world_native.o guest_imported_fns.o the_world_native.o: $(CXX) $(CXXFLAGS) -fPIE -o $@ -c the_world_native.cpp +guest_imported_fns.o: + $(CXX) $(CXXFLAGS) -fPIE -o $@ -c guest_imported_fns.cpp + + clean: -rm *.o \ No newline at end of file diff --git a/crates/cpp/tests/native_strings/guest_imported_fns.cpp b/crates/cpp/tests/native_strings/cpp_host/guest_imported_fns.cpp similarity index 91% rename from crates/cpp/tests/native_strings/guest_imported_fns.cpp rename to crates/cpp/tests/native_strings/cpp_host/guest_imported_fns.cpp index 54060d9bd..179cff845 100644 --- a/crates/cpp/tests/native_strings/guest_imported_fns.cpp +++ b/crates/cpp/tests/native_strings/cpp_host/guest_imported_fns.cpp @@ -1,4 +1,4 @@ -#include "./cpp_host/the_world_cpp_native.h" +#include "./the_world_cpp_native.h" #include using namespace std; From a590c75e664c7eacb8b04c9904bd5506b310e682 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar K J Date: Wed, 5 Jun 2024 18:06:38 +0530 Subject: [PATCH 6/8] rust native code Signed-off-by: Pradeep Kumar K J --- Cargo.lock | 11 + Cargo.toml | 3 +- crates/cpp/Cargo.toml | 1 + crates/cpp/tests/native_strings/Makefile | 8 +- crates/cpp/tests/native_strings/README.md | 2 +- .../{rust => rust-host/rust-host}/Cargo.toml | 6 - .../rust-host/src/generated.rs} | 26 +- .../rust-host/src/guest_imported_fns.rs | 20 ++ .../rust-host/rust-host/src/lib.rs | 5 + .../rust-host/rust-host/src/native_imports.rs | 66 ++++ .../rust-host/src/the_native_imports.rs | 22 ++ .../rust-host}/src/the_world.rs | 68 ++-- .../rust-host/src/the_world_native.rs | 54 ++++ .../rust-host/rust_app/Cargo.toml | 7 + .../rust-host/rust_app/src/main.rs | 14 + .../rust-host/rust_native_host_lib/Cargo.toml | 6 + .../rust_native_host_lib/src/generated.rs | 47 +++ .../src/guest_imported_fns.rs | 20 ++ .../rust-host/rust_native_host_lib/src/lib.rs | 5 + .../src/native_imports.rs | 66 ++++ .../src/the_native_imports.rs | 22 ++ .../rust_native_host_lib/src/the_world.rs | 306 ++++++++++++++++++ .../src/the_world_native.rs | 54 ++++ .../cpp/tests/native_strings/rust/Cargo.lock | 7 - 24 files changed, 789 insertions(+), 57 deletions(-) rename crates/cpp/tests/native_strings/{rust => rust-host/rust-host}/Cargo.toml (52%) rename crates/cpp/tests/native_strings/{rust/src/lib.rs => rust-host/rust-host/src/generated.rs} (62%) create mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs rename crates/cpp/tests/native_strings/{rust => rust-host/rust-host}/src/the_world.rs (84%) create mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_app/Cargo.toml create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_app/src/main.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/Cargo.toml create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/generated.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/guest_imported_fns.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/lib.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/native_imports.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_native_imports.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world.rs create mode 100644 crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world_native.rs delete mode 100644 crates/cpp/tests/native_strings/rust/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index 1c3091e40..1a33afa47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1213,6 +1213,17 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "rust_app" +version = "0.1.0" +dependencies = [ + "rust_native_host_lib", +] + +[[package]] +name = "rust_native_host_lib" +version = "0.1.0" + [[package]] name = "rustc-demangle" version = "0.1.23" diff --git a/Cargo.toml b/Cargo.toml index 8a7300430..7a7b55358 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,8 +12,7 @@ CLI tool to generate bindings for WIT documents and the component model. [workspace] members = [ - "crates/test-rust-wasm", -] + "crates/test-rust-wasm","crates/cpp/tests/native_strings/rust-host/rust_native_host_lib","crates/cpp/tests/native_strings/rust-host/rust_app"] resolver = "2" [workspace.package] diff --git a/crates/cpp/Cargo.toml b/crates/cpp/Cargo.toml index b9d9a5139..28e464c9a 100644 --- a/crates/cpp/Cargo.toml +++ b/crates/cpp/Cargo.toml @@ -9,6 +9,7 @@ description = """ C++ guest and host binding generator for WIT and the component model. """ + [lib] doctest = false test = false diff --git a/crates/cpp/tests/native_strings/Makefile b/crates/cpp/tests/native_strings/Makefile index 172ae383a..55413602b 100644 --- a/crates/cpp/tests/native_strings/Makefile +++ b/crates/cpp/tests/native_strings/Makefile @@ -1,14 +1,18 @@ CXXFLAGS=-g -O0 -I../../helper-types -I../../cpp_host -I../../guest --std=c++17 WIT_BINDGEN=../../../../target/debug/wit-bindgen -all: libstrings.so app-strings +all: libstrings.so cpp-app-strings rust-app-strings libstrings.so: cd guest && make $@ -app-strings: ./cpp_host/the_world_native.o main.o ./cpp_host/guest_imported_fns.o +cpp-app-strings: ./cpp_host/the_world_native.o main.o ./cpp_host/guest_imported_fns.o $(CXX) $(CXXFLAGS) -o $@ $^ -g -L./guest -lstrings +rust-app-strings: main.o + $(CXX) $(CXXFLAGS) -o $@ $^ -g -L/mnt/sda2/pradeep/wasm/RND/math_fns/target/debug -lstrings + + the_world_native.o: cd cpp_host && make $@ diff --git a/crates/cpp/tests/native_strings/README.md b/crates/cpp/tests/native_strings/README.md index d32cf1837..542356ab0 100644 --- a/crates/cpp/tests/native_strings/README.md +++ b/crates/cpp/tests/native_strings/README.md @@ -22,4 +22,4 @@ This is how the example works, call graph for the function `A` (communication be guest_1->exports::foo::foo::strings::A(a){native host export call}->fooX3AfooX2FstringsX23a(){native host export binding(lifting)} -> exports::foo::foo::strings::A(wit::string &&x){guest_1 export implementation} -> foo::foo::strings::A(std::string_view x){guest import call}->fooX3AfooX2FstringsX00a() {native host import binding(lowering)} --> foo::foo::strings::A(std::string_view x) { guest_2 import implementation} +-> foo::foo::strings::A(std::string_view x) { guest import functions implementation} diff --git a/crates/cpp/tests/native_strings/rust/Cargo.toml b/crates/cpp/tests/native_strings/rust-host/rust-host/Cargo.toml similarity index 52% rename from crates/cpp/tests/native_strings/rust/Cargo.toml rename to crates/cpp/tests/native_strings/rust-host/rust-host/Cargo.toml index 54920869d..636ed4f5b 100644 --- a/crates/cpp/tests/native_strings/rust/Cargo.toml +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/Cargo.toml @@ -1,12 +1,6 @@ -[workspace] - [package] name = "strings" version = "0.1.0" edition = "2021" -[lib] -crate-type = ["cdylib"] - [dependencies] -# wit-bindgen-rt = "0.21.0" diff --git a/crates/cpp/tests/native_strings/rust/src/lib.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/generated.rs similarity index 62% rename from crates/cpp/tests/native_strings/rust/src/lib.rs rename to crates/cpp/tests/native_strings/rust-host/rust-host/src/generated.rs index 95e30c643..a70a232e5 100644 --- a/crates/cpp/tests/native_strings/rust/src/lib.rs +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/src/generated.rs @@ -1,32 +1,24 @@ use std::alloc::Layout; -use the_world::exports::foo::foo::strings::Guest; - -use the_world::exports::foo::foo::strings; -#[macro_use] -mod the_world; -mod the_world_native; - +use crate::__export_foo_foo_strings_cabi; +use crate::the_world::exports::foo::foo::strings::Guest; struct MyWorld; impl Guest for MyWorld { - fn a(x: String,) { - the_world::foo::foo::strings::a(&x); + fn a(x: String) { + crate::the_world::foo::foo::strings::a(&x); } fn b() -> String { - the_world::foo::foo::strings::b() + crate::the_world::foo::foo::strings::b() } - fn c(a: String,b: String,) -> String { - the_world::foo::foo::strings::c(&a, &b) + fn c(a: String, b: String) -> String { + crate::the_world::foo::foo::strings::c(&a, &b) } } -the_world::export!(MyWorld with_types_in the_world); - -__export_foo_foo_strings_cabi!(MyWorld with_types_in strings); - +__export_foo_foo_strings_cabi!(MyWorld with_types_in crate::the_world::exports::foo::foo::strings); // the crate wit-bindgen-rt doesn't work on native #[no_mangle] @@ -49,7 +41,7 @@ pub unsafe extern "C" fn cabi_realloc( std::alloc::realloc(old_ptr, layout, new_len) }; if ptr.is_null() { - unreachable!(); + unreachable!(); } return ptr; } diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs new file mode 100644 index 000000000..bd7765079 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs @@ -0,0 +1,20 @@ +pub mod foo { + pub mod foo { + pub mod strings { + + pub fn a(a: String) { + println!("{a}"); + } + pub fn b() -> String { + let s = String::from("hello B"); + s + } + + pub fn c(a: String, b: String) -> String { + println!("guest imported: {} | {}", a, b); + let s = String::from("hello C"); + s + } + } + } +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs new file mode 100644 index 000000000..abea8b1d1 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs @@ -0,0 +1,5 @@ +mod generated; +pub mod guest_imported_fns; +mod native_imports; +mod the_world; +pub mod the_world_native; diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs new file mode 100644 index 000000000..006d69388 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs @@ -0,0 +1,66 @@ +use crate::guest_imported_fns::foo::foo::strings::*; +use std::{ptr, slice}; + +#[allow(non_snake_case)] +pub extern "C" fn fooX3AfooX2FstringsX00a(arg0: *mut u8, arg1: usize) { + unsafe { + let slice = std::slice::from_raw_parts(arg0, arg1); + let string_result = String::from_utf8(slice.to_vec()); + + let ip = match string_result { + Ok(string) => string, + Err(_) => String::from("Invalid UTF-8 sequence"), + }; + a(ip); + } +} + +#[allow(non_snake_case)] +pub extern "C" fn fooX3AfooX2FstringsX00b(arg0: *mut u8) { + let result0 = b(); + + unsafe { + let len1 = result0.len(); + let ptr1 = result0.as_ptr(); + std::mem::forget(result0); + let ptr_to_ptr1 = arg0 as *mut *const u8; + ptr::write(ptr_to_ptr1, ptr1); + + // `arg0` + 8 offset to store the length (usize, which is 8 bytes on 64-bit systems) + let ptr_to_len1 = arg0.add(8) as *mut usize; + ptr::write(ptr_to_len1, len1); + } +} + +#[allow(non_snake_case)] +pub extern "C" fn fooX3AfooX2FstringsX00c( + ptr0: *mut u8, + len0: usize, + ptr1: *mut u8, + len1: usize, + ptr2: *mut u8, +) { + unsafe { + let slice1 = slice::from_raw_parts(ptr0, len0); + let str1 = match std::str::from_utf8(slice1) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + + let slice2 = slice::from_raw_parts(ptr1, len1); + let str2 = match std::str::from_utf8(slice2) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + let result0 = c(String::from(str1.unwrap()), String::from(str2.unwrap())); + let len1 = result0.len(); + let ptr1 = result0.as_ptr(); + std::mem::forget(result0); + let ptr_to_ptr1 = ptr2 as *mut *const u8; + ptr::write(ptr_to_ptr1, ptr1); + + // `arg0` + 8 offset to store the length (usize, which is 8 bytes on 64-bit systems) + let ptr_to_len1 = ptr2.add(8) as *mut usize; + ptr::write(ptr_to_len1, len1); + } +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs new file mode 100644 index 000000000..a7987dd4e --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs @@ -0,0 +1,22 @@ +use std::slice; + +use crate::the_world_native::foo; + + + + +pub extern "C" fn fooX3AfooX2FstringsX00a(arg0: *mut u8, arg1: usize) { + let len0 = arg1; + let byte_slice: &[u8] = unsafe { slice::from_raw_parts(arg0, len0) }; + foo::foo::strings::A(std::str::from_utf8(byte_slice).unwrap().into()); +} + +extern "C" fn fooX3AfooX2FstringsX00b(arg0: &[u8]) { + todo!() + // let result0 = foo::foo::strings::B(); + // let &vec1 = result0; + // auto ptr1 = vec1.data(); + // auto len1 = vec1.size(); + // *((size_t *)(arg0 + 8)) = len1; + // *((uint8_t **)(arg0 + 0)) = ptr1; +} \ No newline at end of file diff --git a/crates/cpp/tests/native_strings/rust/src/the_world.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world.rs similarity index 84% rename from crates/cpp/tests/native_strings/rust/src/the_world.rs rename to crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world.rs index 9f53259ca..d694fc1fb 100644 --- a/crates/cpp/tests/native_strings/rust/src/the_world.rs +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world.rs @@ -12,7 +12,8 @@ pub mod foo { #[cfg(target_arch = "wasm32")] static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; - use crate::the_world_native; + + use crate::native_imports; use super::super::super::_rt; #[allow(unused_unsafe, clippy::all)] @@ -27,7 +28,7 @@ pub mod foo { #[cfg_attr(target_arch = "wasm32", link_name = "a")] fn fooX3AfooX2FstringsX00a(_: *mut u8, _: usize); } - the_world_native::fooX3AfooX2FstringsX00a(ptr0.cast_mut(), len0); + native_imports::fooX3AfooX2FstringsX00a(ptr0.cast_mut(), len0); } } #[allow(unused_unsafe, clippy::all)] @@ -42,7 +43,8 @@ pub mod foo { #[cfg_attr(target_arch = "wasm32", link_name = "b")] fn fooX3AfooX2FstringsX00b(_: *mut u8); } - fooX3AfooX2FstringsX00b(ptr0); + native_imports::fooX3AfooX2FstringsX00b(ptr0); + let l1 = *ptr0.add(0).cast::<*mut u8>(); let l2 = *ptr0.add(8).cast::(); let len3 = l2; @@ -74,7 +76,14 @@ pub mod foo { _: *mut u8, ); } - fooX3AfooX2FstringsX00c(ptr0.cast_mut(), len0, ptr1.cast_mut(), len1, ptr2); + native_imports::fooX3AfooX2FstringsX00c( + ptr0.cast_mut(), + len0, + ptr1.cast_mut(), + len1, + ptr2, + ); + let l3 = *ptr2.add(0).cast::<*mut u8>(); let l4 = *ptr2.add(8).cast::(); let len5 = l4; @@ -104,16 +113,29 @@ pub mod exports { pub unsafe fn _export_a_cabi(arg0: *mut u8, arg1: usize) { #[cfg(target_arch = "wasm32")] _rt::run_ctors_once(); - let len0 = arg1; - let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); - T::a(_rt::string_lift(bytes0)); + + unsafe { + // let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); + let bytes0 = std::slice::from_raw_parts(arg0, arg1); + T::a(_rt::string_lift(bytes0.to_vec())); + } } + + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_a(arg0: *mut u8) { + let l0 = *arg0.add(0).cast::<*mut u8>(); + let l1 = *arg0.add(8).cast::(); + _rt::cabi_dealloc(l0, l1, 1); + } + #[doc(hidden)] #[allow(non_snake_case)] pub unsafe fn _export_b_cabi() -> *mut u8 { #[cfg(target_arch = "wasm32")] _rt::run_ctors_once(); let result0 = T::b(); + let ptr1 = _RET_AREA.0.as_mut_ptr().cast::(); let vec2 = (result0.into_bytes()).into_boxed_slice(); let ptr2 = vec2.as_ptr().cast::(); @@ -123,6 +145,7 @@ pub mod exports { *ptr1.add(0).cast::<*mut u8>() = ptr2.cast_mut(); ptr1 } + #[doc(hidden)] #[allow(non_snake_case)] pub unsafe fn __post_return_b(arg0: *mut u8) { @@ -140,11 +163,14 @@ pub mod exports { ) -> *mut u8 { #[cfg(target_arch = "wasm32")] _rt::run_ctors_once(); - let len0 = arg1; - let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); - let len1 = arg3; - let bytes1 = _rt::Vec::from_raw_parts(arg2.cast(), len1, len1); - let result2 = T::c(_rt::string_lift(bytes0), _rt::string_lift(bytes1)); + //let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); + let bytes0 = std::slice::from_raw_parts(arg0, arg1); + //let bytes1 = _rt::Vec::from_raw_parts(arg2.cast(), len1, len1); + let bytes1 = std::slice::from_raw_parts(arg2, arg3); + let result2 = T::c( + _rt::string_lift(bytes0.to_vec()), + _rt::string_lift(bytes1.to_vec()), + ); let ptr3 = _RET_AREA.0.as_mut_ptr().cast::(); let vec4 = (result2.into_bytes()).into_boxed_slice(); let ptr4 = vec4.as_ptr().cast::(); @@ -169,27 +195,26 @@ pub mod exports { #[doc(hidden)] #[macro_export] macro_rules! __export_foo_foo_strings_cabi{ - ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { + ($ty:ident with_types_in $($path_to_types:tt)*) => { #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#a")] #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] pub unsafe extern "C" fn fooX3AfooX2FstringsX23a(arg0: *mut u8,arg1: usize,) { - println!("fooX3AfooX2FstringsX23a"); - $($path_to_types)*::_export_a_cabi::<$ty>(arg0, arg1) + $($path_to_types)*::_export_a_cabi::<$ty>(arg0, arg1); } #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#b")] #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] - unsafe extern "C" fn fooX3AfooX2FstringsX23b() -> *mut u8 { + pub unsafe extern "C" fn fooX3AfooX2FstringsX23b() -> *mut u8 { $($path_to_types)*::_export_b_cabi::<$ty>() } #[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 cabi_post_fooX3AfooX2FstringsX23b(arg0: *mut u8,) { + pub unsafe extern "C" fn cabi_post_fooX3AfooX2FstringsX23b(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 fooX3AfooX2FstringsX23c(arg0: *mut u8,arg1: usize,arg2: *mut u8,arg3: usize,) -> *mut u8 { + pub unsafe extern "C" fn fooX3AfooX2FstringsX23c(arg0: *mut u8,arg1: usize,arg2: *mut u8,arg3: usize,) -> *mut u8 { $($path_to_types)*::_export_c_cabi::<$ty>(arg0, arg1, arg2, arg3) } #[cfg_attr(target_arch = "wasm32", export_name = "cabi_post_foo:foo/strings#c")] @@ -197,10 +222,10 @@ pub mod exports { unsafe extern "C" fn cabi_post_fooX3AfooX2FstringsX23c(arg0: *mut u8,) { $($path_to_types)*::__post_return_c::<$ty>(arg0) } - };); + }; + } #[doc(hidden)] - pub(crate) use __export_foo_foo_strings_cabi; #[repr(align(8))] struct _RetArea([::core::mem::MaybeUninit; 16]); static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); 16]); @@ -260,8 +285,7 @@ macro_rules! __export_the_world_impl { ) } #[doc(inline)] -pub(crate) use __export_the_world_impl as export; - +//pub(crate) use __export_the_world_impl as export; #[cfg(target_arch = "wasm32")] #[link_section = "component-type:wit-bindgen:0.24.0:the-world:encoded world"] #[doc(hidden)] diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs new file mode 100644 index 000000000..2c6fdeb14 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs @@ -0,0 +1,54 @@ +pub mod exports { + pub mod foo { + pub mod foo { + pub mod strings { + use core::slice; + + use crate::generated::{ + fooX3AfooX2FstringsX23a, fooX3AfooX2FstringsX23b, fooX3AfooX2FstringsX23c, + }; + pub fn a(a: String) { + unsafe { + let ptr0 = a.as_ptr().cast_mut(); + let len0 = a.len(); + fooX3AfooX2FstringsX23a(ptr0, len0); + }; + } + + pub fn b() -> &'static str { + unsafe { + let ret = fooX3AfooX2FstringsX23b(); + let l1 = *ret.cast::<*const u8>(); + let len = *ret.add(8) as usize; + let slice = slice::from_raw_parts(l1, len); + let d = match std::str::from_utf8(slice) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + + return d.unwrap(); + } + } + + pub fn c(a: String, b: String) -> &'static str { + unsafe { + let ptr0 = a.as_ptr().cast_mut(); + let len0 = a.len(); + let ptr1 = b.as_ptr().cast_mut(); + let len1 = b.len(); + let ret = fooX3AfooX2FstringsX23c(ptr0, len0, ptr1, len1); + let l1 = *ret.cast::<*const u8>(); + let len = *ret.add(8) as usize; + let slice = slice::from_raw_parts(l1, len); + let d = match std::str::from_utf8(slice) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + + return d.unwrap(); + } + } + } + } + } +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust_app/Cargo.toml b/crates/cpp/tests/native_strings/rust-host/rust_app/Cargo.toml new file mode 100644 index 000000000..fbaf45acc --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_app/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rust_app" +version = "0.1.0" +edition = "2021" + +[dependencies] +rust_native_host_lib = {path ="../rust_native_host_lib"} \ No newline at end of file diff --git a/crates/cpp/tests/native_strings/rust-host/rust_app/src/main.rs b/crates/cpp/tests/native_strings/rust-host/rust_app/src/main.rs new file mode 100644 index 000000000..064692dce --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_app/src/main.rs @@ -0,0 +1,14 @@ +use rust_native_host_lib::the_world_native::exports::foo::foo::strings::{a, b, c}; + +fn main() { + a("hello a".into()); + { + let b = b(); + println!("{}", b); + } + + let c1 = "hello C1"; + let c2 = "hello C2"; + let c = c(c1.into(), c2.into()); + println!("{}",c); +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/Cargo.toml b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/Cargo.toml new file mode 100644 index 000000000..be4b3d854 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rust_native_host_lib" +version = "0.1.0" +edition.workspace = true + +[dependencies] diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/generated.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/generated.rs new file mode 100644 index 000000000..a70a232e5 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/generated.rs @@ -0,0 +1,47 @@ +use std::alloc::Layout; + +use crate::__export_foo_foo_strings_cabi; +use crate::the_world::exports::foo::foo::strings::Guest; +struct MyWorld; + +impl Guest for MyWorld { + fn a(x: String) { + crate::the_world::foo::foo::strings::a(&x); + } + + fn b() -> String { + crate::the_world::foo::foo::strings::b() + } + + fn c(a: String, b: String) -> String { + crate::the_world::foo::foo::strings::c(&a, &b) + } +} + +__export_foo_foo_strings_cabi!(MyWorld with_types_in crate::the_world::exports::foo::foo::strings); + +// the crate wit-bindgen-rt doesn't work on native +#[no_mangle] +pub unsafe extern "C" fn cabi_realloc( + old_ptr: *mut u8, + old_len: usize, + align: usize, + new_len: usize, +) -> *mut u8 { + let layout; + let ptr = if old_len == 0 { + if new_len == 0 { + return align as *mut u8; + } + layout = Layout::from_size_align_unchecked(new_len, align); + std::alloc::alloc(layout) + } else { + debug_assert_ne!(new_len, 0, "non-zero old_len requires non-zero new_len!"); + layout = Layout::from_size_align_unchecked(old_len, align); + std::alloc::realloc(old_ptr, layout, new_len) + }; + if ptr.is_null() { + unreachable!(); + } + return ptr; +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/guest_imported_fns.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/guest_imported_fns.rs new file mode 100644 index 000000000..bd7765079 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/guest_imported_fns.rs @@ -0,0 +1,20 @@ +pub mod foo { + pub mod foo { + pub mod strings { + + pub fn a(a: String) { + println!("{a}"); + } + pub fn b() -> String { + let s = String::from("hello B"); + s + } + + pub fn c(a: String, b: String) -> String { + println!("guest imported: {} | {}", a, b); + let s = String::from("hello C"); + s + } + } + } +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/lib.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/lib.rs new file mode 100644 index 000000000..abea8b1d1 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/lib.rs @@ -0,0 +1,5 @@ +mod generated; +pub mod guest_imported_fns; +mod native_imports; +mod the_world; +pub mod the_world_native; diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/native_imports.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/native_imports.rs new file mode 100644 index 000000000..006d69388 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/native_imports.rs @@ -0,0 +1,66 @@ +use crate::guest_imported_fns::foo::foo::strings::*; +use std::{ptr, slice}; + +#[allow(non_snake_case)] +pub extern "C" fn fooX3AfooX2FstringsX00a(arg0: *mut u8, arg1: usize) { + unsafe { + let slice = std::slice::from_raw_parts(arg0, arg1); + let string_result = String::from_utf8(slice.to_vec()); + + let ip = match string_result { + Ok(string) => string, + Err(_) => String::from("Invalid UTF-8 sequence"), + }; + a(ip); + } +} + +#[allow(non_snake_case)] +pub extern "C" fn fooX3AfooX2FstringsX00b(arg0: *mut u8) { + let result0 = b(); + + unsafe { + let len1 = result0.len(); + let ptr1 = result0.as_ptr(); + std::mem::forget(result0); + let ptr_to_ptr1 = arg0 as *mut *const u8; + ptr::write(ptr_to_ptr1, ptr1); + + // `arg0` + 8 offset to store the length (usize, which is 8 bytes on 64-bit systems) + let ptr_to_len1 = arg0.add(8) as *mut usize; + ptr::write(ptr_to_len1, len1); + } +} + +#[allow(non_snake_case)] +pub extern "C" fn fooX3AfooX2FstringsX00c( + ptr0: *mut u8, + len0: usize, + ptr1: *mut u8, + len1: usize, + ptr2: *mut u8, +) { + unsafe { + let slice1 = slice::from_raw_parts(ptr0, len0); + let str1 = match std::str::from_utf8(slice1) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + + let slice2 = slice::from_raw_parts(ptr1, len1); + let str2 = match std::str::from_utf8(slice2) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + let result0 = c(String::from(str1.unwrap()), String::from(str2.unwrap())); + let len1 = result0.len(); + let ptr1 = result0.as_ptr(); + std::mem::forget(result0); + let ptr_to_ptr1 = ptr2 as *mut *const u8; + ptr::write(ptr_to_ptr1, ptr1); + + // `arg0` + 8 offset to store the length (usize, which is 8 bytes on 64-bit systems) + let ptr_to_len1 = ptr2.add(8) as *mut usize; + ptr::write(ptr_to_len1, len1); + } +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_native_imports.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_native_imports.rs new file mode 100644 index 000000000..a7987dd4e --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_native_imports.rs @@ -0,0 +1,22 @@ +use std::slice; + +use crate::the_world_native::foo; + + + + +pub extern "C" fn fooX3AfooX2FstringsX00a(arg0: *mut u8, arg1: usize) { + let len0 = arg1; + let byte_slice: &[u8] = unsafe { slice::from_raw_parts(arg0, len0) }; + foo::foo::strings::A(std::str::from_utf8(byte_slice).unwrap().into()); +} + +extern "C" fn fooX3AfooX2FstringsX00b(arg0: &[u8]) { + todo!() + // let result0 = foo::foo::strings::B(); + // let &vec1 = result0; + // auto ptr1 = vec1.data(); + // auto len1 = vec1.size(); + // *((size_t *)(arg0 + 8)) = len1; + // *((uint8_t **)(arg0 + 0)) = ptr1; +} \ No newline at end of file diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world.rs new file mode 100644 index 000000000..d694fc1fb --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world.rs @@ -0,0 +1,306 @@ +// Generated by `wit-bindgen` 0.24.0. DO NOT EDIT! +// Options used: + +#[allow(dead_code)] +pub mod foo { + #[allow(dead_code)] + pub mod foo { + #[allow(dead_code, clippy::all)] + pub mod strings { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::__link_custom_section_describing_imports; + + use crate::native_imports; + + use super::super::super::_rt; + #[allow(unused_unsafe, clippy::all)] + pub fn a(x: &str) { + unsafe { + let vec0 = x; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + + #[link(wasm_import_module = "foo:foo/strings")] + extern "C" { + #[cfg_attr(target_arch = "wasm32", link_name = "a")] + fn fooX3AfooX2FstringsX00a(_: *mut u8, _: usize); + } + native_imports::fooX3AfooX2FstringsX00a(ptr0.cast_mut(), len0); + } + } + #[allow(unused_unsafe, clippy::all)] + pub fn b() -> _rt::String { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 16]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); + let ptr0 = ret_area.0.as_mut_ptr().cast::(); + #[link(wasm_import_module = "foo:foo/strings")] + extern "C" { + #[cfg_attr(target_arch = "wasm32", link_name = "b")] + fn fooX3AfooX2FstringsX00b(_: *mut u8); + } + native_imports::fooX3AfooX2FstringsX00b(ptr0); + + let l1 = *ptr0.add(0).cast::<*mut u8>(); + let l2 = *ptr0.add(8).cast::(); + let len3 = l2; + let bytes3 = _rt::Vec::from_raw_parts(l1.cast(), len3, len3); + _rt::string_lift(bytes3) + } + } + #[allow(unused_unsafe, clippy::all)] + pub fn c(a: &str, b: &str) -> _rt::String { + unsafe { + #[repr(align(8))] + struct RetArea([::core::mem::MaybeUninit; 16]); + let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); + let vec0 = a; + let ptr0 = vec0.as_ptr().cast::(); + let len0 = vec0.len(); + let vec1 = b; + let ptr1 = vec1.as_ptr().cast::(); + let len1 = vec1.len(); + let ptr2 = ret_area.0.as_mut_ptr().cast::(); + #[link(wasm_import_module = "foo:foo/strings")] + extern "C" { + #[cfg_attr(target_arch = "wasm32", link_name = "c")] + fn fooX3AfooX2FstringsX00c( + _: *mut u8, + _: usize, + _: *mut u8, + _: usize, + _: *mut u8, + ); + } + native_imports::fooX3AfooX2FstringsX00c( + ptr0.cast_mut(), + len0, + ptr1.cast_mut(), + len1, + ptr2, + ); + + let l3 = *ptr2.add(0).cast::<*mut u8>(); + let l4 = *ptr2.add(8).cast::(); + let len5 = l4; + let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); + _rt::string_lift(bytes5) + } + } + } + } +} +#[allow(dead_code)] +pub mod exports { + #[allow(dead_code)] + pub mod foo { + #[allow(dead_code)] + pub mod foo { + #[allow(dead_code, clippy::all)] + pub mod strings { + #[used] + #[doc(hidden)] + #[cfg(target_arch = "wasm32")] + static __FORCE_SECTION_REF: fn() = + super::super::super::super::__link_custom_section_describing_imports; + use super::super::super::super::_rt; + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_a_cabi(arg0: *mut u8, arg1: usize) { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + + unsafe { + // let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); + let bytes0 = std::slice::from_raw_parts(arg0, arg1); + T::a(_rt::string_lift(bytes0.to_vec())); + } + } + + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_a(arg0: *mut u8) { + let l0 = *arg0.add(0).cast::<*mut u8>(); + let l1 = *arg0.add(8).cast::(); + _rt::cabi_dealloc(l0, l1, 1); + } + + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_b_cabi() -> *mut u8 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + let result0 = T::b(); + + let ptr1 = _RET_AREA.0.as_mut_ptr().cast::(); + let vec2 = (result0.into_bytes()).into_boxed_slice(); + let ptr2 = vec2.as_ptr().cast::(); + let len2 = vec2.len(); + ::core::mem::forget(vec2); + *ptr1.add(8).cast::() = len2; + *ptr1.add(0).cast::<*mut u8>() = ptr2.cast_mut(); + ptr1 + } + + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_b(arg0: *mut u8) { + let l0 = *arg0.add(0).cast::<*mut u8>(); + let l1 = *arg0.add(8).cast::(); + _rt::cabi_dealloc(l0, l1, 1); + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_c_cabi( + arg0: *mut u8, + arg1: usize, + arg2: *mut u8, + arg3: usize, + ) -> *mut u8 { + #[cfg(target_arch = "wasm32")] + _rt::run_ctors_once(); + //let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); + let bytes0 = std::slice::from_raw_parts(arg0, arg1); + //let bytes1 = _rt::Vec::from_raw_parts(arg2.cast(), len1, len1); + let bytes1 = std::slice::from_raw_parts(arg2, arg3); + let result2 = T::c( + _rt::string_lift(bytes0.to_vec()), + _rt::string_lift(bytes1.to_vec()), + ); + let ptr3 = _RET_AREA.0.as_mut_ptr().cast::(); + let vec4 = (result2.into_bytes()).into_boxed_slice(); + let ptr4 = vec4.as_ptr().cast::(); + let len4 = vec4.len(); + ::core::mem::forget(vec4); + *ptr3.add(8).cast::() = len4; + *ptr3.add(0).cast::<*mut u8>() = ptr4.cast_mut(); + ptr3 + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_c(arg0: *mut u8) { + let l0 = *arg0.add(0).cast::<*mut u8>(); + let l1 = *arg0.add(8).cast::(); + _rt::cabi_dealloc(l0, l1, 1); + } + pub trait Guest { + fn a(x: _rt::String); + fn b() -> _rt::String; + fn c(a: _rt::String, b: _rt::String) -> _rt::String; + } + #[doc(hidden)] + #[macro_export] + macro_rules! __export_foo_foo_strings_cabi{ + ($ty:ident with_types_in $($path_to_types:tt)*) => { + + #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#a")] + #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] + pub unsafe extern "C" fn fooX3AfooX2FstringsX23a(arg0: *mut u8,arg1: usize,) { + $($path_to_types)*::_export_a_cabi::<$ty>(arg0, arg1); + } + #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#b")] + #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] + pub unsafe extern "C" fn fooX3AfooX2FstringsX23b() -> *mut u8 { + $($path_to_types)*::_export_b_cabi::<$ty>() + } + #[cfg_attr(target_arch = "wasm32", export_name = "cabi_post_foo:foo/strings#b")] + #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] + pub unsafe extern "C" fn cabi_post_fooX3AfooX2FstringsX23b(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)] + pub unsafe extern "C" fn fooX3AfooX2FstringsX23c(arg0: *mut u8,arg1: usize,arg2: *mut u8,arg3: usize,) -> *mut u8 { + $($path_to_types)*::_export_c_cabi::<$ty>(arg0, arg1, arg2, arg3) + } + #[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 cabi_post_fooX3AfooX2FstringsX23c(arg0: *mut u8,) { + $($path_to_types)*::__post_return_c::<$ty>(arg0) + } + }; + + } + #[doc(hidden)] + #[repr(align(8))] + struct _RetArea([::core::mem::MaybeUninit; 16]); + static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); 16]); + } + } + } +} +mod _rt { + pub use alloc_crate::string::String; + pub use alloc_crate::vec::Vec; + pub unsafe fn string_lift(bytes: Vec) -> 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() { + wit_bindgen::rt::run_ctors_once(); + } + pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) { + if size == 0 { + return; + } + let layout = alloc::Layout::from_size_align_unchecked(size, align); + alloc::dealloc(ptr as *mut u8, layout); + } + extern crate alloc as alloc_crate; + pub use alloc_crate::alloc; +} + +/// Generates `#[no_mangle]` functions to export the specified type as the +/// root implementation of all generated traits. +/// +/// For more information see the documentation of `wit_bindgen::generate!`. +/// +/// ```rust +/// # macro_rules! export{ ($($t:tt)*) => (); } +/// # trait Guest {} +/// struct MyType; +/// +/// impl Guest for MyType { +/// // ... +/// } +/// +/// export!(MyType); +/// ``` +#[allow(unused_macros)] +#[doc(hidden)] + +macro_rules! __export_the_world_impl { + ($ty:ident) => (self::export!($ty with_types_in self);); + ($ty:ident with_types_in $($path_to_types_root:tt)*) => ( + $($path_to_types_root)*::exports::foo::foo::strings::__export_foo_foo_strings_cabi!($ty with_types_in $($path_to_types_root)*::exports::foo::foo::strings); + ) +} +#[doc(inline)] +//pub(crate) use __export_the_world_impl as export; +#[cfg(target_arch = "wasm32")] +#[link_section = "component-type:wit-bindgen:0.24.0:the-world:encoded world"] +#[doc(hidden)] +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 286] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\x9e\x01\x01A\x02\x01\ +A\x04\x01B\x06\x01@\x01\x01xs\x01\0\x04\0\x01a\x01\0\x01@\0\0s\x04\0\x01b\x01\x01\ +\x01@\x02\x01as\x01bs\0s\x04\0\x01c\x01\x02\x03\x01\x0ffoo:foo/strings\x05\0\x01\ +B\x06\x01@\x01\x01xs\x01\0\x04\0\x01a\x01\0\x01@\0\0s\x04\0\x01b\x01\x01\x01@\x02\ +\x01as\x01bs\0s\x04\0\x01c\x01\x02\x04\x01\x0ffoo:foo/strings\x05\x01\x04\x01\x11\ +foo:foo/the-world\x04\0\x0b\x0f\x01\0\x09the-world\x03\0\0\0G\x09producers\x01\x0c\ +processed-by\x02\x0dwit-component\x070.207.0\x10wit-bindgen-rust\x060.24.0"; + +#[inline(never)] +#[doc(hidden)] +#[cfg(target_arch = "wasm32")] +pub fn __link_custom_section_describing_imports() { + wit_bindgen::rt::maybe_link_cabi_realloc(); +} diff --git a/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world_native.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world_native.rs new file mode 100644 index 000000000..2c6fdeb14 --- /dev/null +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/the_world_native.rs @@ -0,0 +1,54 @@ +pub mod exports { + pub mod foo { + pub mod foo { + pub mod strings { + use core::slice; + + use crate::generated::{ + fooX3AfooX2FstringsX23a, fooX3AfooX2FstringsX23b, fooX3AfooX2FstringsX23c, + }; + pub fn a(a: String) { + unsafe { + let ptr0 = a.as_ptr().cast_mut(); + let len0 = a.len(); + fooX3AfooX2FstringsX23a(ptr0, len0); + }; + } + + pub fn b() -> &'static str { + unsafe { + let ret = fooX3AfooX2FstringsX23b(); + let l1 = *ret.cast::<*const u8>(); + let len = *ret.add(8) as usize; + let slice = slice::from_raw_parts(l1, len); + let d = match std::str::from_utf8(slice) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + + return d.unwrap(); + } + } + + pub fn c(a: String, b: String) -> &'static str { + unsafe { + let ptr0 = a.as_ptr().cast_mut(); + let len0 = a.len(); + let ptr1 = b.as_ptr().cast_mut(); + let len1 = b.len(); + let ret = fooX3AfooX2FstringsX23c(ptr0, len0, ptr1, len1); + let l1 = *ret.cast::<*const u8>(); + let len = *ret.add(8) as usize; + let slice = slice::from_raw_parts(l1, len); + let d = match std::str::from_utf8(slice) { + Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful + Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 + }; + + return d.unwrap(); + } + } + } + } + } +} diff --git a/crates/cpp/tests/native_strings/rust/Cargo.lock b/crates/cpp/tests/native_strings/rust/Cargo.lock deleted file mode 100644 index d85cfd92e..000000000 --- a/crates/cpp/tests/native_strings/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "strings" -version = "0.1.0" From 9e5a7c36a9dae15a2ada81aed1ebb60f5d740ddc Mon Sep 17 00:00:00 2001 From: Pradeep Kumar K J Date: Wed, 5 Jun 2024 18:10:09 +0530 Subject: [PATCH 7/8] remove redundant code Signed-off-by: Pradeep Kumar K J --- .../rust-host/rust-host/Cargo.toml | 6 - .../rust-host/rust-host/src/generated.rs | 47 --- .../rust-host/src/guest_imported_fns.rs | 20 -- .../rust-host/rust-host/src/lib.rs | 5 - .../rust-host/rust-host/src/native_imports.rs | 66 ---- .../rust-host/src/the_native_imports.rs | 22 -- .../rust-host/rust-host/src/the_world.rs | 306 ------------------ .../rust-host/src/the_world_native.rs | 54 ---- 8 files changed, 526 deletions(-) delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/Cargo.toml delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/generated.rs delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world.rs delete mode 100644 crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/Cargo.toml b/crates/cpp/tests/native_strings/rust-host/rust-host/Cargo.toml deleted file mode 100644 index 636ed4f5b..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "strings" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/generated.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/generated.rs deleted file mode 100644 index a70a232e5..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/src/generated.rs +++ /dev/null @@ -1,47 +0,0 @@ -use std::alloc::Layout; - -use crate::__export_foo_foo_strings_cabi; -use crate::the_world::exports::foo::foo::strings::Guest; -struct MyWorld; - -impl Guest for MyWorld { - fn a(x: String) { - crate::the_world::foo::foo::strings::a(&x); - } - - fn b() -> String { - crate::the_world::foo::foo::strings::b() - } - - fn c(a: String, b: String) -> String { - crate::the_world::foo::foo::strings::c(&a, &b) - } -} - -__export_foo_foo_strings_cabi!(MyWorld with_types_in crate::the_world::exports::foo::foo::strings); - -// the crate wit-bindgen-rt doesn't work on native -#[no_mangle] -pub unsafe extern "C" fn cabi_realloc( - old_ptr: *mut u8, - old_len: usize, - align: usize, - new_len: usize, -) -> *mut u8 { - let layout; - let ptr = if old_len == 0 { - if new_len == 0 { - return align as *mut u8; - } - layout = Layout::from_size_align_unchecked(new_len, align); - std::alloc::alloc(layout) - } else { - debug_assert_ne!(new_len, 0, "non-zero old_len requires non-zero new_len!"); - layout = Layout::from_size_align_unchecked(old_len, align); - std::alloc::realloc(old_ptr, layout, new_len) - }; - if ptr.is_null() { - unreachable!(); - } - return ptr; -} diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs deleted file mode 100644 index bd7765079..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/src/guest_imported_fns.rs +++ /dev/null @@ -1,20 +0,0 @@ -pub mod foo { - pub mod foo { - pub mod strings { - - pub fn a(a: String) { - println!("{a}"); - } - pub fn b() -> String { - let s = String::from("hello B"); - s - } - - pub fn c(a: String, b: String) -> String { - println!("guest imported: {} | {}", a, b); - let s = String::from("hello C"); - s - } - } - } -} diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs deleted file mode 100644 index abea8b1d1..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod generated; -pub mod guest_imported_fns; -mod native_imports; -mod the_world; -pub mod the_world_native; diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs deleted file mode 100644 index 006d69388..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/src/native_imports.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::guest_imported_fns::foo::foo::strings::*; -use std::{ptr, slice}; - -#[allow(non_snake_case)] -pub extern "C" fn fooX3AfooX2FstringsX00a(arg0: *mut u8, arg1: usize) { - unsafe { - let slice = std::slice::from_raw_parts(arg0, arg1); - let string_result = String::from_utf8(slice.to_vec()); - - let ip = match string_result { - Ok(string) => string, - Err(_) => String::from("Invalid UTF-8 sequence"), - }; - a(ip); - } -} - -#[allow(non_snake_case)] -pub extern "C" fn fooX3AfooX2FstringsX00b(arg0: *mut u8) { - let result0 = b(); - - unsafe { - let len1 = result0.len(); - let ptr1 = result0.as_ptr(); - std::mem::forget(result0); - let ptr_to_ptr1 = arg0 as *mut *const u8; - ptr::write(ptr_to_ptr1, ptr1); - - // `arg0` + 8 offset to store the length (usize, which is 8 bytes on 64-bit systems) - let ptr_to_len1 = arg0.add(8) as *mut usize; - ptr::write(ptr_to_len1, len1); - } -} - -#[allow(non_snake_case)] -pub extern "C" fn fooX3AfooX2FstringsX00c( - ptr0: *mut u8, - len0: usize, - ptr1: *mut u8, - len1: usize, - ptr2: *mut u8, -) { - unsafe { - let slice1 = slice::from_raw_parts(ptr0, len0); - let str1 = match std::str::from_utf8(slice1) { - Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful - Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 - }; - - let slice2 = slice::from_raw_parts(ptr1, len1); - let str2 = match std::str::from_utf8(slice2) { - Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful - Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 - }; - let result0 = c(String::from(str1.unwrap()), String::from(str2.unwrap())); - let len1 = result0.len(); - let ptr1 = result0.as_ptr(); - std::mem::forget(result0); - let ptr_to_ptr1 = ptr2 as *mut *const u8; - ptr::write(ptr_to_ptr1, ptr1); - - // `arg0` + 8 offset to store the length (usize, which is 8 bytes on 64-bit systems) - let ptr_to_len1 = ptr2.add(8) as *mut usize; - ptr::write(ptr_to_len1, len1); - } -} diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs deleted file mode 100644 index a7987dd4e..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_native_imports.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::slice; - -use crate::the_world_native::foo; - - - - -pub extern "C" fn fooX3AfooX2FstringsX00a(arg0: *mut u8, arg1: usize) { - let len0 = arg1; - let byte_slice: &[u8] = unsafe { slice::from_raw_parts(arg0, len0) }; - foo::foo::strings::A(std::str::from_utf8(byte_slice).unwrap().into()); -} - -extern "C" fn fooX3AfooX2FstringsX00b(arg0: &[u8]) { - todo!() - // let result0 = foo::foo::strings::B(); - // let &vec1 = result0; - // auto ptr1 = vec1.data(); - // auto len1 = vec1.size(); - // *((size_t *)(arg0 + 8)) = len1; - // *((uint8_t **)(arg0 + 0)) = ptr1; -} \ No newline at end of file diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world.rs deleted file mode 100644 index d694fc1fb..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world.rs +++ /dev/null @@ -1,306 +0,0 @@ -// Generated by `wit-bindgen` 0.24.0. DO NOT EDIT! -// Options used: - -#[allow(dead_code)] -pub mod foo { - #[allow(dead_code)] - pub mod foo { - #[allow(dead_code, clippy::all)] - pub mod strings { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - - use crate::native_imports; - - use super::super::super::_rt; - #[allow(unused_unsafe, clippy::all)] - pub fn a(x: &str) { - unsafe { - let vec0 = x; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - - #[link(wasm_import_module = "foo:foo/strings")] - extern "C" { - #[cfg_attr(target_arch = "wasm32", link_name = "a")] - fn fooX3AfooX2FstringsX00a(_: *mut u8, _: usize); - } - native_imports::fooX3AfooX2FstringsX00a(ptr0.cast_mut(), len0); - } - } - #[allow(unused_unsafe, clippy::all)] - pub fn b() -> _rt::String { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[link(wasm_import_module = "foo:foo/strings")] - extern "C" { - #[cfg_attr(target_arch = "wasm32", link_name = "b")] - fn fooX3AfooX2FstringsX00b(_: *mut u8); - } - native_imports::fooX3AfooX2FstringsX00b(ptr0); - - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(8).cast::(); - let len3 = l2; - let bytes3 = _rt::Vec::from_raw_parts(l1.cast(), len3, len3); - _rt::string_lift(bytes3) - } - } - #[allow(unused_unsafe, clippy::all)] - pub fn c(a: &str, b: &str) -> _rt::String { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let vec0 = a; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let vec1 = b; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let ptr2 = ret_area.0.as_mut_ptr().cast::(); - #[link(wasm_import_module = "foo:foo/strings")] - extern "C" { - #[cfg_attr(target_arch = "wasm32", link_name = "c")] - fn fooX3AfooX2FstringsX00c( - _: *mut u8, - _: usize, - _: *mut u8, - _: usize, - _: *mut u8, - ); - } - native_imports::fooX3AfooX2FstringsX00c( - ptr0.cast_mut(), - len0, - ptr1.cast_mut(), - len1, - ptr2, - ); - - let l3 = *ptr2.add(0).cast::<*mut u8>(); - let l4 = *ptr2.add(8).cast::(); - let len5 = l4; - let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); - _rt::string_lift(bytes5) - } - } - } - } -} -#[allow(dead_code)] -pub mod exports { - #[allow(dead_code)] - pub mod foo { - #[allow(dead_code)] - pub mod foo { - #[allow(dead_code, clippy::all)] - pub mod strings { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::super::__link_custom_section_describing_imports; - use super::super::super::super::_rt; - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn _export_a_cabi(arg0: *mut u8, arg1: usize) { - #[cfg(target_arch = "wasm32")] - _rt::run_ctors_once(); - - unsafe { - // let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); - let bytes0 = std::slice::from_raw_parts(arg0, arg1); - T::a(_rt::string_lift(bytes0.to_vec())); - } - } - - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn __post_return_a(arg0: *mut u8) { - let l0 = *arg0.add(0).cast::<*mut u8>(); - let l1 = *arg0.add(8).cast::(); - _rt::cabi_dealloc(l0, l1, 1); - } - - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn _export_b_cabi() -> *mut u8 { - #[cfg(target_arch = "wasm32")] - _rt::run_ctors_once(); - let result0 = T::b(); - - let ptr1 = _RET_AREA.0.as_mut_ptr().cast::(); - let vec2 = (result0.into_bytes()).into_boxed_slice(); - let ptr2 = vec2.as_ptr().cast::(); - let len2 = vec2.len(); - ::core::mem::forget(vec2); - *ptr1.add(8).cast::() = len2; - *ptr1.add(0).cast::<*mut u8>() = ptr2.cast_mut(); - ptr1 - } - - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn __post_return_b(arg0: *mut u8) { - let l0 = *arg0.add(0).cast::<*mut u8>(); - let l1 = *arg0.add(8).cast::(); - _rt::cabi_dealloc(l0, l1, 1); - } - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn _export_c_cabi( - arg0: *mut u8, - arg1: usize, - arg2: *mut u8, - arg3: usize, - ) -> *mut u8 { - #[cfg(target_arch = "wasm32")] - _rt::run_ctors_once(); - //let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); - let bytes0 = std::slice::from_raw_parts(arg0, arg1); - //let bytes1 = _rt::Vec::from_raw_parts(arg2.cast(), len1, len1); - let bytes1 = std::slice::from_raw_parts(arg2, arg3); - let result2 = T::c( - _rt::string_lift(bytes0.to_vec()), - _rt::string_lift(bytes1.to_vec()), - ); - let ptr3 = _RET_AREA.0.as_mut_ptr().cast::(); - let vec4 = (result2.into_bytes()).into_boxed_slice(); - let ptr4 = vec4.as_ptr().cast::(); - let len4 = vec4.len(); - ::core::mem::forget(vec4); - *ptr3.add(8).cast::() = len4; - *ptr3.add(0).cast::<*mut u8>() = ptr4.cast_mut(); - ptr3 - } - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn __post_return_c(arg0: *mut u8) { - let l0 = *arg0.add(0).cast::<*mut u8>(); - let l1 = *arg0.add(8).cast::(); - _rt::cabi_dealloc(l0, l1, 1); - } - pub trait Guest { - fn a(x: _rt::String); - fn b() -> _rt::String; - fn c(a: _rt::String, b: _rt::String) -> _rt::String; - } - #[doc(hidden)] - #[macro_export] - macro_rules! __export_foo_foo_strings_cabi{ - ($ty:ident with_types_in $($path_to_types:tt)*) => { - - #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#a")] - #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] - pub unsafe extern "C" fn fooX3AfooX2FstringsX23a(arg0: *mut u8,arg1: usize,) { - $($path_to_types)*::_export_a_cabi::<$ty>(arg0, arg1); - } - #[cfg_attr(target_arch = "wasm32", export_name = "foo:foo/strings#b")] - #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] - pub unsafe extern "C" fn fooX3AfooX2FstringsX23b() -> *mut u8 { - $($path_to_types)*::_export_b_cabi::<$ty>() - } - #[cfg_attr(target_arch = "wasm32", export_name = "cabi_post_foo:foo/strings#b")] - #[cfg_attr(not(target_arch = "wasm32"), no_mangle)] - pub unsafe extern "C" fn cabi_post_fooX3AfooX2FstringsX23b(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)] - pub unsafe extern "C" fn fooX3AfooX2FstringsX23c(arg0: *mut u8,arg1: usize,arg2: *mut u8,arg3: usize,) -> *mut u8 { - $($path_to_types)*::_export_c_cabi::<$ty>(arg0, arg1, arg2, arg3) - } - #[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 cabi_post_fooX3AfooX2FstringsX23c(arg0: *mut u8,) { - $($path_to_types)*::__post_return_c::<$ty>(arg0) - } - }; - - } - #[doc(hidden)] - #[repr(align(8))] - struct _RetArea([::core::mem::MaybeUninit; 16]); - static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); 16]); - } - } - } -} -mod _rt { - pub use alloc_crate::string::String; - pub use alloc_crate::vec::Vec; - pub unsafe fn string_lift(bytes: Vec) -> 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() { - wit_bindgen::rt::run_ctors_once(); - } - pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) { - if size == 0 { - return; - } - let layout = alloc::Layout::from_size_align_unchecked(size, align); - alloc::dealloc(ptr as *mut u8, layout); - } - extern crate alloc as alloc_crate; - pub use alloc_crate::alloc; -} - -/// Generates `#[no_mangle]` functions to export the specified type as the -/// root implementation of all generated traits. -/// -/// For more information see the documentation of `wit_bindgen::generate!`. -/// -/// ```rust -/// # macro_rules! export{ ($($t:tt)*) => (); } -/// # trait Guest {} -/// struct MyType; -/// -/// impl Guest for MyType { -/// // ... -/// } -/// -/// export!(MyType); -/// ``` -#[allow(unused_macros)] -#[doc(hidden)] - -macro_rules! __export_the_world_impl { - ($ty:ident) => (self::export!($ty with_types_in self);); - ($ty:ident with_types_in $($path_to_types_root:tt)*) => ( - $($path_to_types_root)*::exports::foo::foo::strings::__export_foo_foo_strings_cabi!($ty with_types_in $($path_to_types_root)*::exports::foo::foo::strings); - ) -} -#[doc(inline)] -//pub(crate) use __export_the_world_impl as export; -#[cfg(target_arch = "wasm32")] -#[link_section = "component-type:wit-bindgen:0.24.0:the-world:encoded world"] -#[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 286] = *b"\ -\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\x9e\x01\x01A\x02\x01\ -A\x04\x01B\x06\x01@\x01\x01xs\x01\0\x04\0\x01a\x01\0\x01@\0\0s\x04\0\x01b\x01\x01\ -\x01@\x02\x01as\x01bs\0s\x04\0\x01c\x01\x02\x03\x01\x0ffoo:foo/strings\x05\0\x01\ -B\x06\x01@\x01\x01xs\x01\0\x04\0\x01a\x01\0\x01@\0\0s\x04\0\x01b\x01\x01\x01@\x02\ -\x01as\x01bs\0s\x04\0\x01c\x01\x02\x04\x01\x0ffoo:foo/strings\x05\x01\x04\x01\x11\ -foo:foo/the-world\x04\0\x0b\x0f\x01\0\x09the-world\x03\0\0\0G\x09producers\x01\x0c\ -processed-by\x02\x0dwit-component\x070.207.0\x10wit-bindgen-rust\x060.24.0"; - -#[inline(never)] -#[doc(hidden)] -#[cfg(target_arch = "wasm32")] -pub fn __link_custom_section_describing_imports() { - wit_bindgen::rt::maybe_link_cabi_realloc(); -} diff --git a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs b/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs deleted file mode 100644 index 2c6fdeb14..000000000 --- a/crates/cpp/tests/native_strings/rust-host/rust-host/src/the_world_native.rs +++ /dev/null @@ -1,54 +0,0 @@ -pub mod exports { - pub mod foo { - pub mod foo { - pub mod strings { - use core::slice; - - use crate::generated::{ - fooX3AfooX2FstringsX23a, fooX3AfooX2FstringsX23b, fooX3AfooX2FstringsX23c, - }; - pub fn a(a: String) { - unsafe { - let ptr0 = a.as_ptr().cast_mut(); - let len0 = a.len(); - fooX3AfooX2FstringsX23a(ptr0, len0); - }; - } - - pub fn b() -> &'static str { - unsafe { - let ret = fooX3AfooX2FstringsX23b(); - let l1 = *ret.cast::<*const u8>(); - let len = *ret.add(8) as usize; - let slice = slice::from_raw_parts(l1, len); - let d = match std::str::from_utf8(slice) { - Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful - Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 - }; - - return d.unwrap(); - } - } - - pub fn c(a: String, b: String) -> &'static str { - unsafe { - let ptr0 = a.as_ptr().cast_mut(); - let len0 = a.len(); - let ptr1 = b.as_ptr().cast_mut(); - let len1 = b.len(); - let ret = fooX3AfooX2FstringsX23c(ptr0, len0, ptr1, len1); - let l1 = *ret.cast::<*const u8>(); - let len = *ret.add(8) as usize; - let slice = slice::from_raw_parts(l1, len); - let d = match std::str::from_utf8(slice) { - Ok(utf8_str) => Ok(utf8_str), // Convert to String if successful - Err(e) => Err(e), // Return None if the byte slice is not valid UTF-8 - }; - - return d.unwrap(); - } - } - } - } - } -} From 97565c424681e114bc2531d685f4cfa1cdeb445f Mon Sep 17 00:00:00 2001 From: Pradeep Kumar K J Date: Wed, 5 Jun 2024 18:13:52 +0530 Subject: [PATCH 8/8] Update readme Signed-off-by: Pradeep Kumar K J --- crates/cpp/tests/native_strings/README.md | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/crates/cpp/tests/native_strings/README.md b/crates/cpp/tests/native_strings/README.md index 542356ab0..4a7e6add8 100644 --- a/crates/cpp/tests/native_strings/README.md +++ b/crates/cpp/tests/native_strings/README.md @@ -23,3 +23,28 @@ guest_1->exports::foo::foo::strings::A(a){native host export call}->fooX3AfooX2F -> exports::foo::foo::strings::A(wit::string &&x){guest_1 export implementation} -> foo::foo::strings::A(std::string_view x){guest import call}->fooX3AfooX2FstringsX00a() {native host import binding(lowering)} -> foo::foo::strings::A(std::string_view x) { guest import functions implementation} + +# Building the rust native string app +Here is the rust based native string application source code tree +``` +├── rust_app (Application that uses the native rust code) +│ ├── Cargo.toml +│ └── src +│ └── main.rs +└── rust_native_host_lib (Rust native rust code as library) + ├── Cargo.toml + └── src + ├── generated.rs + ├── guest_imported_fns.rs + ├── lib.rs + ├── native_imports.rs + ├── the_native_imports.rs + ├── the_world_native.rs + └── the_world.rs +``` +to build and run the application run the command + +```shell +cargo run -p rust_app` +``` +