(assert_abi (witx (module $x (@interface func (export "f")))) (wasm) (call_wasm call.wasm return) (call_interface call.interface return) ) ;; scalar arguments (assert_abi (witx (module $x (@interface func (export "f") (param $p u8)))) (wasm (param i32)) (call_wasm get-arg0 i32.from_u8 call.wasm return) (call_interface get-arg0 u8.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p s8)))) (wasm (param i32)) (call_wasm get-arg0 i32.from_s8 call.wasm return) (call_interface get-arg0 s8.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p u16)))) (wasm (param i32)) (call_wasm get-arg0 i32.from_u16 call.wasm return) (call_interface get-arg0 u16.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p s16)))) (wasm (param i32)) (call_wasm get-arg0 i32.from_s16 call.wasm return) (call_interface get-arg0 s16.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p u32)))) (wasm (param i32)) (call_wasm get-arg0 i32.from_u32 call.wasm return) (call_interface get-arg0 u32.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p s32)))) (wasm (param i32)) (call_wasm get-arg0 i32.from_s32 call.wasm return) (call_interface get-arg0 s32.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p u64)))) (wasm (param i64)) (call_wasm get-arg0 i64.from_u64 call.wasm return) (call_interface get-arg0 u64.from_i64 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p s64)))) (wasm (param i64)) (call_wasm get-arg0 i64.from_s64 call.wasm return) (call_interface get-arg0 s64.from_i64 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p f32)))) (wasm (param f32)) (call_wasm get-arg0 f32.from_if32 call.wasm return) (call_interface get-arg0 if32.from_f32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p f64)))) (wasm (param f64)) (call_wasm get-arg0 f64.from_if64 call.wasm return) (call_interface get-arg0 if64.from_f64 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p (@witx usize))))) (wasm (param i32)) (call_wasm get-arg0 i32.from_usize call.wasm return) (call_interface get-arg0 usize.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p (@witx char8))))) (wasm (param i32)) (call_wasm get-arg0 i32.from_char8 call.wasm return) (call_interface get-arg0 char8.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p char)))) (wasm (param i32)) (call_wasm get-arg0 i32.from_char call.wasm return) (call_interface get-arg0 char.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p (@witx pointer u8))))) (wasm (param i32)) (call_wasm get-arg0 i32.from_pointer call.wasm return) (call_interface get-arg0 pointer.from_i32 call.interface return) ) (assert_abi (witx (module $x (@interface func (export "f") (param $p (@witx const_pointer u8))))) (wasm (param i32)) (call_wasm get-arg0 i32.from_const_pointer call.wasm return) (call_interface get-arg0 const_pointer.from_i32 call.interface return) ) ;; flags parameter (assert_abi (witx (typename $a (flags $x $y)) (module $x (@interface func (export "f") (param $p $a))) ) (wasm (param i32)) (call_wasm get-arg0 i32.from_bitflags call.wasm return) (call_interface get-arg0 bitflags.from_i32 call.interface return) ) (assert_abi (witx (typename $a (flags (@witx repr u64) $x $y)) (module $x (@interface func (export "f") (param $p $a))) ) (wasm (param i64)) (call_wasm get-arg0 i64.from_bitflags call.wasm return) (call_interface get-arg0 bitflags.from_i64 call.interface return) ) ;; struct parameter (assert_abi (witx (typename $a (record (field $x u8))) (module $x (@interface func (export "f") (param $p $a))) ) (wasm (param i32)) (call_wasm get-arg0 addr-of call.wasm return) (call_interface get-arg0 load call.interface return) ) ;; handle parameter (assert_abi (witx (typename $a (handle)) (module $x (@interface func (export "f") (param $p $a))) ) (wasm (param i32)) (call_wasm get-arg0 i32.from_handle call.wasm return) (call_interface get-arg0 handle.from_i32 call.interface return) ) ;; list parameter (assert_abi (witx (module $x (@interface func (export "f") (param $p (list u8)))) ) (wasm (param i32 i32)) (call_wasm get-arg0 list.pointer_length call.wasm return) (call_interface get-arg0 get-arg1 list.from_pointer_length call.interface return) ) ;; variant parameter -- some not allowed at this time (assert_abi (witx (typename $a (enum $b)) (module $x (@interface func (export "f") (param $p $a))) ) (wasm (param i32)) (call_wasm get-arg0 enum.lower call.wasm return) (call_interface get-arg0 enum.lift call.interface return) ) (assert_abi (witx (typename $a (union f32)) (module $x (@interface func (export "f") (param $p $a))) ) (wasm (param i32)) (call_wasm get-arg0 addr-of call.wasm return) (call_interface get-arg0 load call.interface return) ) ;; scalar returns (assert_abi (witx (module $x (@interface func (export "f") (result $p u8)))) (wasm (result i32)) (call_wasm call.wasm u8.from_i32 return) (call_interface call.interface i32.from_u8 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p s8)))) (wasm (result i32)) (call_wasm call.wasm s8.from_i32 return) (call_interface call.interface i32.from_s8 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p u16)))) (wasm (result i32)) (call_wasm call.wasm u16.from_i32 return) (call_interface call.interface i32.from_u16 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p s16)))) (wasm (result i32)) (call_wasm call.wasm s16.from_i32 return) (call_interface call.interface i32.from_s16 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p u32)))) (wasm (result i32)) (call_wasm call.wasm u32.from_i32 return) (call_interface call.interface i32.from_u32 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p s32)))) (wasm (result i32)) (call_wasm call.wasm s32.from_i32 return) (call_interface call.interface i32.from_s32 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p u64)))) (wasm (result i64)) (call_wasm call.wasm u64.from_i64 return) (call_interface call.interface i64.from_u64 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p s64)))) (wasm (result i64)) (call_wasm call.wasm s64.from_i64 return) (call_interface call.interface i64.from_s64 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p f32)))) (wasm (result f32)) (call_wasm call.wasm if32.from_f32 return) (call_interface call.interface f32.from_if32 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p f64)))) (wasm (result f64)) (call_wasm call.wasm if64.from_f64 return) (call_interface call.interface f64.from_if64 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p (@witx usize))))) (wasm (result i32)) (call_wasm call.wasm usize.from_i32 return) (call_interface call.interface i32.from_usize return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p (@witx char8))))) (wasm (result i32)) (call_wasm call.wasm char8.from_i32 return) (call_interface call.interface i32.from_char8 return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p char)))) (wasm (result i32)) (call_wasm call.wasm char.from_i32 return) (call_interface call.interface i32.from_char return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p (@witx pointer u8))))) (wasm (result i32)) (call_wasm call.wasm pointer.from_i32 return) (call_interface call.interface i32.from_pointer return) ) (assert_abi (witx (module $x (@interface func (export "f") (result $p (@witx const_pointer u8))))) (wasm (result i32)) (call_wasm call.wasm const_pointer.from_i32 return) (call_interface call.interface i32.from_const_pointer return) ) ;; flags return (assert_abi (witx (typename $a (flags $x $y)) (module $x (@interface func (export "f") (result $p $a))) ) (wasm (result i32)) (call_wasm call.wasm bitflags.from_i32 return) (call_interface call.interface i32.from_bitflags return) ) (assert_abi (witx (typename $a (flags (@witx repr u64) $x $y)) (module $x (@interface func (export "f") (result $p $a))) ) (wasm (result i64)) (call_wasm call.wasm bitflags.from_i64 return) (call_interface call.interface i64.from_bitflags return) ) ;; handle return (assert_abi (witx (typename $a (handle)) (module $x (@interface func (export "f") (result $p $a))) ) (wasm (result i32)) (call_wasm call.wasm handle.from_i32 return) (call_interface call.interface i32.from_handle return) ) ;; struct return -- not supported (assert_invalid (witx (typename $a (record (field $x u8))) (module $x (@interface func (export "f") (result $p $a))) ) "ABI error: invalid return type" ) ;; list return -- not supported (assert_invalid (witx (module $x (@interface func (export "f") (result $p (list u8)))) ) "ABI error: invalid return type" ) ;; variant return -- only some allowed (assert_invalid (witx (typename $a (enum $b)) (module $x (@interface func (export "f") (result $p $a))) ) "ABI error: invalid return type" ) (assert_invalid (witx (typename $a (union s32 f32)) (module $x (@interface func (export "f") (result $p $a))) ) "ABI error: invalid return type" ) (assert_invalid (witx (typename $a (expected (error f32))) (module $x (@interface func (export "f") (result $p $a))) ) "ABI error: only named types are allowed in results" ) (assert_invalid (witx (typename $errno (enum $success $bad)) (typename $a (expected f32 (error $errno))) (module $x (@interface func (export "f") (result $p $a))) ) "ABI error: only named types are allowed in results" ) ;; Result<(), $errno> (assert_abi (witx (typename $errno (enum $success $bad)) (typename $a (expected (error $errno))) (module $x (@interface func (export "f") (result $p $a))) ) (wasm (result i32)) (call_wasm call.wasm ;; ok block, nothing happens block.push block.finish ;; err block, we lift the return value as the num block.push reuse_return enum.lift block.finish ;; consumes 2 blocks and uses the return value of the call to discriminate result.lift return) (call_interface call.interface ;; ok block, nothing happens block.push block.finish ;; err block, lift the enum block.push variant-payload enum.lower block.finish ;; consume the 2 blocks and lower based on the call result.lower return) ) ;; Result<$ty, $errno> (assert_abi (witx (typename $errno (enum $success $bad)) (typename $size u32) (typename $a (expected $size (error $errno))) (module $x (@interface func (export "f") (result $p $a))) ) (wasm (param i32) (result i32)) (call_wasm ;; make space for the return value and push its pointer allocate-space return_pointer.get0 call.wasm ;; ok block, load the return pointer and have it be the result for the `Ok` block.push return_pointer.get0 load block.finish block.push reuse_return enum.lift block.finish result.lift return) (call_interface call.interface ;; store the successful result at the first return pointer (the first param) block.push variant-payload get-arg0 store block.finish block.push variant-payload enum.lower block.finish result.lower return) ) ;; Result<($a, $b), $errno> (assert_abi (witx (typename $errno (enum $success $bad)) (typename $size u32) (typename $other (record (field $a $size))) (module $x (@interface func (export "f") (result $p (expected (tuple $size $other) (error $errno))))) ) (wasm (param i32 i32) (result i32)) (call_wasm allocate-space return_pointer.get0 allocate-space return_pointer.get1 call.wasm block.push return_pointer.get0 load return_pointer.get1 load tuple.lift block.finish block.push reuse_return enum.lift block.finish result.lift return) (call_interface call.interface ;; note the reverse order since we're consuming the results of lowering the ;; tuple block.push variant-payload tuple.lower get-arg1 store get-arg0 store block.finish block.push variant-payload enum.lower block.finish result.lower return) )