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