diff --git a/README.md b/README.md index 35292415..bb77d041 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ represents the `Homestar` runtime. We recommend diving into each package's own the input interface for working with Ipvm's standard Wasm tasks. You can find the spec for translating between IPLD and WIT runtime values - based on WIT types [here](./homestar-wasm/README.md##interpreting-between-ipld-and-wit). + based on WIT types [here](./homestar-wasm/README.md#interpreting-between-ipld-and-wit). - [homestar-workflow](./homestar-workflow) diff --git a/homestar-functions/subtract/src/bindings.rs b/homestar-functions/subtract/src/bindings.rs index 20575bd7..b75dd48a 100644 --- a/homestar-functions/subtract/src/bindings.rs +++ b/homestar-functions/subtract/src/bindings.rs @@ -7,8 +7,16 @@ pub unsafe fn _export_subtract_cabi(arg0: f64, arg1: f64) -> f64 { let result0 = T::subtract(arg0, arg1); _rt::as_f64(result0) } + +#[doc(hidden)] +#[allow(non_snake_case)] +pub unsafe fn _export_subtract_int_cabi(arg0: i32, arg1: i32) -> i32 { + let result0 = T::subtract_int(arg0 as i8, arg1 as i8); + _rt::as_i32(result0) +} pub trait Guest { fn subtract(a: f64, b: f64) -> f64; + fn subtract_int(a: i8, b: i8) -> i8; } #[doc(hidden)] @@ -20,6 +28,11 @@ macro_rules! __export_world_subtract_cabi{ unsafe extern "C" fn export_subtract(arg0: f64,arg1: f64,) -> f64 { $($path_to_types)*::_export_subtract_cabi::<$ty>(arg0, arg1) } + + #[export_name = "subtract-int"] + unsafe extern "C" fn export_subtract_int(arg0: i32,arg1: i32,) -> i32 { + $($path_to_types)*::_export_subtract_int_cabi::<$ty>(arg0, arg1) + } };); } #[doc(hidden)] @@ -46,6 +59,76 @@ mod _rt { self as f64 } } + + pub fn as_i32(t: T) -> i32 { + t.as_i32() + } + + pub trait AsI32 { + fn as_i32(self) -> i32; + } + + impl<'a, T: Copy + AsI32> AsI32 for &'a T { + fn as_i32(self) -> i32 { + (*self).as_i32() + } + } + + impl AsI32 for i32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for i8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for u8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for char { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + + impl AsI32 for usize { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } } /// Generates `#[no_mangle]` functions to export the specified type as the @@ -79,11 +162,12 @@ pub(crate) use __export_subtract_impl as export; #[cfg(target_arch = "wasm32")] #[link_section = "component-type:wit-bindgen:0.20.0:subtract:encoded world"] #[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 197] = *b"\ -\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07G\x01A\x02\x01A\x02\x01\ -@\x02\x01au\x01bu\0u\x04\0\x08subtract\x01\0\x04\x01$homestar-functions:subtract\ -/subtract\x04\0\x0b\x0e\x01\0\x08subtract\x03\0\0\0G\x09producers\x01\x0cprocess\ -ed-by\x02\x0dwit-component\x070.201.0\x10wit-bindgen-rust\x060.20.0"; +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 225] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07c\x01A\x02\x01A\x04\x01\ +@\x02\x01au\x01bu\0u\x04\0\x08subtract\x01\0\x01@\x02\x01a~\x01b~\0~\x04\0\x0csu\ +btract-int\x01\x01\x04\x01$homestar-functions:subtract/subtract\x04\0\x0b\x0e\x01\ +\0\x08subtract\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x07\ +0.201.0\x10wit-bindgen-rust\x060.20.0"; #[inline(never)] #[doc(hidden)] diff --git a/homestar-functions/subtract/src/lib.rs b/homestar-functions/subtract/src/lib.rs index 8d6089f9..189c1983 100644 --- a/homestar-functions/subtract/src/lib.rs +++ b/homestar-functions/subtract/src/lib.rs @@ -10,6 +10,10 @@ impl Guest for Component { fn subtract(a: f64, b: f64) -> f64 { a - b } + + fn subtract_int(a: i8, b: i8) -> i8 { + a - b + } } bindings::export!(Component with_types_in bindings); diff --git a/homestar-functions/subtract/wit/world.wit b/homestar-functions/subtract/wit/world.wit index d8d04ad9..49b36fb9 100644 --- a/homestar-functions/subtract/wit/world.wit +++ b/homestar-functions/subtract/wit/world.wit @@ -2,4 +2,5 @@ package homestar-functions:subtract; world subtract { export subtract: func(a: float64, b: float64) -> float64; + export subtract-int: func(a: s8, b: s8) -> s8; } diff --git a/homestar-wasm/README.md b/homestar-wasm/README.md index ed6c2448..cc9e0fa5 100644 --- a/homestar-wasm/README.md +++ b/homestar-wasm/README.md @@ -130,7 +130,7 @@ ty ::= 'u8' | 'u16' | 'u32' | 'u64' Conversely, when an integer value (not a float) is returned from a WIT function, it can be translated back into an `Ipld::Integer`. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ```ipldschme type IPLDIntegerAsWit union { @@ -173,7 +173,7 @@ ty ::= 'float32' | 'float64' - **IPLD to WIT Translation**: - When a WIT function expects a float input, an `Ipld::Float` value is + Typically, when a WIT function expects a float input, an `Ipld::Float` value is mapped to a float WIT runtime value. Casting is done to convert from `f32` to `f64` if necessary. @@ -194,6 +194,11 @@ ty ::= 'float32' | 'float64' `1.0` is converted into an `Ipld::Float`, which is then translated and passed into `fn` as a float argument (`f64`). + **Note**: However, if the input argument to the WIT interface is one of the + WIT interger types, but the incoming value is an `Ipld::Integer`, then the + IPLD value will be cast to that integer type, and remain as one for the rest + of the computation. + - **WIT to IPLD Translation**: Conversely, when a `float32` or `float64` value is returned from a WIT @@ -203,7 +208,7 @@ ty ::= 'float32' | 'float64' the default precision for [IPLD][ipld-float], precision will be lost. **The interpreter will use decimal precision in this conversion**. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ```ipldsch type IPLDFloatAsWit union { @@ -221,7 +226,7 @@ type WitAsIpldFloat union { This section outlines the translation process between IPLD string values (`Ipld::String`) and various [WIT runtime values][wit-val]. A `Ipld::String` value can be -interpreted as one of a `string`, `char`, `list`, or an `enum` discriminant +interpreted as one of a `string`, `char`, or an `enum` discriminant (which has no payload). - `string` @@ -282,35 +287,6 @@ interpreted as one of a `string`, `char`, `list`, or an `enum` discriminant Conversely, when a char value is returned from a WIT function, it is translated back into an `Ipld::String`. -- `list` - - * **IPLD to WIT Translation** - - When a WIT function expects a `list` input, an `Ipld::String` value is - mapped to a `list` WIT runtime value. - - **Example**: - - ```wit - export fn: func(a: list) -> list; - ``` - - Given a JSON input for this function: - - ```json - { - "args": ["aGVsbDA"] - } - ``` - - `"aGVsbDA"` is converted into an `Ipld::String`, which is then translated - into bytes and passed into `fn` as a `list` argument. - - * **WIT to IPLD Translation**: - - **Here, when a `list` value is returned from a WIT function, it is - translated into an `Ipld::Bytes` value, which is the proper type**. - - [`enum`][wit-enum]: An enum statement defines a new type which is semantically equivalent to a @@ -350,7 +326,7 @@ interpreted as one of a `string`, `char`, `list`, or an `enum` discriminant Conversely, when an enum value is returned from a WIT function, it can be translated back into an `Ipld::String` value. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type Enum enum { @@ -440,7 +416,7 @@ can be interpreted either as a `list` or `string`. translated into an `Ipld::String` value, because we can't determine if it was originally `bytes`**. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type IPLDBytesAsWit union { @@ -491,7 +467,7 @@ below. Conversely, when a `string` value of `"null"` is returned from a WIT function, it can be translated into an `Ipld::Null` value. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type None unit representation null @@ -543,7 +519,7 @@ interpreted as a `string` in WIT, and vice versa. can be converted to a Cid, it can then be translated into an `Ipld::Link` value. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type IPLDLinkAsWit &String link @@ -674,7 +650,7 @@ possibilities here**. translated back into an `Ipld::List` value. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type IPLDListAsWit union { @@ -810,7 +786,7 @@ a `list` of two-element `tuples`. Conversely, when a `list` of two-element `tuples` is returned from a WIT function, it can be translated back into an `Ipld::Map` value. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type TupleAsMap {string:any} representation listpairs @@ -882,7 +858,7 @@ as either a `Ipld::Null` or of any other IPLD value. translated back into an `Ipld::Null` value if it's the `None`/`Unit` case, or any other IPLD value if it's the `Some` case. -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type IpldAsWitOption union { @@ -1024,7 +1000,7 @@ A [`result`][wit-result] can be interpreted as one of these patterns: `[null, 1]` internally, which signifies the `Err` (error) case, with the `1` payload discarded.** -**IPLD Schema Definitions**: +*IPLD Schema Definitions*: ``` ipldsch type Null unit representation null diff --git a/homestar-wasm/fixtures/example_subtract.wasm b/homestar-wasm/fixtures/example_subtract.wasm index 5127bbd1..7febdcf0 100755 Binary files a/homestar-wasm/fixtures/example_subtract.wasm and b/homestar-wasm/fixtures/example_subtract.wasm differ diff --git a/homestar-wasm/fixtures/example_subtract.wat b/homestar-wasm/fixtures/example_subtract.wat index fde7da55..cac5b58e 100644 --- a/homestar-wasm/fixtures/example_subtract.wat +++ b/homestar-wasm/fixtures/example_subtract.wat @@ -12,6 +12,12 @@ f64.sub ) (func (;1;) (type 1) (param i32 i32) (result i32) + local.get 0 + local.get 1 + i32.sub + i32.extend8_s + ) + (func (;2;) (type 1) (param i32 i32) (result i32) (local i32 i32 i32 i32 i32) i32.const 0 local.set 2 @@ -43,7 +49,7 @@ i32.add i32.const 12 i32.add - call 2 + call 3 local.tee 1 i32.eqz br_if 0 (;@1;) @@ -143,7 +149,7 @@ i32.store offset=4 local.get 2 local.get 1 - call 3 + call 4 br 1 (;@2;) end local.get 2 @@ -206,7 +212,7 @@ i32.store offset=4 local.get 1 local.get 3 - call 3 + call 4 end local.get 0 i32.const 8 @@ -215,7 +221,7 @@ end local.get 2 ) - (func (;2;) (type 2) (param i32) (result i32) + (func (;3;) (type 2) (param i32) (result i32) (local i32 i32 i32 i32 i32 i32 i32 i32 i64) block ;; label = @1 block ;; label = @2 @@ -1682,7 +1688,7 @@ br_if 0 (;@12;) local.get 1 local.get 0 - call 4 + call 5 br 8 (;@4;) end local.get 0 @@ -1776,7 +1782,7 @@ i32.const -8 i32.and local.tee 1 - call 5 + call 6 local.get 1 local.get 2 i32.add @@ -1810,7 +1816,7 @@ br_if 0 (;@11;) local.get 0 local.get 2 - call 4 + call 5 br 6 (;@5;) end local.get 2 @@ -2146,7 +2152,7 @@ br_if 0 (;@3;) local.get 0 local.get 1 - call 4 + call 5 br 2 (;@1;) end local.get 1 @@ -2217,7 +2223,7 @@ i32.const 8 i32.add ) - (func (;3;) (type 3) (param i32 i32) + (func (;4;) (type 3) (param i32 i32) (local i32 i32) local.get 0 local.get 1 @@ -2279,7 +2285,7 @@ end local.get 0 local.get 3 - call 5 + call 6 end block ;; label = @2 block ;; label = @3 @@ -2306,7 +2312,7 @@ i32.const -8 i32.and local.tee 3 - call 5 + call 6 local.get 0 local.get 3 local.get 1 @@ -2353,7 +2359,7 @@ br_if 0 (;@4;) local.get 0 local.get 1 - call 4 + call 5 br 3 (;@1;) end local.get 1 @@ -2453,7 +2459,7 @@ return end ) - (func (;4;) (type 3) (param i32 i32) + (func (;5;) (type 3) (param i32 i32) (local i32 i32 i32 i32) i32.const 31 local.set 2 @@ -2609,7 +2615,7 @@ local.get 0 i32.store offset=8 ) - (func (;5;) (type 3) (param i32 i32) + (func (;6;) (type 3) (param i32 i32) (local i32 i32 i32 i32) local.get 0 i32.load offset=12 @@ -2804,7 +2810,7 @@ return end ) - (func (;6;) (type 4) (param i32) + (func (;7;) (type 4) (param i32) (local i32 i32 i32 i32 i32) local.get 0 i32.const -8 @@ -2876,7 +2882,7 @@ end local.get 1 local.get 2 - call 5 + call 6 end block ;; label = @4 block ;; label = @5 @@ -2902,7 +2908,7 @@ i32.const -8 i32.and local.tee 2 - call 5 + call 6 local.get 1 local.get 2 local.get 0 @@ -2948,7 +2954,7 @@ br_if 2 (;@2;) local.get 1 local.get 0 - call 4 + call 5 i32.const 0 local.set 1 i32.const 0 @@ -3165,7 +3171,7 @@ local.get 0 i32.store ) - (func (;7;) (type 5) (param i32 i32 i32 i32) (result i32) + (func (;8;) (type 5) (param i32 i32 i32 i32) (result i32) (local i32 i32 i32 i32) block ;; label = @1 block ;; label = @2 @@ -3187,7 +3193,7 @@ br_if 0 (;@6;) local.get 2 local.get 3 - call 1 + call 2 local.tee 2 i32.eqz br_if 2 (;@4;) @@ -3199,10 +3205,10 @@ local.get 3 i32.lt_u select - call 9 + call 10 local.set 3 local.get 0 - call 6 + call 7 local.get 3 return end @@ -3296,7 +3302,7 @@ br_if 3 (;@6;) local.get 7 local.get 5 - call 5 + call 6 local.get 2 local.get 1 i32.sub @@ -3333,7 +3339,7 @@ i32.store offset=4 local.get 1 local.get 3 - call 3 + call 4 local.get 0 return end @@ -3369,7 +3375,7 @@ i32.store offset=4 local.get 1 local.get 3 - call 3 + call 4 local.get 0 return end @@ -3463,7 +3469,7 @@ br_if 5 (;@1;) end local.get 3 - call 2 + call 3 local.tee 1 i32.eqz br_if 1 (;@4;) @@ -3487,10 +3493,10 @@ local.get 3 i32.lt_u select - call 9 + call 10 local.set 3 local.get 0 - call 6 + call 7 local.get 3 return end @@ -3505,12 +3511,12 @@ br_if 0 (;@6;) local.get 2 local.get 3 - call 1 + call 2 local.set 0 br 1 (;@5;) end local.get 3 - call 2 + call 3 local.set 0 end local.get 0 @@ -3570,7 +3576,7 @@ i32.store offset=1049008 local.get 0 ) - (func (;8;) (type 6) (param i32 i32 i32) (result i32) + (func (;9;) (type 6) (param i32 i32 i32) (result i32) (local i32 i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 block ;; label = @2 @@ -3751,18 +3757,18 @@ end local.get 0 ) - (func (;9;) (type 6) (param i32 i32 i32) (result i32) + (func (;10;) (type 6) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 - call 8 + call 9 ) - (func (;10;) (type 5) (param i32 i32 i32 i32) (result i32) + (func (;11;) (type 5) (param i32 i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 local.get 3 - call 7 + call 8 ) (table (;0;) 2 2 funcref) (memory (;0;) 17) @@ -3771,10 +3777,11 @@ (global (;2;) i32 i32.const 1049040) (export "memory" (memory 0)) (export "subtract" (func 0)) - (export "cabi_realloc_wit_bindgen_0_20_0" (func 7)) - (export "cabi_realloc" (func 10)) + (export "subtract-int" (func 1)) + (export "cabi_realloc_wit_bindgen_0_20_0" (func 8)) + (export "cabi_realloc" (func 11)) (export "__data_end" (global 1)) (export "__heap_base" (global 2)) - (elem (;0;) (i32.const 1) func 10) + (elem (;0;) (i32.const 1) func 11) (data (;0;) (i32.const 1048576) "\01\00\00\00") ) diff --git a/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wasm b/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wasm index ebde5d3d..1a766728 100755 Binary files a/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wasm and b/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wasm differ diff --git a/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wat b/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wat index 562bb4e4..b9f12ece 100644 --- a/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wat +++ b/homestar-wasm/fixtures/example_subtract_cargo_component_wasi.wat @@ -1,10 +1,10 @@ (component (core module (;0;) (type (;0;) (func (param f64 f64) (result f64))) - (type (;1;) (func (param i32 i32 i32 i32) (result i32))) - (type (;2;) (func (param i32) (result i32))) - (type (;3;) (func (param i32))) - (type (;4;) (func (param i32 i32) (result i32))) + (type (;1;) (func (param i32 i32) (result i32))) + (type (;2;) (func (param i32 i32 i32 i32) (result i32))) + (type (;3;) (func (param i32) (result i32))) + (type (;4;) (func (param i32))) (type (;5;) (func (param i32 i32))) (type (;6;) (func)) (type (;7;) (func (param i32 i32 i32) (result i32))) @@ -13,7 +13,13 @@ local.get 1 f64.sub ) - (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) + (func (;1;) (type 1) (param i32 i32) (result i32) + local.get 0 + local.get 1 + i32.sub + i32.extend8_s + ) + (func (;2;) (type 2) (param i32 i32 i32 i32) (result i32) (local i32) block ;; label = @1 block ;; label = @2 @@ -50,7 +56,7 @@ select local.get 3 i32.add - call 9 + call 10 local.set 2 br 2 (;@3;) end @@ -77,7 +83,7 @@ select local.get 3 i32.add - call 9 + call 10 local.tee 2 i32.eqz br_if 3 (;@2;) @@ -89,20 +95,20 @@ local.get 3 i32.lt_u select - call 12 + call 13 drop local.get 0 - call 4 + call 5 br 4 (;@1;) end local.get 0 local.get 3 - call 6 + call 7 local.set 2 br 1 (;@3;) end local.get 3 - call 2 + call 3 local.set 2 end local.get 2 @@ -113,11 +119,11 @@ end local.get 2 ) - (func (;2;) (type 2) (param i32) (result i32) + (func (;3;) (type 3) (param i32) (result i32) local.get 0 - call 3 + call 4 ) - (func (;3;) (type 2) (param i32) (result i32) + (func (;4;) (type 3) (param i32) (result i32) (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) global.get 0 i32.const 16 @@ -1205,7 +1211,7 @@ end end i32.const 0 - call 11 + call 12 local.tee 0 i32.const -1 i32.eq @@ -1265,7 +1271,7 @@ br_if 7 (;@7;) end local.get 6 - call 11 + call 12 local.tee 4 local.get 0 i32.ne @@ -1282,7 +1288,7 @@ i32.gt_u br_if 5 (;@7;) local.get 6 - call 11 + call 12 local.tee 0 local.get 4 i32.load @@ -1327,7 +1333,7 @@ end block ;; label = @13 local.get 3 - call 11 + call 12 i32.const -1 i32.eq br_if 0 (;@13;) @@ -1342,7 +1348,7 @@ i32.const 0 local.get 6 i32.sub - call 11 + call 12 drop br 5 (;@7;) end @@ -1382,10 +1388,10 @@ i32.gt_u br_if 1 (;@4;) local.get 9 - call 11 + call 12 local.set 0 i32.const 0 - call 11 + call 12 local.set 4 local.get 0 i32.const -1 @@ -3133,11 +3139,11 @@ global.set 0 local.get 4 ) - (func (;4;) (type 3) (param i32) + (func (;5;) (type 4) (param i32) local.get 0 - call 5 + call 6 ) - (func (;5;) (type 3) (param i32) + (func (;6;) (type 4) (param i32) (local i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 0 @@ -3935,13 +3941,13 @@ i32.store offset=1048616 end ) - (func (;6;) (type 4) (param i32 i32) (result i32) + (func (;7;) (type 1) (param i32 i32) (result i32) (local i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 local.get 0 br_if 0 (;@1;) local.get 1 - call 3 + call 4 return end block ;; label = @1 @@ -4047,7 +4053,7 @@ i32.store offset=4 local.get 2 local.get 1 - call 7 + call 8 local.get 0 return end @@ -4448,13 +4454,13 @@ i32.store offset=4 local.get 1 local.get 10 - call 7 + call 8 local.get 0 return end block ;; label = @2 local.get 1 - call 3 + call 4 local.tee 2 br_if 0 (;@2;) i32.const 0 @@ -4480,16 +4486,16 @@ local.get 1 i32.lt_u select - call 12 + call 13 local.set 1 local.get 0 - call 5 + call 6 local.get 1 local.set 0 end local.get 0 ) - (func (;7;) (type 5) (param i32 i32) + (func (;8;) (type 5) (param i32 i32) (local i32 i32 i32 i32 i32 i32) local.get 0 local.get 1 @@ -5247,7 +5253,7 @@ i32.store offset=8 end ) - (func (;8;) (type 4) (param i32 i32) (result i32) + (func (;9;) (type 1) (param i32 i32) (result i32) (local i32 i32 i32 i32 i32) block ;; label = @1 block ;; label = @2 @@ -5310,7 +5316,7 @@ i32.add i32.const 12 i32.add - call 3 + call 4 local.tee 3 br_if 0 (;@1;) i32.const 0 @@ -5423,7 +5429,7 @@ i32.store offset=4 local.get 2 local.get 3 - call 7 + call 8 end block ;; label = @1 local.get 0 @@ -5473,31 +5479,31 @@ i32.store offset=4 local.get 3 local.get 1 - call 7 + call 8 end local.get 0 i32.const 8 i32.add ) - (func (;9;) (type 4) (param i32 i32) (result i32) + (func (;10;) (type 1) (param i32 i32) (result i32) block ;; label = @1 local.get 0 i32.const 16 i32.gt_u br_if 0 (;@1;) local.get 1 - call 3 + call 4 return end local.get 0 local.get 1 - call 8 + call 9 ) - (func (;10;) (type 6) + (func (;11;) (type 6) unreachable unreachable ) - (func (;11;) (type 2) (param i32) (result i32) + (func (;12;) (type 3) (param i32) (result i32) block ;; label = @1 local.get 0 br_if 0 (;@1;) @@ -5535,10 +5541,10 @@ i32.shl return end - call 10 + call 11 unreachable ) - (func (;12;) (type 7) (param i32 i32 i32) (result i32) + (func (;13;) (type 7) (param i32 i32 i32) (result i32) (local i32 i32 i32 i32) block ;; label = @1 block ;; label = @2 @@ -6055,48 +6061,55 @@ end local.get 0 ) - (func (;13;) (type 1) (param i32 i32 i32 i32) (result i32) + (func (;14;) (type 2) (param i32 i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 local.get 3 - call 1 + call 2 ) - (func (;14;) (type 6)) - (func (;15;) (type 6) - call 14 - call 14 + (func (;15;) (type 6)) + (func (;16;) (type 6) + call 15 + call 15 ) - (func (;16;) (type 0) (param f64 f64) (result f64) + (func (;17;) (type 0) (param f64 f64) (result f64) local.get 0 local.get 1 call 0 - call 15 + call 16 + ) + (func (;18;) (type 1) (param i32 i32) (result i32) + local.get 0 + local.get 1 + call 1 + call 16 ) - (func (;17;) (type 1) (param i32 i32 i32 i32) (result i32) + (func (;19;) (type 2) (param i32 i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 local.get 3 - call 1 - call 15 + call 2 + call 16 ) - (func (;18;) (type 1) (param i32 i32 i32 i32) (result i32) + (func (;20;) (type 2) (param i32 i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 local.get 3 - call 13 - call 15 + call 14 + call 16 ) (table (;0;) 2 2 funcref) (memory (;0;) 17) (global (;0;) (mut i32) i32.const 1048576) (export "memory" (memory 0)) - (export "subtract" (func 16)) - (export "cabi_realloc_wit_bindgen_0_20_0" (func 17)) - (export "cabi_realloc" (func 18)) - (elem (;0;) (i32.const 1) func 13) + (export "subtract" (func 17)) + (export "subtract-int" (func 18)) + (export "cabi_realloc_wit_bindgen_0_20_0" (func 19)) + (export "cabi_realloc" (func 20)) + (elem (;0;) (i32.const 1) func 14) (data (;0;) (i32.const 1048576) "\01\00\00\00") (@producers (processed-by "wit-component" "0.201.0") @@ -6110,6 +6123,10 @@ (alias core export 0 "subtract" (core func (;1;))) (func (;0;) (type 0) (canon lift (core func 1))) (export (;1;) "subtract" (func 0)) + (type (;1;) (func (param "a" s8) (param "b" s8) (result s8))) + (alias core export 0 "subtract-int" (core func (;2;))) + (func (;2;) (type 1) (canon lift (core func 2))) + (export (;3;) "subtract-int" (func 2)) (@producers (processed-by "wit-component" "0.201.0") (processed-by "cargo-component" "0.9.0 (wasi:ab5a448)") diff --git a/homestar-wasm/fixtures/example_subtract_component.wasm b/homestar-wasm/fixtures/example_subtract_component.wasm index cbf52f3a..442a28ec 100644 Binary files a/homestar-wasm/fixtures/example_subtract_component.wasm and b/homestar-wasm/fixtures/example_subtract_component.wasm differ diff --git a/homestar-wasm/fixtures/example_subtract_component.wat b/homestar-wasm/fixtures/example_subtract_component.wat index da875e21..979dbf4a 100644 --- a/homestar-wasm/fixtures/example_subtract_component.wat +++ b/homestar-wasm/fixtures/example_subtract_component.wat @@ -13,6 +13,12 @@ f64.sub ) (func (;1;) (type 1) (param i32 i32) (result i32) + local.get 0 + local.get 1 + i32.sub + i32.extend8_s + ) + (func (;2;) (type 1) (param i32 i32) (result i32) (local i32 i32 i32 i32 i32) i32.const 0 local.set 2 @@ -44,7 +50,7 @@ i32.add i32.const 12 i32.add - call 2 + call 3 local.tee 1 i32.eqz br_if 0 (;@1;) @@ -144,7 +150,7 @@ i32.store offset=4 local.get 2 local.get 1 - call 3 + call 4 br 1 (;@2;) end local.get 2 @@ -207,7 +213,7 @@ i32.store offset=4 local.get 1 local.get 3 - call 3 + call 4 end local.get 0 i32.const 8 @@ -216,7 +222,7 @@ end local.get 2 ) - (func (;2;) (type 2) (param i32) (result i32) + (func (;3;) (type 2) (param i32) (result i32) (local i32 i32 i32 i32 i32 i32 i32 i32 i64) block ;; label = @1 block ;; label = @2 @@ -1683,7 +1689,7 @@ br_if 0 (;@12;) local.get 1 local.get 0 - call 4 + call 5 br 8 (;@4;) end local.get 0 @@ -1777,7 +1783,7 @@ i32.const -8 i32.and local.tee 1 - call 5 + call 6 local.get 1 local.get 2 i32.add @@ -1811,7 +1817,7 @@ br_if 0 (;@11;) local.get 0 local.get 2 - call 4 + call 5 br 6 (;@5;) end local.get 2 @@ -2147,7 +2153,7 @@ br_if 0 (;@3;) local.get 0 local.get 1 - call 4 + call 5 br 2 (;@1;) end local.get 1 @@ -2218,7 +2224,7 @@ i32.const 8 i32.add ) - (func (;3;) (type 3) (param i32 i32) + (func (;4;) (type 3) (param i32 i32) (local i32 i32) local.get 0 local.get 1 @@ -2280,7 +2286,7 @@ end local.get 0 local.get 3 - call 5 + call 6 end block ;; label = @2 block ;; label = @3 @@ -2307,7 +2313,7 @@ i32.const -8 i32.and local.tee 3 - call 5 + call 6 local.get 0 local.get 3 local.get 1 @@ -2354,7 +2360,7 @@ br_if 0 (;@4;) local.get 0 local.get 1 - call 4 + call 5 br 3 (;@1;) end local.get 1 @@ -2454,7 +2460,7 @@ return end ) - (func (;4;) (type 3) (param i32 i32) + (func (;5;) (type 3) (param i32 i32) (local i32 i32 i32 i32) i32.const 31 local.set 2 @@ -2610,7 +2616,7 @@ local.get 0 i32.store offset=8 ) - (func (;5;) (type 3) (param i32 i32) + (func (;6;) (type 3) (param i32 i32) (local i32 i32 i32 i32) local.get 0 i32.load offset=12 @@ -2805,7 +2811,7 @@ return end ) - (func (;6;) (type 4) (param i32) + (func (;7;) (type 4) (param i32) (local i32 i32 i32 i32 i32) local.get 0 i32.const -8 @@ -2877,7 +2883,7 @@ end local.get 1 local.get 2 - call 5 + call 6 end block ;; label = @4 block ;; label = @5 @@ -2903,7 +2909,7 @@ i32.const -8 i32.and local.tee 2 - call 5 + call 6 local.get 1 local.get 2 local.get 0 @@ -2949,7 +2955,7 @@ br_if 2 (;@2;) local.get 1 local.get 0 - call 4 + call 5 i32.const 0 local.set 1 i32.const 0 @@ -3166,7 +3172,7 @@ local.get 0 i32.store ) - (func (;7;) (type 5) (param i32 i32 i32 i32) (result i32) + (func (;8;) (type 5) (param i32 i32 i32 i32) (result i32) (local i32 i32 i32 i32) block ;; label = @1 block ;; label = @2 @@ -3188,7 +3194,7 @@ br_if 0 (;@6;) local.get 2 local.get 3 - call 1 + call 2 local.tee 2 i32.eqz br_if 2 (;@4;) @@ -3200,10 +3206,10 @@ local.get 3 i32.lt_u select - call 9 + call 10 local.set 3 local.get 0 - call 6 + call 7 local.get 3 return end @@ -3297,7 +3303,7 @@ br_if 3 (;@6;) local.get 7 local.get 5 - call 5 + call 6 local.get 2 local.get 1 i32.sub @@ -3334,7 +3340,7 @@ i32.store offset=4 local.get 1 local.get 3 - call 3 + call 4 local.get 0 return end @@ -3370,7 +3376,7 @@ i32.store offset=4 local.get 1 local.get 3 - call 3 + call 4 local.get 0 return end @@ -3464,7 +3470,7 @@ br_if 5 (;@1;) end local.get 3 - call 2 + call 3 local.tee 1 i32.eqz br_if 1 (;@4;) @@ -3488,10 +3494,10 @@ local.get 3 i32.lt_u select - call 9 + call 10 local.set 3 local.get 0 - call 6 + call 7 local.get 3 return end @@ -3506,12 +3512,12 @@ br_if 0 (;@6;) local.get 2 local.get 3 - call 1 + call 2 local.set 0 br 1 (;@5;) end local.get 3 - call 2 + call 3 local.set 0 end local.get 0 @@ -3571,7 +3577,7 @@ i32.store offset=1049008 local.get 0 ) - (func (;8;) (type 6) (param i32 i32 i32) (result i32) + (func (;9;) (type 6) (param i32 i32 i32) (result i32) (local i32 i32 i32 i32 i32 i32 i32 i32) block ;; label = @1 block ;; label = @2 @@ -3752,18 +3758,18 @@ end local.get 0 ) - (func (;9;) (type 6) (param i32 i32 i32) (result i32) + (func (;10;) (type 6) (param i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 - call 8 + call 9 ) - (func (;10;) (type 5) (param i32 i32 i32 i32) (result i32) + (func (;11;) (type 5) (param i32 i32 i32 i32) (result i32) local.get 0 local.get 1 local.get 2 local.get 3 - call 7 + call 8 ) (table (;0;) 2 2 funcref) (memory (;0;) 17) @@ -3772,11 +3778,12 @@ (global (;2;) i32 i32.const 1049040) (export "memory" (memory 0)) (export "subtract" (func 0)) - (export "cabi_realloc_wit_bindgen_0_20_0" (func 7)) - (export "cabi_realloc" (func 10)) + (export "subtract-int" (func 1)) + (export "cabi_realloc_wit_bindgen_0_20_0" (func 8)) + (export "cabi_realloc" (func 11)) (export "__data_end" (global 1)) (export "__heap_base" (global 2)) - (elem (;0;) (i32.const 1) func 10) + (elem (;0;) (i32.const 1) func 11) (data (;0;) (i32.const 1048576) "\01\00\00\00") (@producers (processed-by "wit-component" "0.201.0") @@ -3790,6 +3797,10 @@ (alias core export 0 "subtract" (core func (;1;))) (func (;0;) (type 0) (canon lift (core func 1))) (export (;1;) "subtract" (func 0)) + (type (;1;) (func (param "a" s8) (param "b" s8) (result s8))) + (alias core export 0 "subtract-int" (core func (;2;))) + (func (;2;) (type 1) (canon lift (core func 2))) + (export (;3;) "subtract-int" (func 2)) (@producers (processed-by "wit-component" "0.201.0") ) diff --git a/homestar-wasm/src/wasmtime/ipld.rs b/homestar-wasm/src/wasmtime/ipld.rs index d2659dc5..b1de134b 100644 --- a/homestar-wasm/src/wasmtime/ipld.rs +++ b/homestar-wasm/src/wasmtime/ipld.rs @@ -302,14 +302,40 @@ impl RuntimeVal { | InterfaceType::Type(Type::S64) | InterfaceType::TypeRef(Type::S64) => RuntimeVal::new(Val::S64(v.try_into()?)), _ => Err(InterpreterError::IpldToWit( - "Expected conversion to integer".to_string(), + "Expected conversion to integer/float".to_string(), ))?, }, Ipld::Float(v) => match interface_ty { InterfaceType::Type(Type::Float32) | InterfaceType::TypeRef(Type::Float32) => { RuntimeVal::new(Val::Float32(v as f32)) } - _ => RuntimeVal::new(Val::Float64(v)), + InterfaceType::Type(Type::Float64) + | InterfaceType::TypeRef(Type::Float64) + | InterfaceType::Any => RuntimeVal::new(Val::Float64(v)), + InterfaceType::Type(Type::U8) | InterfaceType::TypeRef(Type::U8) => { + RuntimeVal::new(Val::U8(v as u8)) + } + InterfaceType::Type(Type::U16) | InterfaceType::TypeRef(Type::U16) => { + RuntimeVal::new(Val::U16(v as u16)) + } + InterfaceType::Type(Type::U32) | InterfaceType::TypeRef(Type::U32) => { + RuntimeVal::new(Val::U32(v as u32)) + } + InterfaceType::Type(Type::U64) | InterfaceType::TypeRef(Type::U64) => { + RuntimeVal::new(Val::U64(v as u64)) + } + InterfaceType::Type(Type::S8) | InterfaceType::TypeRef(Type::S8) => { + RuntimeVal::new(Val::S8(v as i8)) + } + InterfaceType::Type(Type::S16) | InterfaceType::TypeRef(Type::S16) => { + RuntimeVal::new(Val::S16(v as i16)) + } + InterfaceType::Type(Type::S32) | InterfaceType::TypeRef(Type::S32) => { + RuntimeVal::new(Val::S32(v as i32)) + } + _ => Err(InterpreterError::IpldToWit( + "Expected conversion to float/integer".to_string(), + ))?, }, Ipld::String(v) => match interface_ty.inner() { Some(Type::Enum(enum_inst)) => enum_inst @@ -339,12 +365,10 @@ impl RuntimeVal { }?; RuntimeVal::new(Val::Char(c)) } - Some(Type::List(list_inst)) => { - let bytes = v.as_bytes(); - let val_bytes = bytes.iter().map(|elem| Val::U8(*elem)).collect(); - - RuntimeVal::new(list_inst.new_val(val_bytes)?) - } + Some(Type::List(_list_inst)) => Err(InterpreterError::TypeMismatch { + expected: "".to_string(), + given: format!("{} as a string", v).into(), + })?, _ => RuntimeVal::new(Val::String(Box::from(v))), }, Ipld::Bytes(v) => match interface_ty.inner() { @@ -929,6 +953,28 @@ mod test { assert_eq!(Ipld::try_from(runtime_float).unwrap(), ipld_out); } + #[test] + fn try_float32_to_integer() { + let ipld_in = Ipld::Float(5.0); + let ipld_out = Ipld::Integer(5); + let runtime_int = RuntimeVal::new(Val::U8(5)); + + let ty = test_utils::component::setup_component_with_param( + "u8".to_string(), + &[test_utils::component::Param( + test_utils::component::Type::U8, + None, + )], + ); + + assert_eq!( + RuntimeVal::try_from(ipld_in.clone(), &InterfaceType::Type(ty)).unwrap(), + runtime_int + ); + + assert_eq!(Ipld::try_from(runtime_int).unwrap(), ipld_out); + } + #[test] fn try_integer_to_float64() { let ipld_in = Ipld::Integer(5); @@ -976,25 +1022,9 @@ mod test { fn try_string_to_listu8_to_string_roundtrip() { let ipld_bytes_as_string = Ipld::String(String::from_utf8_lossy(b"hell0").to_string()); let ty = test_utils::component::setup_component("(list u8)".to_string(), 8); - let val_list = ty - .unwrap_list() - .new_val(Box::new([ - Val::U8(104), - Val::U8(101), - Val::U8(108), - Val::U8(108), - Val::U8(48), - ])) - .unwrap(); - let runtime = RuntimeVal::new(val_list); - assert_eq!( - RuntimeVal::try_from(ipld_bytes_as_string.clone(), &InterfaceType::Type(ty)).unwrap(), - runtime - ); - assert_eq!( - Ipld::try_from(runtime).unwrap(), - Ipld::Bytes(b"hell0".to_vec()) + assert!( + RuntimeVal::try_from(ipld_bytes_as_string.clone(), &InterfaceType::Type(ty)).is_err(), ); } diff --git a/homestar-wasm/src/wasmtime/world.rs b/homestar-wasm/src/wasmtime/world.rs index 41474d66..fc980239 100644 --- a/homestar-wasm/src/wasmtime/world.rs +++ b/homestar-wasm/src/wasmtime/world.rs @@ -382,6 +382,7 @@ impl World { let mut __exports = exports.root(); let func = __exports .func(fun_name) + .or_else(|| __exports.func(&fun_name.to_uppercase())) .or_else(|| __exports.func(&fun_name.to_kebab_case())) .or_else(|| __exports.func(&fun_name.to_snake_case())) .or_else(|| __exports.func(&fun_name.to_lower_camel_case())) diff --git a/homestar-wasm/tests/execute_wasm.rs b/homestar-wasm/tests/execute_wasm.rs index 90870a3c..1c999d54 100644 --- a/homestar-wasm/tests/execute_wasm.rs +++ b/homestar-wasm/tests/execute_wasm.rs @@ -559,7 +559,7 @@ async fn test_execute_wasms_with_multiple_inits() { let promise = Await::new(invoked_instr, AwaitResult::Ok); let ipld_step_2 = Input::::Ipld(Ipld::Map(BTreeMap::from([ - ("func".into(), Ipld::String("join-strings".to_string())), + ("func".into(), Ipld::String("%join-strings".to_string())), ( "args".into(), Ipld::List(vec![Ipld::from(promise), Ipld::String("about".to_string())]), @@ -568,7 +568,7 @@ async fn test_execute_wasms_with_multiple_inits() { let wasm = fs::read(fixtures("example_test.wasm")).unwrap(); - let mut env = World::instantiate(wasm.clone(), "join-strings", State::default()) + let mut env = World::instantiate(wasm.clone(), "%join-strings", State::default()) .await .unwrap(); @@ -608,9 +608,9 @@ async fn test_execute_wasms_with_multiple_inits() { } #[tokio::test] -async fn test_subtract() { +async fn test_subtract_int_to_float() { let ipld = Input::Ipld(Ipld::Map(BTreeMap::from([ - ("func".into(), Ipld::String("subtract".to_string())), + ("func".into(), Ipld::String("SUBTRACT".to_string())), ( "args".into(), Ipld::List(vec![Ipld::Integer(1), Ipld::Integer(1)]), @@ -624,3 +624,21 @@ async fn test_subtract() { let res = env.execute(ipld.parse().unwrap().into()).await.unwrap(); assert_eq!(res, Output::Value(wasmtime::component::Val::Float64(0.0))); } + +#[tokio::test] +async fn test_subtract_float_to_int() { + let ipld = Input::Ipld(Ipld::Map(BTreeMap::from([ + ("func".into(), Ipld::String("subtractInt".to_string())), + ( + "args".into(), + Ipld::List(vec![Ipld::Float(1.0), Ipld::Float(2.0)]), + ), + ]))); + + let wasm = fs::read(fixtures("example_subtract.wasm")).unwrap(); + let mut env = World::instantiate(wasm, "subtractInt", State::default()) + .await + .unwrap(); + let res = env.execute(ipld.parse().unwrap().into()).await.unwrap(); + assert_eq!(res, Output::Value(wasmtime::component::Val::S8(-1))); +}