wa-lang.org/wazero@v1.0.2/internal/wasm/binary/code_test.go (about) 1 package binary 2 3 import ( 4 "testing" 5 6 "wa-lang.org/wazero/internal/testing/require" 7 "wa-lang.org/wazero/internal/wasm" 8 ) 9 10 var addLocalZeroLocalTwo = []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 2, wasm.OpcodeI32Add, wasm.OpcodeEnd} 11 12 func TestEncodeCode(t *testing.T) { 13 addLocalZeroLocalOne := []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeLocalGet, 1, wasm.OpcodeI32Add, wasm.OpcodeEnd} 14 tests := []struct { 15 name string 16 input *wasm.Code 17 expected []byte 18 }{ 19 { 20 name: "smallest function body", 21 input: &wasm.Code{ // e.g. (func) 22 Body: []byte{wasm.OpcodeEnd}, 23 }, 24 expected: []byte{ 25 0x02, // 2 bytes to encode locals and the body 26 0x00, // no local blocks 27 wasm.OpcodeEnd, // Body 28 }, 29 }, 30 { 31 name: "params and instructions", // local.get index space is params, then locals 32 input: &wasm.Code{ // e.g. (func (type 3) local.get 0 local.get 1 i32.add) 33 Body: addLocalZeroLocalOne, 34 }, 35 expected: append([]byte{ 36 0x07, // 7 bytes to encode locals and the body 37 0x00, // no local blocks 38 }, 39 addLocalZeroLocalOne..., // Body 40 ), 41 }, 42 { 43 name: "locals and instructions", 44 input: &wasm.Code{ // e.g. (func (result i32) (local i32, i32) local.get 0 local.get 1 i32.add) 45 LocalTypes: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI32}, 46 Body: addLocalZeroLocalOne, 47 }, 48 expected: append([]byte{ 49 0x09, // 9 bytes to encode locals and the body 50 0x01, // 1 local block 51 0x02, wasm.ValueTypeI32, // local block 1 52 }, 53 addLocalZeroLocalOne..., // Body 54 ), 55 }, 56 { 57 name: "mixed locals and instructions", 58 input: &wasm.Code{ // e.g. (func (result i32) (local i32) (local i64) (local i32) local.get 0 local.get 2 i32.add) 59 LocalTypes: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI64, wasm.ValueTypeI32}, 60 Body: addLocalZeroLocalTwo, 61 }, 62 expected: append([]byte{ 63 0x0d, // 13 bytes to encode locals and the body 64 0x03, // 3 local blocks 65 0x01, wasm.ValueTypeI32, // local block 1 66 0x01, wasm.ValueTypeI64, // local block 2 67 0x01, wasm.ValueTypeI32, // local block 3 68 }, 69 addLocalZeroLocalTwo..., // Body 70 ), 71 }, 72 } 73 74 for _, tt := range tests { 75 tc := tt 76 77 t.Run(tc.name, func(t *testing.T) { 78 bytes := encodeCode(tc.input) 79 require.Equal(t, tc.expected, bytes) 80 }) 81 } 82 } 83 84 func BenchmarkEncodeCode(b *testing.B) { 85 input := &wasm.Code{ // e.g. (func (result i32) (local i32) (local i64) (local i32) local.get 0 local.get 2 i32.add) 86 LocalTypes: []wasm.ValueType{wasm.ValueTypeI32, wasm.ValueTypeI64, wasm.ValueTypeI32}, 87 Body: addLocalZeroLocalTwo, 88 } 89 90 b.ReportAllocs() 91 for i := 0; i < b.N; i++ { 92 if bytes := encodeCode(input); len(bytes) == 0 { 93 b.Fatal("didn't encode anything") 94 } 95 } 96 }