Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(interface-types) New numbers and strings instructions #1329

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## **[Unreleased]**

- [#1329](https://github.com/wasmerio/wasmer/pull/1329) New numbers and strings instructions for WIT
- [#1320](https://github.com/wasmerio/wasmer/pull/1320) Change `custom_sections` field in `ModuleInfo` to be more standards compliant by allowing multiple custom sections with the same name. To get the old behavior with the new API, you can add `.last().unwrap()` to accesses. For example, `module_info.custom_sections["custom_section_name"].last().unwrap()`.
- [#1303](https://github.com/wasmerio/wasmer/pull/1303) NaN canonicalization for singlepass backend.
- [#1305](https://github.com/wasmerio/wasmer/pull/1305) Handle panics from DynamicFunc.
Expand Down
97 changes: 46 additions & 51 deletions lib/interface-types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,57 +41,52 @@ binary.

## Instructions

Very basically, WebAssembly Interface Types defines a set of
instructions, used by adapters to transform the data between
WebAssembly core and the outside world ([learn
Very basically, WebAssembly Interface Types defines a [set of
instructions](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/working-notes/Instructions.md),
used by adapters to transform the data between WebAssembly core and
the outside world ([learn
mode](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md)).

Here is the instructions that are implemented:
Here is the instructions that are implemented by this crate:

| Instruction | WAT encoder | Binary encoder | WAT decoder | Binary decoder | Interpreter |
|-|-|-|-|-|-|
| `arg.get` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `call-core` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `memory-to-string` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `string-to-memory` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `call-adapter` | ❌ | ❌ | ❌ | ❌ | ❌ |
| `defer-call-core` | ❌ | ❌ | ❌ | ❌ | ❌ |
| `i32-to-s8` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i32-to-s8x` | ✅ | ✅ | ✅ | ✅ | ❌ |
| `i32-to-u8` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i32-to-s16` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i32-to-s16x` | ✅ | ✅ | ✅ | ✅ | ❌ |
| `i32-to-u16` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i32-to-s32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i32-to-u32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i32-to-s64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i32-to-u64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-s8` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-s8x` | ✅ | ✅ | ✅ | ✅ | ❌ |
| `i64-to-u8` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-s16` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-s16x` | ✅ | ✅ | ✅ | ✅ | ❌ |
| `i64-to-u16` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-s32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-s32x` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-u32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-s64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `i64-to-u64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s8-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u8-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s16-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u16-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s32-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u32-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s64-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s64-to-i32x` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u64-to-i32` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u64-to-i32x` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s8-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u8-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s16-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u16-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s32-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u32-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `s64-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `u64-to-i64` | ✅ | ✅ | ✅ | ✅ | ✅ |
| Instruction | WAT encoder/decoder | Binary encoder/decoder | Interpreter | Comment |
|-|-|-|-|-|
| `arg.get` | ✅ | ✅ | ✅ | |
| `call-core` | ✅ | ✅ | ✅ | |
| `s8.from_i32` | ✅ | ✅ | ✅ | |
| `s8.from_i64` | ✅ | ✅ | ✅ | |
| `s16.from_i32` | ✅ | ✅ | ✅ | |
| `s16.from_i64` | ✅ | ✅ | ✅ | |
| `s32.from_i32` | ✅ | ✅ | ✅ | |
| `s32.from_i64` | ✅ | ✅ | ✅ | |
| `s64.from_i32` | ✅ | ✅ | ✅ | |
| `s64.from_i64` | ✅ | ✅ | ✅ | |
| `i32.from_s8` | ✅ | ✅ | ✅ | |
| `i32.from_s16` | ✅ | ✅ | ✅ | |
| `i32.from_s32` | ✅ | ✅ | ✅ | |
| `i32.from_s64` | ✅ | ✅ | ✅ | |
| `i64.from_s8` | ✅ | ✅ | ✅ | |
| `i64.from_s16` | ✅ | ✅ | ✅ | |
| `i64.from_s32` | ✅ | ✅ | ✅ | |
| `i64.from_s64` | ✅ | ✅ | ✅ | |
| `u8.from_i32` | ✅ | ✅ | ✅ | |
| `u8.from_i64` | ✅ | ✅ | ✅ | |
| `u16.from_i32` | ✅ | ✅ | ✅ | |
| `u16.from_i64` | ✅ | ✅ | ✅ | |
| `u32.from_i32` | ✅ | ✅ | ✅ | |
| `u32.from_i64` | ✅ | ✅ | ✅ | |
| `u64.from_i32` | ✅ | ✅ | ✅ | |
| `u64.from_i64` | ✅ | ✅ | ✅ | |
| `i32.from_u8` | ✅ | ✅ | ✅ | |
| `i32.from_u16` | ✅ | ✅ | ✅ | |
| `i32.from_u32` | ✅ | ✅ | ✅ | |
| `i32.from_u64` | ✅ | ✅ | ✅ | |
| `i64.from_u8` | ✅ | ✅ | ✅ | |
| `i64.from_u16` | ✅ | ✅ | ✅ | |
| `i64.from_u32` | ✅ | ✅ | ✅ | |
| `i64.from_u64` | ✅ | ✅ | ✅ | |
| `string.lift_memory` | ✅ | ✅ | ✅ | `#memidx` is not supported; `#encoding` is not supported but UTF-8 is assumed |
| `string.lower_memory` | ✅ | ✅ | ✅ | `#memidx` is not supported; `#encoding` is not supported but UTF-8 is assumed |
| `string.size` | ✅ | ✅ | ✅ | `#encoding` is not supported but UTF-8 is assumed |
| `call-adapter` | ❌ | ❌ | ❌ | |
| `defer-call-core` | ❌ | ❌ | ❌ | |
235 changes: 109 additions & 126 deletions lib/interface-types/src/decoders/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,57 +174,52 @@ fn instruction<'input, E: ParseError<&'input [u8]>>(
)
}

0x03 => (input, Instruction::MemoryToString),

0x04 => {
0x02 => (input, Instruction::S8FromI32),
0x03 => (input, Instruction::S8FromI64),
0x04 => (input, Instruction::S16FromI32),
0x05 => (input, Instruction::S16FromI64),
0x06 => (input, Instruction::S32FromI32),
0x07 => (input, Instruction::S32FromI64),
0x08 => (input, Instruction::S64FromI32),
0x09 => (input, Instruction::S64FromI64),
0x0a => (input, Instruction::I32FromS8),
0x0b => (input, Instruction::I32FromS16),
0x0c => (input, Instruction::I32FromS32),
0x0d => (input, Instruction::I32FromS64),
0x0e => (input, Instruction::I64FromS8),
0x0f => (input, Instruction::I64FromS16),
0x10 => (input, Instruction::I64FromS32),
0x11 => (input, Instruction::I64FromS64),
0x12 => (input, Instruction::U8FromI32),
0x13 => (input, Instruction::U8FromI64),
0x14 => (input, Instruction::U16FromI32),
0x15 => (input, Instruction::U16FromI64),
0x16 => (input, Instruction::U32FromI32),
0x17 => (input, Instruction::U32FromI64),
0x18 => (input, Instruction::U64FromI32),
0x19 => (input, Instruction::U64FromI64),
0x1a => (input, Instruction::I32FromU8),
0x1b => (input, Instruction::I32FromU16),
0x1c => (input, Instruction::I32FromU32),
0x1d => (input, Instruction::I32FromU64),
0x1e => (input, Instruction::I64FromU8),
0x1f => (input, Instruction::I64FromU16),
0x20 => (input, Instruction::I64FromU32),
0x21 => (input, Instruction::I64FromU64),

0x22 => (input, Instruction::StringLiftMemory),

0x23 => {
consume!((input, argument_0) = uleb(input)?);
(
input,
Instruction::StringToMemory {
Instruction::StringLowerMemory {
allocator_index: argument_0 as u32,
},
)
}

0x07 => (input, Instruction::I32ToS8),
0x08 => (input, Instruction::I32ToS8X),
0x09 => (input, Instruction::I32ToU8),
0x0a => (input, Instruction::I32ToS16),
0x0b => (input, Instruction::I32ToS16X),
0x0c => (input, Instruction::I32ToU16),
0x0d => (input, Instruction::I32ToS32),
0x0e => (input, Instruction::I32ToU32),
0x0f => (input, Instruction::I32ToS64),
0x10 => (input, Instruction::I32ToU64),
0x11 => (input, Instruction::I64ToS8),
0x12 => (input, Instruction::I64ToS8X),
0x13 => (input, Instruction::I64ToU8),
0x14 => (input, Instruction::I64ToS16),
0x15 => (input, Instruction::I64ToS16X),
0x16 => (input, Instruction::I64ToU16),
0x17 => (input, Instruction::I64ToS32),
0x18 => (input, Instruction::I64ToS32X),
0x19 => (input, Instruction::I64ToU32),
0x1a => (input, Instruction::I64ToS64),
0x1b => (input, Instruction::I64ToU64),
0x1c => (input, Instruction::S8ToI32),
0x1d => (input, Instruction::U8ToI32),
0x1e => (input, Instruction::S16ToI32),
0x1f => (input, Instruction::U16ToI32),
0x20 => (input, Instruction::S32ToI32),
0x21 => (input, Instruction::U32ToI32),
0x22 => (input, Instruction::S64ToI32),
0x23 => (input, Instruction::S64ToI32X),
0x24 => (input, Instruction::U64ToI32),
0x25 => (input, Instruction::U64ToI32X),
0x26 => (input, Instruction::S8ToI64),
0x27 => (input, Instruction::U8ToI64),
0x28 => (input, Instruction::S16ToI64),
0x29 => (input, Instruction::U16ToI64),
0x2a => (input, Instruction::S32ToI64),
0x2b => (input, Instruction::U32ToI64),
0x2c => (input, Instruction::S64ToI64),
0x2d => (input, Instruction::U64ToI64),
0x24 => (input, Instruction::StringSize),

_ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
})
Expand Down Expand Up @@ -627,98 +622,86 @@ mod tests {
#[test]
fn test_instructions() {
let input = &[
0x2b, // list of 43 items
0x25, // list of 37 items
0x00, 0x01, // ArgumentGet { index: 1 }
0x01, 0x01, // CallCore { function_index: 1 }
0x03, // MemoryToString
0x04, 0x01, // StringToMemory { allocator_index: 1 }
0x07, // I32ToS8
0x08, // I32ToS8X
0x09, // I32ToU8
0x0a, // I32ToS16
0x0b, // I32ToS16X
0x0c, // I32ToU16
0x0d, // I32ToS32
0x0e, // I32ToU32
0x0f, // I32ToS64
0x10, // I32ToU64
0x11, // I64ToS8
0x12, // I64ToS8X
0x13, // I64ToU8
0x14, // I64ToS16
0x15, // I64ToS16X
0x16, // I64ToU16
0x17, // I64ToS32
0x18, // I64ToS32X
0x19, // I64ToU32
0x1a, // I64ToS64
0x1b, // I64ToU64
0x1c, // S8ToI32
0x1d, // U8ToI32
0x1e, // S16ToI32
0x1f, // U16ToI32
0x20, // S32ToI32
0x21, // U32ToI32
0x22, // S64ToI32
0x23, // S64ToI32X
0x24, // U64ToI32
0x25, // U64ToI32X
0x26, // S8ToI64
0x27, // U8ToI64
0x28, // S16ToI64
0x29, // U16ToI64
0x2a, // S32ToI64
0x2b, // U32ToI64
0x2c, // S64ToI64
0x2d, // U64ToI64
0x02, // S8FromI32
0x03, // S8FromI64
0x04, // S16FromI32
0x05, // S16FromI64
0x06, // S32FromI32
0x07, // S32FromI64
0x08, // S64FromI32
0x09, // S64FromI64
0x0a, // I32FromS8
0x0b, // I32FromS16
0x0c, // I32FromS32
0x0d, // I32FromS64
0x0e, // I64FromS8
0x0f, // I64FromS16
0x10, // I64FromS32
0x11, // I64FromS64
0x12, // U8FromI32
0x13, // U8FromI64
0x14, // U16FromI32
0x15, // U16FromI64
0x16, // U32FromI32
0x17, // U32FromI64
0x18, // U64FromI32
0x19, // U64FromI64
0x1a, // I32FromU8
0x1b, // I32FromU16
0x1c, // I32FromU32
0x1d, // I32FromU64
0x1e, // I64FromU8
0x1f, // I64FromU16
0x20, // I64FromU32
0x21, // I64FromU64
0x22, // StringLiftMemory
0x23, 0x01, // StringLowerMemory { allocator_index: 1 }
0x24, // StringSize
0x0a,
];
let output = Ok((
&[0x0a][..],
vec![
Instruction::ArgumentGet { index: 1 },
Instruction::CallCore { function_index: 1 },
Instruction::MemoryToString,
Instruction::StringToMemory { allocator_index: 1 },
Instruction::I32ToS8,
Instruction::I32ToS8X,
Instruction::I32ToU8,
Instruction::I32ToS16,
Instruction::I32ToS16X,
Instruction::I32ToU16,
Instruction::I32ToS32,
Instruction::I32ToU32,
Instruction::I32ToS64,
Instruction::I32ToU64,
Instruction::I64ToS8,
Instruction::I64ToS8X,
Instruction::I64ToU8,
Instruction::I64ToS16,
Instruction::I64ToS16X,
Instruction::I64ToU16,
Instruction::I64ToS32,
Instruction::I64ToS32X,
Instruction::I64ToU32,
Instruction::I64ToS64,
Instruction::I64ToU64,
Instruction::S8ToI32,
Instruction::U8ToI32,
Instruction::S16ToI32,
Instruction::U16ToI32,
Instruction::S32ToI32,
Instruction::U32ToI32,
Instruction::S64ToI32,
Instruction::S64ToI32X,
Instruction::U64ToI32,
Instruction::U64ToI32X,
Instruction::S8ToI64,
Instruction::U8ToI64,
Instruction::S16ToI64,
Instruction::U16ToI64,
Instruction::S32ToI64,
Instruction::U32ToI64,
Instruction::S64ToI64,
Instruction::U64ToI64,
Instruction::S8FromI32,
Instruction::S8FromI64,
Instruction::S16FromI32,
Instruction::S16FromI64,
Instruction::S32FromI32,
Instruction::S32FromI64,
Instruction::S64FromI32,
Instruction::S64FromI64,
Instruction::I32FromS8,
Instruction::I32FromS16,
Instruction::I32FromS32,
Instruction::I32FromS64,
Instruction::I64FromS8,
Instruction::I64FromS16,
Instruction::I64FromS32,
Instruction::I64FromS64,
Instruction::U8FromI32,
Instruction::U8FromI64,
Instruction::U16FromI32,
Instruction::U16FromI64,
Instruction::U32FromI32,
Instruction::U32FromI64,
Instruction::U64FromI32,
Instruction::U64FromI64,
Instruction::I32FromU8,
Instruction::I32FromU16,
Instruction::I32FromU32,
Instruction::I32FromU64,
Instruction::I64FromU8,
Instruction::I64FromU16,
Instruction::I64FromU32,
Instruction::I64FromU64,
Instruction::StringLiftMemory,
Instruction::StringLowerMemory { allocator_index: 1 },
Instruction::StringSize,
],
));

Expand Down
Loading