|
| 1 | +# Type mapping |
| 2 | + |
| 3 | +| Code | Environment | |
| 4 | +| --- | --- | |
| 5 | +| G-- | guest side | |
| 6 | +| H-- | host side | |
| 7 | +| -I- | guest-import (guest calls) | |
| 8 | +| -E- | guest-export (host calls) | |
| 9 | +| --A | argument | |
| 10 | +| --R | result | |
| 11 | +| --S | in struct | |
| 12 | + |
| 13 | +| mode | | |
| 14 | +| --- | --- | |
| 15 | +| v | passed by value | |
| 16 | +| t | owernership transferred | |
| 17 | +| p | cabi_post_ cleans up | |
| 18 | + |
| 19 | +| API | | | ABI | | |
| 20 | +| --- | --- | --- | --- | --- | |
| 21 | +| 🕸 | old | | 📘 | canonical | |
| 22 | +| 💎 | new | | 🪞 | symmetric | |
| 23 | + |
| 24 | +| Code | mode | WIT Type | Rust type | C++ Type | Lower | Reason | |
| 25 | +| --- | --- | --- | --- | --- | --- | --- | |
| 26 | +| GIA | v | string | &str[^1] | string_view (17) | addr, len | | |
| 27 | +| | | list | &[T] | wit::span [^5] | addr, len | | |
| 28 | +| | | tuple | (...) | std::tuple | 0, 1, ...| | |
| 29 | +| | | tuple<string, list> | (&str, &[T]) | std::tuple<...> | a,l,a,l | |
| 30 | +| | | record{string, list} | &T | T const& | a,l,a,l | |
| 31 | +| | | large-struct (>16 args) | &T | T const& | &t | |
| 32 | +| | | result<string,list> | Result<&str, &[]> | std::expected<string_view, span> | d,a,l | |
| 33 | +| | | option\<string> | Option\<&str> | optional<string_view> const& | d,a,l| |
| 34 | +| | | list\<resrc> | &[\&Resrc]? | vector<string_view> const& | a,l| |
| 35 | +| GIR | t | string | String | wit::string[^2] | &(addr, len) [^8] | | |
| 36 | +| | | list | Vec | wit::vector | &(a,l) | |
| 37 | +| | | result<string,list> | Result<String, Vec> | std::expected<wit::string, wit::vector> | &(d,a,l) | |
| 38 | +| GEA | t | string | String | 🕸 wit::string&& | addr, len | |
| 39 | +| | | | | 💎 string_view | | |
| 40 | +| | | result<string,list> | Result<String, Vec> | 🕸 std::expected<wit::string, wit::vector>&& | d,a,l | |
| 41 | +| | | | | 💎 std::expected<string_view, wit::span> | | |
| 42 | +| GER | p | string | String | wit::string (or std?) | 📘 -> &(a,l) cabi_post_N:P/I#F [^7] | |
| 43 | +| | | | | | 🪞 &(a,l) | |
| 44 | +| | | result<string,list> | Result<String, Vec> | std::expected<wit::string, wit::vector> | 📘 -> &(d,a,l) cabi_post | |
| 45 | +| --S | ? | string | String | wit::string | addr, len | |
| 46 | +| HIA | v | string | | string_view | a,l | |
| 47 | +| HIR | t | string | | wit::string[^3] | &(a,l) | |
| 48 | +| HEA | t | string | | 🕸 wit::string[^4] | a,l | |
| 49 | +| | | | | 💎 string_view [^6] | | |
| 50 | +| HER | p | string | | 🕸 wit::guest_owned<string_view> | 📘 -> &(a,l) | |
| 51 | +| | | | | 💎 wit::string [^6] | 🪞 &(a,l) | |
| 52 | + |
| 53 | +[^1]: The host never frees memory (is never passed ownership)! |
| 54 | + |
| 55 | +[^2]: A wit::string is identical to the canonical representation, so it can be part of structures. On the guest a wit::string owns the memory and frees it after use. |
| 56 | +On the host a wit::string can be constructed(=allocated) with an exec_env argument. Thus, without an exec_env a wit::string on the host is inaccessible. |
| 57 | +Complex (non-POD) struct elements on the host will need exec_env to decode or construct. |
| 58 | + |
| 59 | +[^3]: A wit::string requires exec_env inside the host implementation. ~~Perhaps a flexible type (either std::string or wit::string would be possible), or make this a generation option?~~ std::string requires a copy, wit::string requires passing exec_env to the method (which is necessary for methods anyway). |
| 60 | + |
| 61 | +[^4]: A host side wit::string doesn't own the data (not free in dtor), thus no move semantics. |
| 62 | + |
| 63 | +[^5]: std::span requires C++-20, this alias should give minimal functionality with older compiler targets. |
| 64 | + |
| 65 | +[^6]: Not implemented, for now symmetric is priority |
| 66 | + |
| 67 | +[^7]: Here the callee (guest) allocates the memory for the set on its side |
| 68 | + |
| 69 | +[^8]: Caller passes address of the return object as argument |
| 70 | + |
| 71 | +## [Symmetric ABI](https://github.com/WebAssembly/component-model/issues/386) |
| 72 | + |
| 73 | +The idea is to directly connect (link) components to each other. |
| 74 | + |
| 75 | +Thus imported and exported functions and resources need to be compatible |
| 76 | +at the ABI level. |
| 77 | + |
| 78 | +For now for functions the guest import convention is used in both directions: |
| 79 | + |
| 80 | +- The imported function ABI is used with the following properties |
| 81 | + |
| 82 | + - (unchanged) List and string arguments are passed as Views, no free |
| 83 | + required, lifetime is constrained until the end of the call |
| 84 | + |
| 85 | + - (unchanged) Owned resources in arguments or results pass ownership |
| 86 | + to the callee |
| 87 | + |
| 88 | + - (unchanged) If there are too many (>1) flat results, a local |
| 89 | + uninitialized ret_area is passed via the last argument |
| 90 | + |
| 91 | + - (unchanged) Returned objects are owned. |
| 92 | + For functional safety, i.e. avoiding all |
| 93 | + allocations in the hot path, the hope is with [#385](https://github.com/WebAssembly/component-model/issues/385). |
| 94 | + |
| 95 | +- The imported resource ABI is used also for exporting |
| 96 | + with one modification: |
| 97 | + |
| 98 | + Resource IDs become usize, so you can optimize the resource table away. |
0 commit comments