(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)
)