Type Misuse
NOTE
Please pay attention to distinguish it from type checking. Type checking ensures operand types that passed to instructions are correct, while this checks immediates.
WasmGC introduces struct types and array types, and also introduces new instructions like array.*
and struct.*
. This checks if types that used in these instructions match the instruction or not.
array.*
and struct.*
For example, a struct type used in array.*
instructions:
(module
(type $struct (struct))
(func
i32.const 0
array.new_default $struct
drop))
Or, an array type used in struct.*
instructions:
(module
(type $array (array i32))
(func
struct.new_default $array
drop))
array.copy
Beside the checks above, array.copy
also checks the source and destination types. The source type must match the destination type.
(module
(type $dst_array (array (mut i32)))
(type $src_array (array i64))
(func (param (ref $dst_array) (ref $src_array))
local.get 0
i32.const 0
local.get 1
i32.const 0
i32.const 0
array.copy $dst_array $src_array))
call_ref
and return_call_ref
These instructions require the referenced type must be a function type.
(module
(type $func (func))
(type $struct (struct (field i32)))
(type $array (array (mut i32)))
(func (param (ref $func))
local.get 0
call_ref $func
local.get 0
return_call_ref $func)
(func (param (ref $func))
local.get 0
call_ref $struct
local.get 0
return_call_ref $array))
br_on_cast
This instruction requires the last type of the label's types must be a ref type:
(module
(func
(br_on_cast 0 structref structref
(unreachable))))
It requires the second ref type must match the first ref type:
(module
(func (result anyref)
(br_on_cast 0 structref arrayref
(unreachable))))
It also requires the second ref type must match the last type of the label's types:
(module
(func (param (ref any)) (result (ref $t))
(block (result (ref any))
(br_on_cast 1 (ref null any) (ref null $t)
(local.get 0)))
(unreachable)))
br_on_cast_fail
This instruction requires the last type of the label's types must be a ref type:
(module
(func
(br_on_cast_fail 0 structref structref
(unreachable))))
It requires the second ref type must match the first ref type:
(module
(func (result anyref)
(br_on_cast_fail 0 structref arrayref
(unreachable))))
It also requires the type difference between the first ref type and the second ref type must match the last type of the label's types:
(module
(func (param (ref null any)) (result (ref any))
(block (result (ref $t))
(br_on_cast_fail 1 (ref null any) (ref $t)
(local.get 0)))))