Add basic GuestString support to wiggle (#13)

* Add basic GuestString support to wiggle

This commit adds basic `GuestString` support to `wiggle`. `GuestString`
is a wrapper around `GuestArray<'_, u8>` array type which itself can
be made into either an owned (cloned) Rust `String` or borrowed as
a reference `&str`. In both cases, `GuestString` ensures that the
underlying bytes are valid Unicode code units, throwing a `InvalidUtf8`
error if not.

This commit adds support *only* for passing in strings as arguments
in WASI. Marshalling of the return arg has not yet been implemented.
I'm not even sure it's possible without multi-value return args
feature of Wasm. It's not a major setback especially since the WASI
spec (and this includes even the `ephemeral` snapshot) doesn't
return strings anywhere. They are only ever passed in as arguments
to interface functions.

It should be noted that error returned in case of invalid UTF-8
requires a lot more love as it doesn't include anything besides
flagging an event that the string contained an invalid Unicode code unit.

* Borrow all of string's memory including nul-byte

Borrow all of string's underlying memory including the nul-byte.
This perhaps might not have a tremendous impact on anything, but
since the nul-byte is technically part of the WASI string, we should
include it in the borrow as well.

* Fill in wiggle-generate blanks for strings

* Print to screen passed string in proptest

* Strings are PointerLengthPairs!

* Fix generation of strings in compound types

* Update test with simple string strategy

* Generate better test strings

* Finalise proptest for strings

* Fix formatting

* Update crates/runtime/src/memory/string.rs

Removes unnecessary comment in code

* Apply Pat's suggestion to wrap Utf8Error as error
This commit is contained in:
Jakub Konka
2020-02-21 22:37:22 +01:00
committed by GitHub
parent 2f223acc55
commit 6ab3ff71d2
9 changed files with 273 additions and 13 deletions

View File

@@ -22,9 +22,9 @@ impl Names {
let ident = format_ident!("{}", id.as_str().to_camel_case());
quote!(#ident)
}
pub fn builtin_type(&self, b: BuiltinType) -> TokenStream {
pub fn builtin_type(&self, b: BuiltinType, lifetime: TokenStream) -> TokenStream {
match b {
BuiltinType::String => quote!(String),
BuiltinType::String => quote!(wiggle_runtime::GuestString<#lifetime>),
BuiltinType::U8 => quote!(u8),
BuiltinType::U16 => quote!(u16),
BuiltinType::U32 => quote!(u32),
@@ -35,7 +35,7 @@ impl Names {
BuiltinType::S64 => quote!(i64),
BuiltinType::F32 => quote!(f32),
BuiltinType::F64 => quote!(f64),
BuiltinType::Char8 => quote!(char),
BuiltinType::Char8 => quote!(u8),
BuiltinType::USize => quote!(usize),
}
}
@@ -59,7 +59,7 @@ impl Names {
}
}
TypeRef::Value(ty) => match &**ty {
witx::Type::Builtin(builtin) => self.builtin_type(*builtin),
witx::Type::Builtin(builtin) => self.builtin_type(*builtin, lifetime.clone()),
witx::Type::Pointer(pointee) => {
let pointee_type = self.type_ref(&pointee, lifetime.clone());
quote!(wiggle_runtime::GuestPtrMut<#lifetime, #pointee_type>)