github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/testing/binaryencoding/names_test.go (about) 1 package binaryencoding 2 3 import ( 4 "testing" 5 6 "github.com/tetratelabs/wazero/internal/testing/require" 7 "github.com/tetratelabs/wazero/internal/wasm" 8 ) 9 10 func TestEncodeNameSectionData(t *testing.T) { 11 tests := []struct { 12 name string 13 input *wasm.NameSection 14 expected []byte 15 }{ 16 { 17 name: "empty", 18 input: &wasm.NameSection{}, 19 }, 20 { 21 name: "only module", 22 // e.g. (module $simple ) 23 input: &wasm.NameSection{ModuleName: "simple"}, 24 expected: []byte{ 25 subsectionIDModuleName, 0x07, // 7 bytes 26 0x06, // the Module name simple is 6 bytes long 27 's', 'i', 'm', 'p', 'l', 'e', 28 }, 29 }, 30 { 31 name: "module and function name", 32 // (module $simple 33 // (import "" "Hello" (func $hello)) 34 // (start $hello) 35 // ) 36 input: &wasm.NameSection{ 37 ModuleName: "simple", 38 FunctionNames: wasm.NameMap{{Index: wasm.Index(0), Name: "hello"}}, 39 }, 40 expected: []byte{ 41 subsectionIDModuleName, 0x07, // 7 bytes 42 0x06, // the Module name simple is 6 bytes long 43 's', 'i', 'm', 'p', 'l', 'e', 44 subsectionIDFunctionNames, 0x08, // 8 bytes 45 0x01, // one function name 46 0x00, // the function index is zero 47 0x05, // the function name hello is 5 bytes long 48 'h', 'e', 'l', 'l', 'o', 49 }, 50 }, 51 { 52 name: "two function names", // e.g. TinyGo which at one point didn't set a module name 53 // (module 54 // (import "wasi_snapshot_preview1" "args_sizes_get" (func $wasi.args_sizes_get (param i32, i32) (result i32))) 55 // (import "wasi_snapshot_preview1" "fd_write" (func $wasi.fd_write (param i32, i32, i32, i32) (result i32))) 56 // ) 57 input: &wasm.NameSection{ 58 FunctionNames: wasm.NameMap{ 59 {Index: wasm.Index(0), Name: "wasi.args_sizes_get"}, 60 {Index: wasm.Index(1), Name: "wasi.fd_write"}, 61 }, 62 }, 63 expected: []byte{ 64 subsectionIDFunctionNames, 0x25, // 37 bytes 65 0x02, // two function names 66 0x00, // the function index is zero 67 0x13, // the function name wasi.args_sizes_get is 19 bytes long 68 'w', 'a', 's', 'i', '.', 'a', 'r', 'g', 's', '_', 's', 'i', 'z', 'e', 's', '_', 'g', 'e', 't', 69 0x01, // the function index is one 70 0x0d, // the function name wasi.fd_write is 13 bytes long 71 'w', 'a', 's', 'i', '.', 'f', 'd', '_', 'w', 'r', 'i', 't', 'e', 72 }, 73 }, 74 { 75 name: "function with local names", 76 // (module 77 // (import "Math" "Mul" (func $mul (param $x f32) (param $y f32) (result f32))) 78 // (import "Math" "Add" (func $add (param $l f32) (param $r f32) (result f32))) 79 // ) 80 input: &wasm.NameSection{ 81 FunctionNames: wasm.NameMap{ 82 {Index: wasm.Index(0), Name: "mul"}, 83 {Index: wasm.Index(1), Name: "add"}, 84 }, 85 LocalNames: wasm.IndirectNameMap{ 86 {Index: wasm.Index(0), NameMap: wasm.NameMap{ 87 {Index: wasm.Index(0), Name: "x"}, 88 {Index: wasm.Index(1), Name: "y"}, 89 }}, 90 {Index: wasm.Index(1), NameMap: wasm.NameMap{ 91 {Index: wasm.Index(0), Name: "l"}, 92 {Index: wasm.Index(1), Name: "r"}, 93 }}, 94 }, 95 }, 96 expected: []byte{ 97 subsectionIDFunctionNames, 0x0b, // 7 bytes 98 0x02, // two function names 99 0x00, 0x03, 'm', 'u', 'l', // index 0, size of "mul", "mul" 100 0x01, 0x03, 'a', 'd', 'd', // index 1, size of "add", "add" 101 subsectionIDLocalNames, 0x11, // 17 bytes 102 0x02, // two functions 103 0x00, 0x02, // index 0 has 2 locals 104 0x00, 0x01, 'x', // index 0, size of "x", "x" 105 0x01, 0x01, 'y', // index 1, size of "y", "y" 106 0x01, 0x02, // index 1 has 2 locals 107 0x00, 0x01, 'l', // index 0, size of "l", "l" 108 0x01, 0x01, 'r', // index 1, size of "r", "r" 109 }, 110 }, 111 } 112 113 for _, tt := range tests { 114 tc := tt 115 116 t.Run(tc.name, func(t *testing.T) { 117 bytes := EncodeNameSectionData(tc.input) 118 require.Equal(t, tc.expected, bytes) 119 }) 120 } 121 } 122 123 func TestEncodeNameSubsection(t *testing.T) { 124 subsectionID := uint8(1) 125 name := []byte("simple") 126 require.Equal(t, []byte{ 127 subsectionID, 128 byte(1 + 6), // 1 is the size of 6 in LEB128 encoding 129 6, 's', 'i', 'm', 'p', 'l', 'e', 130 }, encodeNameSubsection(subsectionID, encodeSizePrefixed(name))) 131 } 132 133 func TestEncodeNameAssoc(t *testing.T) { 134 na := wasm.NameAssoc{Index: 1, Name: "hello"} 135 require.Equal(t, []byte{byte(na.Index), 5, 'h', 'e', 'l', 'l', 'o'}, encodeNameAssoc(na)) 136 } 137 138 func TestEncodeNameMap(t *testing.T) { 139 na := wasm.NameAssoc{Index: 1, Name: "hello"} 140 m := wasm.NameMap{na} 141 require.Equal(t, []byte{byte(1), byte(na.Index), 5, 'h', 'e', 'l', 'l', 'o'}, encodeNameMap(m)) 142 } 143 144 func TestEncodeSizePrefixed(t *testing.T) { 145 // We expect size in bytes (LEB128 encoded) then the bytes 146 require.Equal(t, []byte{5, 'h', 'e', 'l', 'l', 'o'}, encodeSizePrefixed([]byte("hello"))) 147 }