-
Couldn't load subscription status.
- Fork 3
separate guest import and export code #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
95cda46
e7d2508
de08afb
eb016b7
9094986
a590c75
9e5a7c3
97565c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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` | ||
| ``` | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #include "./the_world_cpp_native.h" | ||
| #include <iostream> | ||
|
|
||
| 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; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. adding trailing whitespace? |
||
| 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<std::string_view> exports::foo::foo::strings::B() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fear these targets don't make much sense for the guest directory |
||
| LD_LIBRARY_PATH=. ./app-strings | ||
|
|
||
| valgrind: | ||
| LD_LIBRARY_PATH=. valgrind ./app-strings | ||
|
|
||
| w2c2_guest.c: guest_release.wasm | ||
| w2c2 $^ $@ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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()); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| [package] | ||
| name = "rust_app" | ||
| version = "0.1.0" | ||
| edition = "2021" | ||
|
|
||
| [dependencies] | ||
| rust_native_host_lib = {path ="../rust_native_host_lib"} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| [package] | ||
| name = "rust_native_host_lib" | ||
| version = "0.1.0" | ||
| edition.workspace = true | ||
|
|
||
| [dependencies] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| mod generated; | ||
| pub mod guest_imported_fns; | ||
| mod native_imports; | ||
| mod the_world; | ||
| pub mod the_world_native; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for creating this!