-
Notifications
You must be signed in to change notification settings - Fork 339
Description
With #1650 new Wasmi operators have been introduced together with 2 different modes of bytecode layout: indirect-dispatch and !indirect-dispatch.
indirect-dispatchencodes all operators with a 16-bit op-code.!indirect-dispatchencodes all operators with a pointer sized function pointer to the execution handler.
Thus, indirect-dispatch offsets all operands by 2 bytes whereas !indirect-dispatch offsets operands by either 4 bytes (32-bit) or 8 bytes (64-bit).
Ideally, operators are laid out differently depending on those constraints.
For example, i64.add_ssi has 3 operators:
result: Slot(2 bytes)lhs: Slot(2 bytes)rhs: i64(8 bytes)
This requires different layouts on different configs:
indirect-dispatch:
struct I64Add_Ssi {
pub result: Slot,
pub lhs: Slot,
#[cfg(target_pointer_width = "64")]
_pad: Padding<4>,
pub rhs: i64,
}Where Padding<N> is defined as:
#[derive(Debug, Default, Copy, Clone)]
pub struct Padding<const N: usize> {
marker: [u8; N],
}And has a Decode and Encode impl that simply forwards the decoder or encoder cursor while decoding or encoding nothing. Its bytes are always zeroed and cannot be changed. It simply exist to create padding bytes in between operands.
!indirect-dispatch
This is a bit more tricky since we either have a 4-byte offset (32-bit) or an 8-byte offset (64-bit).
struct I64Add_Ssi {
pub result: Slot,
pub lhs: Slot,
#[cfg(target_pointer_width = "64")]
_pad: Padding<4>,
pub rhs: i64,
}or we could also re-order fields which is what the Rust compiler would do:
#[cfg(target_pointer_width = "64")]
struct I64Add_Ssi {
pub rhs: i64,
pub result: Slot,
pub lhs: Slot,
_pad: Padding<4>, // so the next operator starts at alignment of 4
}
#[cfg(target_pointer_width = "32")]
struct I64Add_Ssi {
pub result: Slot,
pub lhs: Slot,
pub rhs: i64,
}All in all this can get complex very quickly due to the different modes of memory layout.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status