pub enum Instruction<'a> {
Show 76 variants GetArg { nth: usize, }, I32Const { val: i32, }, Bitcasts { casts: &'a [Bitcast], }, ConstZero { tys: &'a [WasmType], }, I32Load { offset: i32, }, I32Load8U { offset: i32, }, I32Load8S { offset: i32, }, I32Load16U { offset: i32, }, I32Load16S { offset: i32, }, I64Load { offset: i32, }, F32Load { offset: i32, }, F64Load { offset: i32, }, I32Store { offset: i32, }, I32Store8 { offset: i32, }, I32Store16 { offset: i32, }, I64Store { offset: i32, }, F32Store { offset: i32, }, F64Store { offset: i32, }, I32FromChar, I64FromU64, I64FromS64, I32FromU32, I32FromS32, I32FromU16, I32FromS16, I32FromU8, I32FromS8, I32FromUsize, I32FromChar8, F32FromIf32, F64FromIf64, S8FromI32, U8FromI32, S16FromI32, U16FromI32, S32FromI32, U32FromI32, S64FromI64, U64FromI64, CharFromI32, If32FromF32, If64FromF64, Char8FromI32, UsizeFromI32, I32FromBorrowedHandle { ty: ResourceId, }, I32FromOwnedHandle { ty: ResourceId, }, HandleOwnedFromI32 { ty: ResourceId, }, HandleBorrowedFromI32 { ty: ResourceId, }, ListCanonLower { element: &'a Type, realloc: Option<&'a str>, }, ListLower { element: &'a Type, realloc: Option<&'a str>, }, ListCanonLift { element: &'a Type, free: Option<&'a str>, ty: TypeId, }, ListLift { element: &'a Type, free: Option<&'a str>, ty: TypeId, }, IterElem { element: &'a Type, }, IterBasePointer, BufferLowerPtrLen { push: bool, ty: &'a Type, }, BufferLowerHandle { push: bool, ty: &'a Type, }, BufferLiftPtrLen { push: bool, ty: &'a Type, }, BufferLiftHandle { push: bool, ty: &'a Type, }, RecordLower { record: &'a Record, name: Option<&'a str>, ty: TypeId, }, RecordLift { record: &'a Record, name: Option<&'a str>, ty: TypeId, }, FlagsLower { record: &'a Record, name: &'a str, ty: TypeId, }, FlagsLower64 { record: &'a Record, name: &'a str, ty: TypeId, }, FlagsLift { record: &'a Record, name: &'a str, ty: TypeId, }, FlagsLift64 { record: &'a Record, name: &'a str, ty: TypeId, }, VariantPayloadName, BufferPayloadName, VariantLower { variant: &'a Variant, name: Option<&'a str>, ty: TypeId, results: &'a [WasmType], }, VariantLift { variant: &'a Variant, name: Option<&'a str>, ty: TypeId, }, CallWasm { module: &'a str, name: &'a str, sig: &'a WasmSignature, }, CallWasmAsyncImport { module: &'a str, name: &'a str, params: &'a [WasmType], results: &'a [WasmType], }, CallWasmAsyncExport { module: &'a str, name: &'a str, params: &'a [WasmType], results: &'a [WasmType], }, CallInterface { module: &'a str, func: &'a Function, }, Return { amt: usize, func: &'a Function, }, ReturnAsyncExport { func: &'a Function, }, ReturnAsyncImport { func: &'a Function, params: usize, }, Witx { instr: &'a WitxInstruction<'a>, },
}

Variants

GetArg

Fields

nth: usize

Acquires the specified parameter and places it on the stack. Depending on the context this may refer to wasm parameters or interface types parameters.

I32Const

Fields

val: i32

Pushes the constant val onto the stack.

Bitcasts

Fields

Casts the top N items on the stack using the Bitcast enum provided. Consumes the same number of operands that this produces.

ConstZero

Fields

Pushes a number of constant zeros for each wasm type on the stack.

I32Load

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian i32 from it, using the specified constant offset.

I32Load8U

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian i8 from it, using the specified constant offset. The value loaded is the zero-extended to 32-bits

I32Load8S

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian i8 from it, using the specified constant offset. The value loaded is the sign-extended to 32-bits

I32Load16U

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian i16 from it, using the specified constant offset. The value loaded is the zero-extended to 32-bits

I32Load16S

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian i16 from it, using the specified constant offset. The value loaded is the sign-extended to 32-bits

I64Load

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian i64 from it, using the specified constant offset.

F32Load

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian f32 from it, using the specified constant offset.

F64Load

Fields

offset: i32

Pops an i32 from the stack and loads a little-endian f64 from it, using the specified constant offset.

I32Store

Fields

offset: i32

Pops an i32 address from the stack and then an i32 value. Stores the value in little-endian at the pointer specified plus the constant offset.

I32Store8

Fields

offset: i32

Pops an i32 address from the stack and then an i32 value. Stores the low 8 bits of the value in little-endian at the pointer specified plus the constant offset.

I32Store16

Fields

offset: i32

Pops an i32 address from the stack and then an i32 value. Stores the low 16 bits of the value in little-endian at the pointer specified plus the constant offset.

I64Store

Fields

offset: i32

Pops an i32 address from the stack and then an i64 value. Stores the value in little-endian at the pointer specified plus the constant offset.

F32Store

Fields

offset: i32

Pops an i32 address from the stack and then an f32 value. Stores the value in little-endian at the pointer specified plus the constant offset.

F64Store

Fields

offset: i32

Pops an i32 address from the stack and then an f64 value. Stores the value in little-endian at the pointer specified plus the constant offset.

I32FromChar

Converts an interface type char value to a 32-bit integer representing the unicode scalar value.

I64FromU64

Converts an interface type u64 value to a wasm i64.

I64FromS64

Converts an interface type s64 value to a wasm i64.

I32FromU32

Converts an interface type u32 value to a wasm i32.

I32FromS32

Converts an interface type s32 value to a wasm i32.

I32FromU16

Converts an interface type u16 value to a wasm i32.

I32FromS16

Converts an interface type s16 value to a wasm i32.

I32FromU8

Converts an interface type u8 value to a wasm i32.

I32FromS8

Converts an interface type s8 value to a wasm i32.

I32FromUsize

Converts a language-specific usize value to a wasm i32.

I32FromChar8

Converts a language-specific C char value to a wasm i32.

F32FromIf32

Conversion an interface type f32 value to a wasm f32.

This may be a noop for some implementations, but it’s here in case the native language representation of f32 is different than the wasm representation of f32.

F64FromIf64

Conversion an interface type f64 value to a wasm f64.

This may be a noop for some implementations, but it’s here in case the native language representation of f64 is different than the wasm representation of f64.

S8FromI32

Converts a native wasm i32 to an interface type s8.

This will truncate the upper bits of the i32.

U8FromI32

Converts a native wasm i32 to an interface type u8.

This will truncate the upper bits of the i32.

S16FromI32

Converts a native wasm i32 to an interface type s16.

This will truncate the upper bits of the i32.

U16FromI32

Converts a native wasm i32 to an interface type u16.

This will truncate the upper bits of the i32.

S32FromI32

Converts a native wasm i32 to an interface type s32.

U32FromI32

Converts a native wasm i32 to an interface type u32.

S64FromI64

Converts a native wasm i64 to an interface type s64.

U64FromI64

Converts a native wasm i64 to an interface type u64.

CharFromI32

Converts a native wasm i32 to an interface type char.

It’s safe to assume that the i32 is indeed a valid unicode code point.

If32FromF32

Converts a native wasm f32 to an interface type f32.

If64FromF64

Converts a native wasm f64 to an interface type f64.

Char8FromI32

Converts a native wasm i32 to a language-specific C char.

This will truncate the upper bits of the i32.

UsizeFromI32

Converts a native wasm i32 to a language-specific usize.

I32FromBorrowedHandle

Fields

Converts a “borrowed” handle into a wasm i32 value.

Note: this documentation is outdated and does not reflect the current implementation of the canonical ABI. This needs to be updated.

A “borrowed” handle in this case means one where ownership is not being relinquished. This is only used for lowering interface types parameters.

Situations that this is used are:

  • A wasm exported function receives, as a parameter, handles defined by the wasm module itself. This is effectively proof of ownership by an external caller (be it host or wasm module) and the ownership of the handle still lies with the caller. The wasm module is only receiving a reference to the resource.

  • A wasm module is calling an import with a handle defined by the import’s module. Sort of the converse of the previous case this means that the wasm module is handing out a reference to a resource that it owns. The type in the wasm module, for example, needs to reflect this.

This instruction is not used for return values in either export/import positions.

I32FromOwnedHandle

Fields

Converts an “owned” handle into a wasm i32 value.

Note: this documentation is outdated and does not reflect the current implementation of the canonical ABI. This needs to be updated.

This conversion is used for handle values which are crossing a module boundary for perhaps the first time. Some example cases of when this conversion is used are:

  • When a host defines a function to be imported, returned handles use this instruction. Handles being returned to wasm a granting a capability, which means that this new capability is typically wrapped up in a new integer descriptor.

  • When a wasm module calls an imported function with a type defined by itself, then it’s granting a capability to the callee. This means that the wasm module’s type is being granted for the first time, possibly, so it needs to be an owned value that’s consumed. Note that this doesn’t actually happen with *.witx today due to the lack of handle type imports.

  • When a wasm module export returns a handle defined within the module, then it’s similar to calling an imported function with that handle. The capability is being granted to the caller of the export, so the owned value is wrapped up in an i32.

  • When a host is calling a wasm module with a capability defined by the host, its’ similar to the host import returning a capability. This would be granting the wasm module with the capability so an owned version with a fresh handle is passed to the wasm module. Note that this doesn’t happen today with *.witx due to the lack of handle type imports.

Basically this instruction is used for handle->wasm conversions depending on the calling context and where the handle type in question was defined.

HandleOwnedFromI32

Fields

Converts a native wasm i32 into an owned handle value.

Note: this documentation is outdated and does not reflect the current implementation of the canonical ABI. This needs to be updated.

This is the converse of I32FromOwnedHandle and is used in similar situations:

  • A host definition of an import receives a handle defined in the module itself.
  • A wasm module calling an import receives a handle defined by the import.
  • A wasm module’s export receives a handle defined by an external module.
  • A host calling a wasm export receives a handle defined in the module.

Note that like I32FromOwnedHandle the first and third bullets above don’t happen today because witx can’t express type imports just yet.

HandleBorrowedFromI32

Fields

Converts a native wasm i32 into a borrowedhandle value.

Note: this documentation is outdated and does not reflect the current implementation of the canonical ABI. This needs to be updated.

This is the converse of I32FromBorrowedHandle and is used in similar situations:

  • An exported wasm function receives, as a parameter, a handle that is defined by the wasm module.
  • An host-defined imported function is receiving a handle, as a parameter, that is defined by the host itself.

ListCanonLower

Fields

element: &'a Type
realloc: Option<&'a str>

Lowers a list where the element’s layout in the native language is expected to match the canonical ABI definition of interface types.

Pops a list value from the stack and pushes the pointer/length onto the stack. If realloc is set to Some then this is expected to consume the list which means that the data needs to be copied. An allocation/copy is expected when:

  • A host is calling a wasm export with a list (it needs to copy the list in to the callee’s module, allocating space with realloc)
  • A wasm export is returning a list (it’s expected to use realloc to give ownership of the list to the caller.
  • A host is returning a list in a import definition, meaning that space needs to be allocated in the caller with realloc).

A copy does not happen (e.g. realloc is None) when:

  • A wasm module calls an import with the list. In this situation it’s expected the caller will know how to access this module’s memory (e.g. the host has raw access or wasm-to-wasm communication would copy the list).

If realloc is Some then the adapter is not responsible for cleaning up this list because the other end is receiving the allocation. If realloc is None then the adapter is responsible for cleaning up any temporary allocation it created, if any.

ListLower

Fields

element: &'a Type
realloc: Option<&'a str>

Lowers a list where the element’s layout in the native language is not expected to match the canonical ABI definition of interface types.

Pops a list value from the stack and pushes the pointer/length onto the stack. This operation also pops a block from the block stack which is used as the iteration body of writing each element of the list consumed.

The realloc field here behaves the same way as ListCanonLower. It’s only set to None when a wasm module calls a declared import. Otherwise lowering in other contexts requires allocating memory for the receiver to own.

ListCanonLift

Fields

element: &'a Type
free: Option<&'a str>
ty: TypeId

Lifts a list which has a canonical representation into an interface types value.

The term “canonical” representation here means that the representation of the interface types value in the native language exactly matches the canonical ABI definition of the type.

This will consume two i32 values from the stack, a pointer and a length, and then produces an interface value list. If the free field is set to Some then the pointer/length should be considered an owned allocation and need to be deallocated by the receiver. If it is set to None then a view is provided but it does not need to be deallocated.

The free field is set to Some in similar situations as described by ListCanonLower. If free is Some then the memory must be deallocated after the lifted list is done being consumed. If it is None then the receiver of the lifted list does not own the memory and must leave the memory as-is.

ListLift

Fields

element: &'a Type
free: Option<&'a str>
ty: TypeId

Lifts a list which into an interface types value.

This will consume two i32 values from the stack, a pointer and a length, and then produces an interface value list. Note that the pointer/length popped are owned and need to be deallocated with the wasm free function when the list is no longer needed.

This will also pop a block from the block stack which is how to read each individual element from the list.

IterElem

Fields

element: &'a Type

Pushes an operand onto the stack representing the list item from each iteration of the list.

This is only used inside of blocks related to lowering lists.

IterBasePointer

Pushes an operand onto the stack representing the base pointer of the next element in a list.

This is used for both lifting and lowering lists.

BufferLowerPtrLen

Fields

push: bool
ty: &'a Type

Pops a buffer value, pushes the pointer/length of where it points to in memory.

BufferLowerHandle

Fields

push: bool
ty: &'a Type

Pops a buffer value, pushes an integer handle for the buffer.

BufferLiftPtrLen

Fields

push: bool
ty: &'a Type

Pops a ptr/len, pushes a buffer wrapping that ptr/len of the memory from the origin module.

BufferLiftHandle

Fields

push: bool
ty: &'a Type

Pops an i32, pushes a buffer wrapping that i32 handle.

RecordLower

Fields

record: &'a Record
name: Option<&'a str>
ty: TypeId

Pops a record value off the stack, decomposes the record to all of its fields, and then pushes the fields onto the stack.

RecordLift

Fields

record: &'a Record
name: Option<&'a str>
ty: TypeId

Pops all fields for a record off the stack and then composes them into a record.

FlagsLower

Fields

record: &'a Record
name: &'a str
ty: TypeId

Converts a language-specific record-of-bools to a list of i32.

FlagsLower64

Fields

record: &'a Record
name: &'a str
ty: TypeId

FlagsLift

Fields

record: &'a Record
name: &'a str
ty: TypeId

Converts a list of native wasm i32 to a language-specific record-of-bools.

FlagsLift64

Fields

record: &'a Record
name: &'a str
ty: TypeId

VariantPayloadName

This is a special instruction used for VariantLower instruction to determine the name of the payload, if present, to use within each block.

Each sub-block will have this be the first instruction, and if it lowers a payload it will expect something bound to this name.

BufferPayloadName

TODO

VariantLower

Fields

variant: &'a Variant
name: Option<&'a str>
ty: TypeId
results: &'a [WasmType]

Pops a variant off the stack as well as ty.cases.len() blocks from the code generator. Uses each of those blocks and the value from the stack to produce nresults of items.

VariantLift

Fields

variant: &'a Variant
name: Option<&'a str>
ty: TypeId

Pops an i32 off the stack as well as ty.cases.len() blocks from the code generator. Uses each of those blocks and the value from the stack to produce a final variant.

CallWasm

Fields

module: &'a str
name: &'a str
sig: &'a WasmSignature

Represents a call to a raw WebAssembly API. The module/name are provided inline as well as the types if necessary.

Note that this instruction is not currently used for async functions, instead CallWasmAsyncImport and CallWasmAsyncExport are used.

CallWasmAsyncImport

Fields

module: &'a str
name: &'a str
results: &'a [WasmType]

Represents a call to an asynchronous wasm import.

This currently only happens when a compiled-to-wasm module calls as async import. This instruction is used to indicate that the specified import function should be called. The specified import function has params as its types, but the final two parameters must be synthesized by this instruction which are the callback/callback state. The actual imported function does not return anything but the callback will be called with the i32 state as the first parameter and results as the rest of the parameters. The callback function should return nothing.

It’s up to the bindings generator to figure out how to make this look synchronous despite it being callback-based in the middle.

CallWasmAsyncExport

Fields

module: &'a str
name: &'a str
results: &'a [WasmType]

Represents a call to an asynchronous wasm export.

This currently only happens when a host module calls an async function on a wasm module. The specified function will take params as its argument plus one more argument of an i32 state that the host needs to synthesize. The function being called doesn’t actually return anything. Instead wasm will call an async_export_done intrinsic in the canonical_abi module. This intrinsic receives a context value and a pointer into linear memory. The context value lines up with the final i32 parameter of this function call (which the bindings generator must synthesize) and the pointer into linear memory contains the results, stored at 8-byte offsets in the same manner that multiple results are transferred.

It’s up to the bindings generator to figure out how to make this look synchronous despite it being callback-based in the middle.

CallInterface

Fields

module: &'a str
func: &'a Function

Same as CallWasm, except the dual where an interface is being called rather than a raw wasm function.

Note that this will be used for async functions.

Return

Fields

amt: usize
func: &'a Function

Returns amt values on the stack. This is always the last instruction.

Note that this instruction is used for asynchronous functions where the results are lifted, not when they’re lowered, though. For those modes the ReturnAsyncExport and ReturnAsyncImport functions are used.

ReturnAsyncExport

Fields

func: &'a Function

“Returns” from an asynchronous export.

This is only used for compiled-to-wasm modules at this time, and only for the exports of async functions in those modules. This instruction receives two parameters, the first of which is the original context from the start of the function which was provided when the export was first called (its last parameter). The second argument is a pointer into linear memory with the results of the asynchronous call already encoded. This instruction should then call the async_export_done intrinsic in the canonical_abi module.

ReturnAsyncImport

Fields

func: &'a Function
params: usize

“Returns” from an asynchronous import.

This is only used for host modules at this time, and only for the import of async functions in those modules. This instruction receives the operands used to call the completion function in the wasm module. The first parameter to this instruction is the index into the function table of the function to call, and the remaining parameters are the parameters to invoke the function with.

Witx

Fields

instr: &'a WitxInstruction<'a>

An instruction from an extended instruction set that’s specific to *.witx and the “Preview1” ABI.

Implementations

How many operands does this instruction pop from the stack?

How many results does this instruction push onto the stack?

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.