1 package binary
2
3 import (
4 "bytes"
5 "fmt"
6 "io"
7
8 "github.com/tetratelabs/wazero/api"
9 "github.com/tetratelabs/wazero/internal/leb128"
10 "github.com/tetratelabs/wazero/internal/wasm"
11 )
12
13 func decodeTypeSection(enabledFeatures api.CoreFeatures, r *bytes.Reader) ([]wasm.FunctionType, error) {
14 vs, _, err := leb128.DecodeUint32(r)
15 if err != nil {
16 return nil, fmt.Errorf("get size of vector: %w", err)
17 }
18
19 result := make([]wasm.FunctionType, vs)
20 for i := uint32(0); i < vs; i++ {
21 if err = decodeFunctionType(enabledFeatures, r, &result[i]); err != nil {
22 return nil, fmt.Errorf("read %d-th type: %v", i, err)
23 }
24 }
25 return result, nil
26 }
27
28
29 func decodeImportSection(
30 r *bytes.Reader,
31 memorySizer memorySizer,
32 memoryLimitPages uint32,
33 enabledFeatures api.CoreFeatures,
34 ) (result []wasm.Import,
35 perModule map[string][]*wasm.Import,
36 funcCount, globalCount, memoryCount, tableCount wasm.Index, err error,
37 ) {
38 vs, _, err := leb128.DecodeUint32(r)
39 if err != nil {
40 err = fmt.Errorf("get size of vector: %w", err)
41 return
42 }
43
44 perModule = make(map[string][]*wasm.Import)
45 result = make([]wasm.Import, vs)
46 for i := uint32(0); i < vs; i++ {
47 imp := &result[i]
48 if err = decodeImport(r, i, memorySizer, memoryLimitPages, enabledFeatures, imp); err != nil {
49 return
50 }
51 switch imp.Type {
52 case wasm.ExternTypeFunc:
53 imp.IndexPerType = funcCount
54 funcCount++
55 case wasm.ExternTypeGlobal:
56 imp.IndexPerType = globalCount
57 globalCount++
58 case wasm.ExternTypeMemory:
59 imp.IndexPerType = memoryCount
60 memoryCount++
61 case wasm.ExternTypeTable:
62 imp.IndexPerType = tableCount
63 tableCount++
64 }
65 perModule[imp.Module] = append(perModule[imp.Module], imp)
66 }
67 return
68 }
69
70 func decodeFunctionSection(r *bytes.Reader) ([]uint32, error) {
71 vs, _, err := leb128.DecodeUint32(r)
72 if err != nil {
73 return nil, fmt.Errorf("get size of vector: %w", err)
74 }
75
76 result := make([]uint32, vs)
77 for i := uint32(0); i < vs; i++ {
78 if result[i], _, err = leb128.DecodeUint32(r); err != nil {
79 return nil, fmt.Errorf("get type index: %w", err)
80 }
81 }
82 return result, err
83 }
84
85 func decodeTableSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.Table, error) {
86 vs, _, err := leb128.DecodeUint32(r)
87 if err != nil {
88 return nil, fmt.Errorf("error reading size")
89 }
90 if vs > 1 {
91 if err := enabledFeatures.RequireEnabled(api.CoreFeatureReferenceTypes); err != nil {
92 return nil, fmt.Errorf("at most one table allowed in module as %w", err)
93 }
94 }
95
96 ret := make([]wasm.Table, vs)
97 for i := range ret {
98 err = decodeTable(r, enabledFeatures, &ret[i])
99 if err != nil {
100 return nil, err
101 }
102 }
103 return ret, nil
104 }
105
106 func decodeMemorySection(
107 r *bytes.Reader,
108 memorySizer memorySizer,
109 memoryLimitPages uint32,
110 ) (*wasm.Memory, error) {
111 vs, _, err := leb128.DecodeUint32(r)
112 if err != nil {
113 return nil, fmt.Errorf("error reading size")
114 }
115 if vs > 1 {
116 return nil, fmt.Errorf("at most one memory allowed in module, but read %d", vs)
117 } else if vs == 0 {
118
119 return nil, nil
120 }
121
122 return decodeMemory(r, memorySizer, memoryLimitPages)
123 }
124
125 func decodeGlobalSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.Global, error) {
126 vs, _, err := leb128.DecodeUint32(r)
127 if err != nil {
128 return nil, fmt.Errorf("get size of vector: %w", err)
129 }
130
131 result := make([]wasm.Global, vs)
132 for i := uint32(0); i < vs; i++ {
133 if err = decodeGlobal(r, enabledFeatures, &result[i]); err != nil {
134 return nil, fmt.Errorf("global[%d]: %w", i, err)
135 }
136 }
137 return result, nil
138 }
139
140 func decodeExportSection(r *bytes.Reader) ([]wasm.Export, map[string]*wasm.Export, error) {
141 vs, _, sizeErr := leb128.DecodeUint32(r)
142 if sizeErr != nil {
143 return nil, nil, fmt.Errorf("get size of vector: %v", sizeErr)
144 }
145
146 exportMap := make(map[string]*wasm.Export, vs)
147 exportSection := make([]wasm.Export, vs)
148 for i := wasm.Index(0); i < vs; i++ {
149 export := &exportSection[i]
150 err := decodeExport(r, export)
151 if err != nil {
152 return nil, nil, fmt.Errorf("read export: %w", err)
153 }
154 if _, ok := exportMap[export.Name]; ok {
155 return nil, nil, fmt.Errorf("export[%d] duplicates name %q", i, export.Name)
156 } else {
157 exportMap[export.Name] = export
158 }
159 }
160 return exportSection, exportMap, nil
161 }
162
163 func decodeStartSection(r *bytes.Reader) (*wasm.Index, error) {
164 vs, _, err := leb128.DecodeUint32(r)
165 if err != nil {
166 return nil, fmt.Errorf("get function index: %w", err)
167 }
168 return &vs, nil
169 }
170
171 func decodeElementSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.ElementSegment, error) {
172 vs, _, err := leb128.DecodeUint32(r)
173 if err != nil {
174 return nil, fmt.Errorf("get size of vector: %w", err)
175 }
176
177 result := make([]wasm.ElementSegment, vs)
178 for i := uint32(0); i < vs; i++ {
179 if err = decodeElementSegment(r, enabledFeatures, &result[i]); err != nil {
180 return nil, fmt.Errorf("read element: %w", err)
181 }
182 }
183 return result, nil
184 }
185
186 func decodeCodeSection(r *bytes.Reader) ([]wasm.Code, error) {
187 codeSectionStart := uint64(r.Len())
188 vs, _, err := leb128.DecodeUint32(r)
189 if err != nil {
190 return nil, fmt.Errorf("get size of vector: %w", err)
191 }
192
193 result := make([]wasm.Code, vs)
194 for i := uint32(0); i < vs; i++ {
195 err = decodeCode(r, codeSectionStart, &result[i])
196 if err != nil {
197 return nil, fmt.Errorf("read %d-th code segment: %v", i, err)
198 }
199 }
200 return result, nil
201 }
202
203 func decodeDataSection(r *bytes.Reader, enabledFeatures api.CoreFeatures) ([]wasm.DataSegment, error) {
204 vs, _, err := leb128.DecodeUint32(r)
205 if err != nil {
206 return nil, fmt.Errorf("get size of vector: %w", err)
207 }
208
209 result := make([]wasm.DataSegment, vs)
210 for i := uint32(0); i < vs; i++ {
211 if err = decodeDataSegment(r, enabledFeatures, &result[i]); err != nil {
212 return nil, fmt.Errorf("read data segment: %w", err)
213 }
214 }
215 return result, nil
216 }
217
218 func decodeDataCountSection(r *bytes.Reader) (count *uint32, err error) {
219 v, _, err := leb128.DecodeUint32(r)
220 if err != nil && err != io.EOF {
221
222 return nil, err
223 }
224 return &v, nil
225 }
226
View as plain text