1
use wasm_encoder::{BlockType, Encode, Function, HeapType, Instruction, MemArg, ValType};
2

            
3
pub struct FunctionEmitter {
4
    bytes: Vec<u8>,
5
}
6

            
7
impl FunctionEmitter {
8
20473
    pub fn new() -> Self {
9
20473
        Self { bytes: Vec::new() }
10
20473
    }
11

            
12
19064
    pub fn finish(self, locals: &[(u32, ValType)]) -> Function {
13
19064
        let mut func = Function::new(locals.iter().copied());
14
19064
        func.raw(self.bytes);
15
19064
        func
16
19064
    }
17

            
18
132
    pub fn memory_init(&mut self, data_idx: u32, dst: u32, len: u32) {
19
132
        Instruction::I32Const(dst as i32).encode(&mut self.bytes);
20
132
        Instruction::I32Const(0).encode(&mut self.bytes);
21
132
        Instruction::I32Const(len as i32).encode(&mut self.bytes);
22
132
        Instruction::MemoryInit {
23
132
            mem: 0,
24
132
            data_index: data_idx,
25
132
        }
26
132
        .encode(&mut self.bytes);
27
132
    }
28

            
29
144700
    pub fn local_get(&mut self, idx: u32) {
30
144700
        Instruction::LocalGet(idx).encode(&mut self.bytes);
31
144700
    }
32

            
33
90548
    pub fn local_set(&mut self, idx: u32) {
34
90548
        Instruction::LocalSet(idx).encode(&mut self.bytes);
35
90548
    }
36

            
37
536
    pub fn local_tee(&mut self, idx: u32) {
38
536
        Instruction::LocalTee(idx).encode(&mut self.bytes);
39
536
    }
40

            
41
100182
    pub fn i32_const(&mut self, value: i32) {
42
100182
        Instruction::I32Const(value).encode(&mut self.bytes);
43
100182
    }
44

            
45
11676
    pub fn i64_const(&mut self, value: i64) {
46
11676
        Instruction::I64Const(value).encode(&mut self.bytes);
47
11676
    }
48

            
49
59913
    pub fn i32_add(&mut self) {
50
59913
        Instruction::I32Add.encode(&mut self.bytes);
51
59913
    }
52

            
53
2232
    pub fn i32_sub(&mut self) {
54
2232
        Instruction::I32Sub.encode(&mut self.bytes);
55
2232
    }
56

            
57
2092
    pub fn i32_eqz(&mut self) {
58
2092
        Instruction::I32Eqz.encode(&mut self.bytes);
59
2092
    }
60

            
61
2358
    pub fn i32_eq(&mut self) {
62
2358
        Instruction::I32Eq.encode(&mut self.bytes);
63
2358
    }
64

            
65
44
    pub fn i32_lt_s(&mut self) {
66
44
        Instruction::I32LtS.encode(&mut self.bytes);
67
44
    }
68

            
69
    pub fn i32_ge_s(&mut self) {
70
        Instruction::I32GeS.encode(&mut self.bytes);
71
    }
72

            
73
    pub fn i32_gt_s(&mut self) {
74
        Instruction::I32GtS.encode(&mut self.bytes);
75
    }
76

            
77
    pub fn i32_le_s(&mut self) {
78
        Instruction::I32LeS.encode(&mut self.bytes);
79
    }
80

            
81
536
    pub fn i32_ne(&mut self) {
82
536
        Instruction::I32Ne.encode(&mut self.bytes);
83
536
    }
84

            
85
536
    pub fn i32_shl(&mut self) {
86
536
        Instruction::I32Shl.encode(&mut self.bytes);
87
536
    }
88

            
89
536
    pub fn i32_or(&mut self) {
90
536
        Instruction::I32Or.encode(&mut self.bytes);
91
536
    }
92

            
93
    pub fn i64_ne(&mut self) {
94
        Instruction::I64Ne.encode(&mut self.bytes);
95
    }
96

            
97
3962
    pub fn i32_mul(&mut self) {
98
3962
        Instruction::I32Mul.encode(&mut self.bytes);
99
3962
    }
100

            
101
13498
    pub fn i32_load(&mut self, offset: u64) {
102
13498
        Instruction::I32Load(MemArg {
103
13498
            offset,
104
13498
            align: 2,
105
13498
            memory_index: 0,
106
13498
        })
107
13498
        .encode(&mut self.bytes);
108
13498
    }
109

            
110
3028
    pub fn i32_load8_u(&mut self, offset: u64) {
111
3028
        Instruction::I32Load8U(MemArg {
112
3028
            offset,
113
3028
            align: 0,
114
3028
            memory_index: 0,
115
3028
        })
116
3028
        .encode(&mut self.bytes);
117
3028
    }
118

            
119
308
    pub fn i64_load(&mut self, offset: u64) {
120
308
        Instruction::I64Load(MemArg {
121
308
            offset,
122
308
            align: 3,
123
308
            memory_index: 0,
124
308
        })
125
308
        .encode(&mut self.bytes);
126
308
    }
127

            
128
13373
    pub fn i32_ge_u(&mut self) {
129
13373
        Instruction::I32GeU.encode(&mut self.bytes);
130
13373
    }
131

            
132
7190
    pub fn struct_get(&mut self, type_idx: u32, field_idx: u32) {
133
7190
        Instruction::StructGet {
134
7190
            struct_type_index: type_idx,
135
7190
            field_index: field_idx,
136
7190
        }
137
7190
        .encode(&mut self.bytes);
138
7190
    }
139

            
140
4234
    pub fn if_block(&mut self, block_type: BlockType) {
141
4234
        Instruction::If(block_type).encode(&mut self.bytes);
142
4234
    }
143

            
144
3344
    pub fn else_block(&mut self) {
145
3344
        Instruction::Else.encode(&mut self.bytes);
146
3344
    }
147

            
148
8744
    pub fn i32_store_raw(&mut self) {
149
8744
        Instruction::I32Store(MemArg {
150
8744
            offset: 0,
151
8744
            align: 2,
152
8744
            memory_index: 0,
153
8744
        })
154
8744
        .encode(&mut self.bytes);
155
8744
    }
156

            
157
3740
    pub fn i64_store_raw(&mut self) {
158
3740
        Instruction::I64Store(MemArg {
159
3740
            offset: 0,
160
3740
            align: 3,
161
3740
            memory_index: 0,
162
3740
        })
163
3740
        .encode(&mut self.bytes);
164
3740
    }
165

            
166
2168
    pub fn i64_extend_i32_u(&mut self) {
167
2168
        Instruction::I64ExtendI32U.encode(&mut self.bytes);
168
2168
    }
169

            
170
2588
    pub fn i32_wrap_i64(&mut self) {
171
2588
        Instruction::I32WrapI64.encode(&mut self.bytes);
172
2588
    }
173

            
174
11229
    pub fn array_new_data(&mut self, type_idx: u32, data_idx: u32) {
175
11229
        Instruction::ArrayNewData {
176
11229
            array_type_index: type_idx,
177
11229
            array_data_index: data_idx,
178
11229
        }
179
11229
        .encode(&mut self.bytes);
180
11229
    }
181

            
182
11899
    pub fn array_get_u(&mut self, type_idx: u32) {
183
11899
        Instruction::ArrayGetU(type_idx).encode(&mut self.bytes);
184
11899
    }
185

            
186
1474
    pub fn array_new_default(&mut self, type_idx: u32) {
187
1474
        Instruction::ArrayNewDefault(type_idx).encode(&mut self.bytes);
188
1474
    }
189

            
190
1474
    pub fn array_set(&mut self, type_idx: u32) {
191
1474
        Instruction::ArraySet(type_idx).encode(&mut self.bytes);
192
1474
    }
193

            
194
1072
    pub fn array_len(&mut self) {
195
1072
        Instruction::ArrayLen.encode(&mut self.bytes);
196
1072
    }
197

            
198
15551
    pub fn block_start(&mut self) {
199
15551
        Instruction::Block(BlockType::Empty).encode(&mut self.bytes);
200
15551
    }
201

            
202
15551
    pub fn loop_start(&mut self) {
203
15551
        Instruction::Loop(BlockType::Empty).encode(&mut self.bytes);
204
15551
    }
205

            
206
34800
    pub fn block_end(&mut self) {
207
34800
        Instruction::End.encode(&mut self.bytes);
208
34800
    }
209

            
210
15551
    pub fn br(&mut self, depth: u32) {
211
15551
        Instruction::Br(depth).encode(&mut self.bytes);
212
15551
    }
213

            
214
15551
    pub fn br_if(&mut self, depth: u32) {
215
15551
        Instruction::BrIf(depth).encode(&mut self.bytes);
216
15551
    }
217

            
218
42259
    pub fn call(&mut self, func_idx: u32) {
219
42259
        Instruction::Call(func_idx).encode(&mut self.bytes);
220
42259
    }
221

            
222
75624
    pub fn store_u8_dynamic(&mut self, local_base: u32, offset: u32, value: u8) {
223
75624
        Instruction::LocalGet(local_base).encode(&mut self.bytes);
224
75624
        Instruction::I32Const(offset as i32).encode(&mut self.bytes);
225
75624
        Instruction::I32Add.encode(&mut self.bytes);
226
75624
        Instruction::I32Const(i32::from(value)).encode(&mut self.bytes);
227
75624
        Instruction::I32Store8(MemArg {
228
75624
            offset: 0,
229
75624
            align: 0,
230
75624
            memory_index: 0,
231
75624
        })
232
75624
        .encode(&mut self.bytes);
233
75624
    }
234

            
235
195628
    pub fn store_i32_dynamic(&mut self, local_base: u32, offset: u32, value: i32) {
236
195628
        Instruction::LocalGet(local_base).encode(&mut self.bytes);
237
195628
        Instruction::I32Const(offset as i32).encode(&mut self.bytes);
238
195628
        Instruction::I32Add.encode(&mut self.bytes);
239
195628
        Instruction::I32Const(value).encode(&mut self.bytes);
240
195628
        Instruction::I32Store(MemArg {
241
195628
            offset: 0,
242
195628
            align: 2,
243
195628
            memory_index: 0,
244
195628
        })
245
195628
        .encode(&mut self.bytes);
246
195628
    }
247

            
248
30414
    pub fn store_i64_dynamic(&mut self, local_base: u32, offset: u32, value: i64) {
249
30414
        Instruction::LocalGet(local_base).encode(&mut self.bytes);
250
30414
        Instruction::I32Const(offset as i32).encode(&mut self.bytes);
251
30414
        Instruction::I32Add.encode(&mut self.bytes);
252
30414
        Instruction::I64Const(value).encode(&mut self.bytes);
253
30414
        Instruction::I64Store(MemArg {
254
30414
            offset: 0,
255
30414
            align: 3,
256
30414
            memory_index: 0,
257
30414
        })
258
30414
        .encode(&mut self.bytes);
259
30414
    }
260

            
261
13639
    pub fn i32_store8_raw(&mut self) {
262
13639
        Instruction::I32Store8(MemArg {
263
13639
            offset: 0,
264
13639
            align: 0,
265
13639
            memory_index: 0,
266
13639
        })
267
13639
        .encode(&mut self.bytes);
268
13639
    }
269

            
270
1474
    pub fn i32_load16_u(&mut self, offset: u64) {
271
1474
        Instruction::I32Load16U(MemArg {
272
1474
            offset,
273
1474
            align: 1,
274
1474
            memory_index: 0,
275
1474
        })
276
1474
        .encode(&mut self.bytes);
277
1474
    }
278

            
279
1158
    pub fn struct_new(&mut self, type_idx: u32) {
280
1158
        Instruction::StructNew(type_idx).encode(&mut self.bytes);
281
1158
    }
282

            
283
1158
    pub fn ref_null(&mut self, type_idx: u32) {
284
1158
        Instruction::RefNull(HeapType::Concrete(type_idx)).encode(&mut self.bytes);
285
1158
    }
286

            
287
1740
    pub fn ref_is_null(&mut self) {
288
1740
        Instruction::RefIsNull.encode(&mut self.bytes);
289
1740
    }
290

            
291
19600
    pub fn end(&mut self) {
292
19600
        Instruction::End.encode(&mut self.bytes);
293
19600
    }
294
}
295

            
296
impl Default for FunctionEmitter {
297
    fn default() -> Self {
298
        Self::new()
299
    }
300
}