core_wasm_ast/
ast.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3use std::sync::Mutex;
4
5#[macro_export]
6macro_rules! body {
7    ($( $v:expr ),*) => {{
8        let mut body = vec![];
9        $(
10            body.extend_from_slice(&$v);
11        )*
12        body.push(ast::Value::new(ast::Instr::end));
13        ast::Value::new(body)
14    }};
15}
16
17#[macro_export]
18macro_rules! make_type {
19    {} => {
20        ast::Type {
21            params: vec![],
22            results: vec![],
23        }
24    };
25
26    {($( $arg:ident ),*) -> ()} => {{
27        use ast::NumType::*;
28
29        let mut t = ast::Type {
30            params: vec![],
31            results: vec![],
32        };
33        $(
34            t.params.push(ast::ValueType::NumType($arg));
35        )*;
36
37        t
38    }};
39
40    {($( $arg:ident ),*) -> $res:ident} => {{
41        use ast::NumType::*;
42
43        let mut t = ast::Type {
44            params: vec![],
45            results: vec![ast::ValueType::NumType($res)],
46        };
47        $(
48            t.params.push(ast::ValueType::NumType($arg));
49        )*;
50
51        t
52    }};
53}
54pub use body;
55pub use make_type;
56
57#[macro_export]
58macro_rules! make_value {
59    ($v:expr) => {
60        Arc::new(Mutex::new(ast::Value::new($v)))
61    };
62}
63pub use make_value;
64
65#[derive(Debug, PartialEq, Clone)]
66pub struct Value<T> {
67    pub value: T,
68    pub start_offset: usize,
69    pub end_offset: usize,
70}
71impl<T> Value<T> {
72    pub fn new(value: T) -> Self {
73        Self {
74            start_offset: 0,
75            end_offset: 0,
76            value,
77        }
78    }
79}
80
81pub type MutableValue<T> = Arc<Mutex<Value<T>>>;
82
83#[derive(Debug, Clone)]
84pub struct Memory {
85    pub min: Value<u32>,
86    pub max: Option<u32>,
87}
88
89#[derive(Debug, Clone)]
90pub struct Code {
91    pub size: Value<u32>,
92    pub locals: Vec<CodeLocal>,
93    pub body: MutableValue<Vec<Value<Instr>>>,
94}
95
96#[derive(Debug, Clone)]
97pub struct CodeLocal {
98    pub count: u32,
99    pub value_type: ValueType,
100}
101
102#[derive(Debug, PartialEq, Clone)]
103pub enum ValueType {
104    NumType(NumType),
105    // VectorType(),
106    // RefType(),
107}
108
109#[derive(Debug, PartialEq, Clone)]
110pub enum NumType {
111    I32,
112    I64,
113    F32,
114    F64,
115}
116
117#[derive(Debug, Clone)]
118pub enum Reftype {
119    Func,
120    Extern,
121}
122
123#[derive(Debug, Clone)]
124pub struct Limits {
125    pub min: u32,
126    pub max: Option<u32>,
127}
128
129#[derive(Debug, Clone)]
130pub struct Table {
131    pub reftype: Reftype,
132    pub limits: Limits,
133}
134
135#[derive(Debug, Clone)]
136pub struct DataSegment {
137    pub offset: Option<Value<Vec<Value<Instr>>>>,
138    pub bytes: Vec<u8>,
139    pub mode: DataSegmentMode,
140}
141
142#[derive(Debug, Clone, PartialEq)]
143pub enum DataSegmentMode {
144    Passive,
145    Active,
146}
147
148impl DataSegment {
149    pub fn compute_offset(&self) -> i64 {
150        let expr = &self.offset.as_ref().unwrap().value;
151        for instr in expr {
152            if let Instr::i32_const(v) = instr.value {
153                return v;
154            }
155        }
156
157        unreachable!("malformed data expression: {:?}", expr)
158    }
159}
160
161#[derive(Debug, PartialEq, Clone)]
162pub enum BlockType {
163    Empty,
164    ValueType(ValueType),
165    Typeidx(u32),
166}
167
168#[derive(Debug, Clone)]
169pub enum Instr {
170    unreachable,
171    nop,
172
173    call(MutableValue<u32>),
174    call_indirect(u32, u32),
175
176    drop,
177    select,
178
179    local_get(u32),
180    local_set(u32),
181    local_tee(u32),
182    global_get(u32),
183    global_set(u32),
184    table_get(u32),
185    table_set(u32),
186
187    i32_load(MutableValue<u32>, u32),
188    i64_load(MutableValue<u32>, u32),
189    f32_load(MutableValue<u32>, u32),
190    f64_load(MutableValue<u32>, u32),
191    i32_load8_s(MutableValue<u32>, u32),
192    i32_load8_u(MutableValue<u32>, u32),
193    i32_load16_s(MutableValue<u32>, u32),
194    i32_load16_u(MutableValue<u32>, u32),
195    i64_load8_s(MutableValue<u32>, u32),
196    i64_load8_u(MutableValue<u32>, u32),
197    i64_load16_s(MutableValue<u32>, u32),
198    i64_load16_u(MutableValue<u32>, u32),
199    i64_load32_s(MutableValue<u32>, u32),
200    i64_load32_u(MutableValue<u32>, u32),
201
202    i32_store(MutableValue<u32>, u32),
203    i64_store(MutableValue<u32>, u32),
204    f32_store(MutableValue<u32>, u32),
205    f64_store(MutableValue<u32>, u32),
206    i32_store8(MutableValue<u32>, u32),
207    i32_store16(MutableValue<u32>, u32),
208    i64_store8(MutableValue<u32>, u32),
209    i64_store16(MutableValue<u32>, u32),
210    i64_store32(MutableValue<u32>, u32),
211
212    memory_size(u8),
213    memory_grow(u8),
214    memory_copy(u8, u8),
215    memory_fill(u8),
216
217    br(u32),
218    br_if(u32),
219    br_table(Vec<u32>, u32),
220    else_end,
221    end,
222    Return,
223    Block(BlockType, MutableValue<Vec<Value<Instr>>>),
224    Loop(BlockType, MutableValue<Vec<Value<Instr>>>),
225    If(BlockType, MutableValue<Vec<Value<Instr>>>),
226
227    i32_const(i64),
228    i64_const(i64),
229    f32_const(f32),
230    f64_const(f64),
231    i32_eqz,
232    i32_eq,
233    i32_ne,
234    i32_lt_s,
235    i32_lt_u,
236    i32_gt_s,
237    i32_gt_u,
238    i32_le_s,
239    i32_le_u,
240    i32_ge_s,
241    i32_ge_u,
242
243    i64_eqz,
244    i64_eq,
245    i64_ne,
246    i64_lt_s,
247    i64_lt_u,
248    i64_gt_s,
249    i64_gt_u,
250    i64_le_s,
251    i64_le_u,
252    i64_ge_s,
253    i64_ge_u,
254
255    f32_eq,
256    f32_ne,
257    f32_lt,
258    f32_gt,
259    f32_le,
260    f32_ge,
261
262    f64_eq,
263    f64_ne,
264    f64_lt,
265    f64_gt,
266    f64_le,
267    f64_ge,
268
269    i32_clz,
270    i32_ctz,
271    i32_popcnt,
272    i32_add,
273    i32_sub,
274    i32_mul,
275    i32_div_s,
276    i32_div_u,
277    i32_rem_s,
278    i32_rem_u,
279    i32_and,
280    i32_or,
281    i32_xor,
282    i32_shl,
283    i32_shr_s,
284    i32_shr_u,
285    i32_rotl,
286    i32_rotr,
287
288    i64_clz,
289    i64_ctz,
290    i64_popcnt,
291    i64_add,
292    i64_sub,
293    i64_mul,
294    i64_div_s,
295    i64_div_u,
296    i64_rem_s,
297    i64_rem_u,
298    i64_and,
299    i64_or,
300    i64_xor,
301    i64_shl,
302    i64_shr_s,
303    i64_shr_u,
304    i64_rotl,
305    i64_rotr,
306
307    f32_abs,
308    f32_neg,
309    f32_ceil,
310    f32_floor,
311    f32_trunc,
312    f32_nearest,
313    f32_sqrt,
314    f32_add,
315    f32_sub,
316    f32_mul,
317    f32_div,
318    f32_min,
319    f32_max,
320    f32_copysign,
321
322    f64_abs,
323    f64_neg,
324    f64_ceil,
325    f64_floor,
326    f64_trunc,
327    f64_nearest,
328    f64_sqrt,
329    f64_add,
330    f64_sub,
331    f64_mul,
332    f64_div,
333    f64_min,
334    f64_max,
335    f64_copysign,
336
337    i32_wrap_i64,
338    i32_trunc_f32_s,
339    i32_trunc_f32_u,
340    i32_trunc_f64_s,
341    i32_trunc_f64_u,
342    i32_trunc_sat_f32_s,
343    i32_trunc_sat_f32_u,
344    i32_trunc_sat_f64_s,
345    i32_trunc_sat_f64_u,
346    i64_extend_i32_s,
347    i64_extend_i32_u,
348    i64_trunc_f32_s,
349    i64_trunc_f32_u,
350    i64_trunc_f64_s,
351    i64_trunc_f64_u,
352    i64_trunc_sat_f32_s,
353    i64_trunc_sat_f32_u,
354    i64_trunc_sat_f64_s,
355    i64_trunc_sat_f64_u,
356    f32_convert_i32_s,
357    f32_convert_i32_u,
358    f32_convert_i64_s,
359    f32_convert_i64_u,
360    f32_demote_f64,
361    f64_convert_i32_s,
362    f64_convert_i32_u,
363    f64_convert_i64_s,
364    f64_convert_i64_u,
365    f64_promote_f32,
366
367    i32_reinterpret_f32,
368    i64_reinterpret_f64,
369    f32_reinterpret_i32,
370    f64_reinterpret_i64,
371
372    i32_extend8_s,
373    i32_extend16_s,
374    i64_extend8_s,
375    i64_extend16_s,
376    i64_extend32_s,
377}
378
379pub type Expr = Value<Vec<Value<Instr>>>;
380
381#[derive(Debug, Clone)]
382pub enum Section {
383    /// (Size, Section)
384    Memory((Value<u32>, Vec<Memory>)),
385    Data((Value<u32>, Arc<Mutex<Vec<DataSegment>>>)),
386    Code((Value<u32>, MutableValue<Vec<Code>>)),
387    Type((Value<u32>, Arc<Mutex<Vec<Type>>>)),
388    Func((Value<u32>, Arc<Mutex<Vec<u32>>>)),
389    Import((Value<u32>, Arc<Mutex<Vec<Import>>>)),
390    Table((Value<u32>, Arc<Mutex<Vec<Table>>>)),
391    Export((Value<u32>, Arc<Mutex<Vec<Export>>>)),
392    Element((Value<u32>, Arc<Mutex<Vec<Element>>>)),
393    Custom((Value<u32>, Arc<Mutex<CustomSection>>)),
394    Global((Value<u32>, Arc<Mutex<Vec<Global>>>)),
395    /// (Id, Size, Section)
396    Unknown((u8, u32, Vec<u8>)),
397}
398
399impl Value<Section> {
400    pub fn pos(&self) -> usize {
401        use Section::*;
402
403        match self.value {
404            Type(_) => 1,
405            Import(_) => 2,
406            Func(_) => 3,
407            Table(_) => 4,
408            Memory(_) => 5,
409            Global(_) => 6,
410            Export(_) => 7,
411            // Start(_) => 8,
412            Element(_) => 9,
413            Code(_) => 10,
414            Data(_) => 11,
415            Custom(_) | Unknown(_) => 99,
416        }
417    }
418}
419
420#[derive(Debug, Clone)]
421pub enum CustomSection {
422    Unknown(String, Vec<u8>),
423    Name(DebugNames),
424    CoredumpCore(wasm_coredump_types::ProcessInfo),
425    CoredumpCoreStack(wasm_coredump_types::CoreStack),
426    BuildId(Vec<u8>),
427}
428
429#[derive(Debug)]
430pub struct Module {
431    pub sections: Arc<Mutex<Vec<Value<Section>>>>,
432}
433
434#[derive(Debug, Clone)]
435pub struct Type {
436    pub params: Vec<ValueType>,
437    pub results: Vec<ValueType>,
438}
439
440#[derive(Debug, Clone)]
441pub struct Import {
442    pub module: String,
443    pub name: String,
444    pub import_type: ImportType,
445}
446
447#[derive(Debug, Clone)]
448pub enum ImportType {
449    Func(u32),
450    Table(Table),
451    Memory(Memory),
452    Global(GlobalType),
453}
454
455#[derive(Debug, Clone)]
456pub struct Export {
457    pub name: String,
458    pub descr: ExportDescr,
459}
460
461#[derive(Debug, Clone)]
462pub enum ExportDescr {
463    Func(Arc<Mutex<u32>>),
464    Table(Arc<Mutex<u32>>),
465    Mem(Arc<Mutex<u32>>),
466    Global(Arc<Mutex<u32>>),
467}
468
469#[derive(Debug, Clone)]
470pub enum Element {
471    FuncActive(Expr, Arc<Mutex<Vec<u32>>>),
472}
473
474#[derive(Debug, Clone)]
475pub struct Global {
476    pub global_type: GlobalType,
477    pub expr: Expr,
478}
479
480impl Global {
481    pub fn compute_value(&self) -> i64 {
482        let expr = &self.expr.value;
483        if !self.global_type.mutable {
484            for instr in expr {
485                if let Instr::i32_const(v) = instr.value {
486                    return v;
487                }
488            }
489        }
490
491        unreachable!("unsupported global expression: {:?}", expr)
492    }
493}
494
495#[derive(Debug, Clone)]
496pub struct GlobalType {
497    pub valtype: ValueType,
498    pub mutable: bool,
499}
500
501#[derive(Debug, Clone)]
502pub struct DebugNames {
503    pub module: Option<String>,
504    pub func_names: Option<Arc<Mutex<HashMap<u32, String>>>>,
505    pub func_local_names: Option<HashMap<u32, HashMap<u32, String>>>,
506    pub global_names: Arc<Mutex<HashMap<u32, String>>>,
507}