1#![deny(missing_docs)]
4
5use std::mem;
6
7pub struct Writer {
14 dst: Vec<u8>,
15 tmp: Vec<Vec<u8>>,
16}
17
18impl Writer {
19 pub fn new() -> Writer {
21 let mut w = Writer {
22 dst: Vec::new(),
23 tmp: Vec::new(),
24 };
25 wit_schema_version::VERSION.encode(&mut w.dst);
26 return w;
27 }
28
29 pub fn types(&mut self, cnt: u32) -> Types<'_> {
32 Types {
33 tmp: self.start_section(cnt),
34 dst: self,
35 }
36 }
37
38 pub fn imports(&mut self, cnt: u32) -> Imports<'_> {
41 Imports {
42 tmp: self.start_section(cnt),
43 dst: self,
44 }
45 }
46
47 pub fn funcs(&mut self, cnt: u32) -> Funcs<'_> {
50 Funcs {
51 tmp: self.start_section(cnt),
52 dst: self,
53 }
54 }
55
56 pub fn exports(&mut self, cnt: u32) -> Exports<'_> {
59 Exports {
60 tmp: self.start_section(cnt),
61 dst: self,
62 }
63 }
64
65 pub fn implements(&mut self, cnt: u32) -> Implements<'_> {
68 Implements {
69 tmp: self.start_section(cnt),
70 dst: self,
71 }
72 }
73
74 pub fn into_payload(self) -> Vec<u8> {
79 self.dst
80 }
81
82 pub fn into_custom_section(mut self) -> Vec<u8> {
84 let mut tmp = self.pop_tmp();
85 wit_schema_version::SECTION_NAME.encode(&mut tmp);
86 tmp.extend_from_slice(&self.dst);
87 let mut tmp2 = self.pop_tmp();
88 tmp2.push(0);
89 tmp.encode(&mut tmp2);
90 return tmp2;
91 }
92
93 fn pop_tmp(&mut self) -> Vec<u8> {
94 self.tmp.pop().unwrap_or(Vec::new())
95 }
96
97 fn push_tmp(&mut self, mut tmp: Vec<u8>) {
98 tmp.truncate(0);
99 self.tmp.push(tmp);
100 }
101
102 fn start_section(&mut self, cnt: u32) -> Vec<u8> {
103 let mut buf = self.pop_tmp();
104 if cnt > 0 {
105 cnt.encode(&mut buf);
106 }
107 buf
108 }
109
110 fn finish_section(&mut self, id: u8, data: Vec<u8>) {
111 if data.len() > 0 {
112 self.dst.push(id);
113 data.encode(&mut self.dst);
114 }
115 self.push_tmp(data);
116 }
117}
118
119pub struct Types<'a> {
121 dst: &'a mut Writer,
122 tmp: Vec<u8>,
123}
124
125impl Types<'_> {
126 pub fn add(
137 &mut self,
138 nparams: u32,
139 params: impl FnOnce(&mut Type<'_>),
140 nresults: u32,
141 results: impl FnOnce(&mut Type<'_>),
142 ) {
143 let mut t = Type {
144 dst: &mut self.tmp,
145 cnt: 0,
146 };
147 nparams.encode(t.dst);
148 params(&mut t);
149 assert_eq!(nparams, t.cnt);
150 t.cnt = 0;
151 nresults.encode(t.dst);
152 results(&mut t);
153 assert_eq!(nresults, t.cnt);
154 }
155}
156
157impl Drop for Types<'_> {
158 fn drop(&mut self) {
159 self.dst
160 .finish_section(0x00, mem::replace(&mut self.tmp, Vec::new()));
161 }
162}
163
164pub struct Type<'a> {
166 cnt: u32,
167 dst: &'a mut Vec<u8>,
168}
169
170#[allow(missing_docs)]
171#[rustfmt::skip]
172impl Type<'_> {
173 fn ty(&mut self, byte: u8) {
174 self.cnt += 1;
175 self.dst.push(byte);
176 }
177
178 pub fn s8(&mut self) { self.ty(0x00) }
179 pub fn s16(&mut self) { self.ty(0x01) }
180 pub fn s32(&mut self) { self.ty(0x02) }
181 pub fn s64(&mut self) { self.ty(0x03) }
182 pub fn u8(&mut self) { self.ty(0x04) }
183 pub fn u16(&mut self) { self.ty(0x05) }
184 pub fn u32(&mut self) { self.ty(0x06) }
185 pub fn u64(&mut self) { self.ty(0x07) }
186 pub fn f32(&mut self) { self.ty(0x08) }
187 pub fn f64(&mut self) { self.ty(0x09) }
188 pub fn string(&mut self) { self.ty(0x0a) }
189 pub fn externref(&mut self) { self.ty(0x0b) }
190 pub fn i32(&mut self) { self.ty(0x0c) }
191 pub fn i64(&mut self) { self.ty(0x0d) }
192}
193
194pub struct Imports<'a> {
196 dst: &'a mut Writer,
197 tmp: Vec<u8>,
198}
199
200impl Imports<'_> {
201 pub fn add(&mut self, module: &str, name: &str, ty: u32) {
203 module.encode(&mut self.tmp);
204 name.encode(&mut self.tmp);
205 ty.encode(&mut self.tmp);
206 }
207}
208
209impl Drop for Imports<'_> {
210 fn drop(&mut self) {
211 self.dst
212 .finish_section(0x01, mem::replace(&mut self.tmp, Vec::new()));
213 }
214}
215
216pub struct Funcs<'a> {
218 dst: &'a mut Writer,
219 tmp: Vec<u8>,
220}
221
222impl<'a> Funcs<'a> {
223 pub fn add(&mut self, ty: u32) -> Instructions<'a, '_> {
225 let mut dst = self.dst.pop_tmp();
226 ty.encode(&mut dst);
227 Instructions {
228 tmp: dst,
229 funcs: self,
230 }
231 }
232}
233
234impl Drop for Funcs<'_> {
235 fn drop(&mut self) {
236 self.dst
237 .finish_section(0x02, mem::replace(&mut self.tmp, Vec::new()));
238 }
239}
240
241pub struct Instructions<'a, 'b> {
243 tmp: Vec<u8>,
244 funcs: &'b mut Funcs<'a>,
245}
246
247#[allow(missing_docs)]
248#[rustfmt::skip]
249impl Instructions<'_, '_> {
250 pub fn arg_get(&mut self, arg: u32) {
251 self.tmp.push(0x00);
252 arg.encode(&mut self.tmp);
253 }
254
255 pub fn call_core(&mut self, func: u32) {
256 self.tmp.push(0x01);
257 func.encode(&mut self.tmp);
258 }
259
260 pub fn memory_to_string(&mut self, mem: u32) {
261 self.tmp.push(0x03);
262 mem.encode(&mut self.tmp);
263 }
264
265 pub fn string_to_memory(&mut self, malloc: u32, mem: u32) {
266 self.tmp.push(0x04);
267 malloc.encode(&mut self.tmp);
268 mem.encode(&mut self.tmp);
269 }
270
271 pub fn call_adapter(&mut self, func: u32) {
272 self.tmp.push(0x05);
273 func.encode(&mut self.tmp);
274 }
275
276 pub fn defer_call_core(&mut self, func: u32) {
277 self.tmp.push(0x06);
278 func.encode(&mut self.tmp);
279 }
280
281 pub fn i32_to_s8(&mut self) { self.tmp.push(0x07) }
282 pub fn i32_to_s8x(&mut self) { self.tmp.push(0x08) }
283 pub fn i32_to_u8(&mut self) { self.tmp.push(0x09) }
284 pub fn i32_to_s16(&mut self) { self.tmp.push(0x0a) }
285 pub fn i32_to_s16x(&mut self) { self.tmp.push(0x0b) }
286 pub fn i32_to_u16(&mut self) { self.tmp.push(0x0c) }
287 pub fn i32_to_s32(&mut self) { self.tmp.push(0x0d) }
288 pub fn i32_to_u32(&mut self) { self.tmp.push(0x0e) }
289 pub fn i32_to_s64(&mut self) { self.tmp.push(0x0f) }
290 pub fn i32_to_u64(&mut self) { self.tmp.push(0x10) }
291
292 pub fn i64_to_s8(&mut self) { self.tmp.push(0x11) }
293 pub fn i64_to_s8x(&mut self) { self.tmp.push(0x12) }
294 pub fn i64_to_u8(&mut self) { self.tmp.push(0x13) }
295 pub fn i64_to_s16(&mut self) { self.tmp.push(0x14) }
296 pub fn i64_to_s16x(&mut self) { self.tmp.push(0x15) }
297 pub fn i64_to_u16(&mut self) { self.tmp.push(0x16) }
298 pub fn i64_to_s32(&mut self) { self.tmp.push(0x17) }
299 pub fn i64_to_s32x(&mut self) { self.tmp.push(0x18) }
300 pub fn i64_to_u32(&mut self) { self.tmp.push(0x19) }
301 pub fn i64_to_s64(&mut self) { self.tmp.push(0x1a) }
302 pub fn i64_to_u64(&mut self) { self.tmp.push(0x1b) }
303
304 pub fn s8_to_i32(&mut self) { self.tmp.push(0x1c) }
305 pub fn u8_to_i32(&mut self) { self.tmp.push(0x1d) }
306 pub fn s16_to_i32(&mut self) { self.tmp.push(0x1e) }
307 pub fn u16_to_i32(&mut self) { self.tmp.push(0x1f) }
308 pub fn s32_to_i32(&mut self) { self.tmp.push(0x20) }
309 pub fn u32_to_i32(&mut self) { self.tmp.push(0x21) }
310 pub fn s64_to_i32(&mut self) { self.tmp.push(0x22) }
311 pub fn s64_to_i32x(&mut self) { self.tmp.push(0x23) }
312 pub fn u64_to_i32(&mut self) { self.tmp.push(0x24) }
313 pub fn u64_to_i32x(&mut self) { self.tmp.push(0x25) }
314
315 pub fn s8_to_i64(&mut self) { self.tmp.push(0x26) }
316 pub fn u8_to_i64(&mut self) { self.tmp.push(0x27) }
317 pub fn s16_to_i64(&mut self) { self.tmp.push(0x28) }
318 pub fn u16_to_i64(&mut self) { self.tmp.push(0x29) }
319 pub fn s32_to_i64(&mut self) { self.tmp.push(0x2a) }
320 pub fn u32_to_i64(&mut self) { self.tmp.push(0x2b) }
321 pub fn s64_to_i64(&mut self) { self.tmp.push(0x2c) }
322 pub fn u64_to_i64(&mut self) { self.tmp.push(0x2d) }
323}
324
325impl Drop for Instructions<'_, '_> {
326 fn drop(&mut self) {
327 self.tmp.push(0x02);
328 let buf = mem::replace(&mut self.tmp, Vec::new());
329 buf.encode(&mut self.funcs.tmp);
330 self.funcs.dst.push_tmp(buf);
331 }
332}
333
334pub struct Exports<'a> {
336 dst: &'a mut Writer,
337 tmp: Vec<u8>,
338}
339
340impl Exports<'_> {
341 pub fn add(&mut self, name: &str, func: u32) {
343 func.encode(&mut self.tmp);
344 name.encode(&mut self.tmp);
345 }
346}
347
348impl Drop for Exports<'_> {
349 fn drop(&mut self) {
350 self.dst
351 .finish_section(0x03, mem::replace(&mut self.tmp, Vec::new()));
352 }
353}
354
355pub struct Implements<'a> {
357 dst: &'a mut Writer,
358 tmp: Vec<u8>,
359}
360
361impl Implements<'_> {
362 pub fn add(&mut self, core_func: u32, adapter_func: u32) {
364 core_func.encode(&mut self.tmp);
365 adapter_func.encode(&mut self.tmp);
366 }
367}
368
369impl Drop for Implements<'_> {
370 fn drop(&mut self) {
371 self.dst
372 .finish_section(0x04, mem::replace(&mut self.tmp, Vec::new()));
373 }
374}
375
376trait Encode {
377 fn encode(&self, e: &mut Vec<u8>);
378}
379
380impl Encode for [u8] {
381 fn encode(&self, e: &mut Vec<u8>) {
382 self.len().encode(e);
383 e.extend_from_slice(self);
384 }
385}
386
387impl Encode for str {
388 fn encode(&self, e: &mut Vec<u8>) {
389 self.as_bytes().encode(e);
390 }
391}
392
393impl Encode for usize {
394 fn encode(&self, e: &mut Vec<u8>) {
395 assert!(*self <= u32::max_value() as usize);
396 (*self as u32).encode(e)
397 }
398}
399
400impl Encode for u32 {
401 fn encode(&self, e: &mut Vec<u8>) {
402 leb128::write::unsigned(e, (*self).into()).unwrap();
403 }
404}