Skip to main content

waffle/
ir.rs

1//! Intermediate representation for Wasm.
2
3use crate::declare_entity;
4
5/// Types in waffle's IR.
6///
7/// These types correspond to (a subset of) the primitive Wasm value
8/// types: integers, floats, SIMD vectors, and function references
9/// (optionally typed).
10///
11/// Every SSA value in a function body has a `Type`, unless it is a
12/// tuple (multi-value or zero-value result).
13#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub enum Type {
15    /// A 32-bit integer. Signedness is unspecified: individual
16    /// operators specify how they handle sign.
17    I32,
18    /// A 64-bit integer. Signedness is unspecified: individual
19    /// operators specify how they handle sign.
20    I64,
21    /// A 32-bit IEEE 754 floating point value. Semantics around NaNs
22    /// are defined by individual operators; from the point of view of
23    /// IR scaffolding, floating-point values are bags of bits.
24    F32,
25    /// A 64-bit IEEE 754 floating point value. Semantics around NaNs
26    /// are defined by individual operators; from the point of view of
27    /// IR scaffolding, floating-point values are bags of bits.
28    F64,
29    /// A 128-bit SIMD vector value. Lanes and lane types are
30    /// specified by individual operators; from the point of view of
31    /// IR scaffolding, SIMD vector values are bags of bits.
32    V128,
33    /// A function reference.
34    FuncRef,
35    /// A typed function reference, optionally nullable, and with type
36    /// specified by a signature index in the module's signature
37    /// index-space.
38    TypedFuncRef(bool, u32),
39}
40impl From<wasmparser::ValType> for Type {
41    fn from(ty: wasmparser::ValType) -> Self {
42        match ty {
43            wasmparser::ValType::I32 => Type::I32,
44            wasmparser::ValType::I64 => Type::I64,
45            wasmparser::ValType::F32 => Type::F32,
46            wasmparser::ValType::F64 => Type::F64,
47            wasmparser::ValType::V128 => Type::V128,
48            wasmparser::ValType::Ref(r) => r.into(),
49        }
50    }
51}
52impl From<wasmparser::RefType> for Type {
53    fn from(ty: wasmparser::RefType) -> Self {
54        match ty.type_index() {
55            Some(idx) => {
56                let nullable = ty.is_nullable();
57                Type::TypedFuncRef(nullable, idx.as_module_index().unwrap())
58            }
59            None => Type::FuncRef,
60        }
61    }
62}
63
64impl std::fmt::Display for Type {
65    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
66        match self {
67            Type::I32 => write!(f, "i32"),
68            Type::I64 => write!(f, "i64"),
69            Type::F32 => write!(f, "f32"),
70            Type::F64 => write!(f, "f64"),
71            Type::V128 => write!(f, "v128"),
72            Type::FuncRef => write!(f, "funcref"),
73            Type::TypedFuncRef(nullable, idx) => write!(
74                f,
75                "funcref({}, {})",
76                if *nullable { "null" } else { "not_null" },
77                idx
78            ),
79        }
80    }
81}
82
83impl From<Type> for wasm_encoder::ValType {
84    fn from(ty: Type) -> wasm_encoder::ValType {
85        match ty {
86            Type::I32 => wasm_encoder::ValType::I32,
87            Type::I64 => wasm_encoder::ValType::I64,
88            Type::F32 => wasm_encoder::ValType::F32,
89            Type::F64 => wasm_encoder::ValType::F64,
90            Type::V128 => wasm_encoder::ValType::V128,
91            Type::FuncRef | Type::TypedFuncRef(..) => wasm_encoder::ValType::Ref(ty.into()),
92        }
93    }
94}
95
96impl From<Type> for wasm_encoder::RefType {
97    fn from(ty: Type) -> wasm_encoder::RefType {
98        match ty {
99            Type::FuncRef => wasm_encoder::RefType::FUNCREF,
100            Type::TypedFuncRef(nullable, idx) => wasm_encoder::RefType {
101                nullable,
102                heap_type: wasm_encoder::HeapType::Concrete(idx),
103            },
104            _ => panic!("Cannot convert {:?} into reftype", ty),
105        }
106    }
107}
108
109// Per-module index spaces:
110
111// A signature (list of parameter types and list of return types) in
112// the module.
113declare_entity!(Signature, "sig");
114// A function in the module.
115declare_entity!(Func, "func");
116// A global variable in the module.
117declare_entity!(Global, "global");
118// A table in the module.
119declare_entity!(Table, "table");
120// A memory in the module.
121declare_entity!(Memory, "memory");
122
123// Per-function index spaces:
124
125// A basic block in one function body.
126declare_entity!(Block, "block");
127// A local variable (storage slot) in one function body.
128declare_entity!(Local, "local");
129// An SSA value in one function body.
130declare_entity!(Value, "v");
131
132mod module;
133pub use module::*;
134mod func;
135pub use func::*;
136mod value;
137pub use value::*;
138mod display;
139pub use display::*;
140mod debug;
141pub use debug::*;