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 54cdcdf09..55413602b 100644 --- a/crates/cpp/tests/native_strings/Makefile +++ b/crates/cpp/tests/native_strings/Makefile @@ -1,30 +1,36 @@ -CXXFLAGS=-g -O0 -I../../helper-types +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: the_world.pie.o guest.pie.o - $(CXX) $(CXXFLAGS) -shared -o $@ $^ -Wl,--version-script=guest.lds +libstrings.so: + cd guest && make $@ -%.pie.o: %.cpp - $(CXX) $(CXXFLAGS) -fPIE -o $@ -c $^ +cpp-app-strings: ./cpp_host/the_world_native.o main.o ./cpp_host/guest_imported_fns.o + $(CXX) $(CXXFLAGS) -o $@ $^ -g -L./guest -lstrings -app-strings: the_world_native.o main.o - $(CXX) $(CXXFLAGS) -o $@ $^ -L. -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 $@ 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_1.cpp /opt/wasi-sdk/bin/clang++ -o $@ $^ $(CXXFLAGS) -guest_release.wasm: the_world.cpp guest.cpp +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 new file mode 100644 index 000000000..4a7e6add8 --- /dev/null +++ b/crates/cpp/tests/native_strings/README.md @@ -0,0 +1,50 @@ +# Native string example + +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 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) + +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 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` +``` + 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..4f059305b --- /dev/null +++ b/crates/cpp/tests/native_strings/cpp_host/Makefile @@ -0,0 +1,14 @@ +CXXFLAGS=-g -O0 -I../../../helper-types --std=c++17 +WIT_BINDGEN=../../../../target/debug/wit-bindgen + +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/cpp_host/guest_imported_fns.cpp b/crates/cpp/tests/native_strings/cpp_host/guest_imported_fns.cpp new file mode 100644 index 000000000..179cff845 --- /dev/null +++ b/crates/cpp/tests/native_strings/cpp_host/guest_imported_fns.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/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 96% rename from crates/cpp/tests/native_strings/the_world_native.cpp rename to crates/cpp/tests/native_strings/cpp_host/the_world_native.cpp index 2ba8a4083..66e35da68 100644 --- a/crates/cpp/tests/native_strings/the_world_native.cpp +++ b/crates/cpp/tests/native_strings/cpp_host/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)); @@ -44,10 +44,10 @@ 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(); + auto len0 = vec0.size(); fooX3AfooX2FstringsX23a(ptr0, len0); } wit::guest_owned exports::foo::foo::strings::B() { 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.cpp b/crates/cpp/tests/native_strings/guest/guest.cpp similarity index 67% rename from crates/cpp/tests/native_strings/guest.cpp rename to crates/cpp/tests/native_strings/guest/guest.cpp index 90fa6258d..6d2938f1a 100644 --- a/crates/cpp/tests/native_strings/guest.cpp +++ b/crates/cpp/tests/native_strings/guest/guest.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.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 97% rename from crates/cpp/tests/native_strings/the_world.cpp rename to crates/cpp/tests/native_strings/guest/the_world.cpp index 9ab7b9c5c..f09af0793 100644 --- a/crates/cpp/tests/native_strings/the_world.cpp +++ b/crates/cpp/tests/native_strings/guest/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()); @@ -63,9 +63,8 @@ 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) { - auto len0 = arg1; - +fooX3AfooX2FstringsX23a(uint8_t *arg0, size_t 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_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/main.cpp b/crates/cpp/tests/native_strings/main.cpp index 0f86198e5..64b55bb4c 100644 --- a/crates/cpp/tests/native_strings/main.cpp +++ b/crates/cpp/tests/native_strings/main.cpp @@ -1,20 +1,7 @@ -#include "the_world_cpp_native.h" +#include "./cpp_host/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-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/src/lib.rs b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/generated.rs similarity index 64% rename from crates/cpp/tests/native_strings/rust/src/lib.rs rename to crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/generated.rs index 0fb041a18..a70a232e5 100644 --- a/crates/cpp/tests/native_strings/rust/src/lib.rs +++ b/crates/cpp/tests/native_strings/rust-host/rust_native_host_lib/src/generated.rs @@ -1,26 +1,24 @@ use std::alloc::Layout; -use the_world::exports::foo::foo::strings::Guest; - -mod the_world; - +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 crate::the_world::exports::foo::foo::strings); // the crate wit-bindgen-rt doesn't work on native #[no_mangle] @@ -43,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_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" diff --git a/crates/cpp/tests/native_strings/rust/Cargo.toml b/crates/cpp/tests/native_strings/rust/Cargo.toml deleted file mode 100644 index 54920869d..000000000 --- a/crates/cpp/tests/native_strings/rust/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[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/the_world.rs b/crates/cpp/tests/native_strings/rust/src/the_world.rs deleted file mode 100644 index 5c05d404b..000000000 --- a/crates/cpp/tests/native_strings/rust/src/the_world.rs +++ /dev/null @@ -1,264 +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 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, ); - } - 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{ - ($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,) { - $($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 { - $($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,) { - $($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 { - $($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)] - 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) - } - } - - #[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(); -} -