roc/compiler/gen_wasm/src/layout.rs
2021-10-09 16:46:59 +01:00

82 lines
2.2 KiB
Rust

use parity_wasm::elements::ValueType;
use roc_mono::layout::{Layout, UnionLayout};
use crate::{PTR_SIZE, PTR_TYPE};
// See README for background information on Wasm locals, memory and function calls
#[derive(Debug, Clone)]
pub enum WasmLayout {
// Primitive number value, without any stack memory.
// For example, Roc i8 is represented as Primitive(ValueType::I32, 1)
Primitive(ValueType, u32),
// Local pointer to stack memory
StackMemory { size: u32, alignment_bytes: u32 },
// Local pointer to heap memory
HeapMemory,
}
impl WasmLayout {
pub fn new(layout: &Layout) -> Self {
use roc_mono::layout::Builtin::*;
use UnionLayout::*;
use ValueType::*;
let size = layout.stack_size(PTR_SIZE);
let alignment_bytes = layout.alignment_bytes(PTR_SIZE);
match layout {
Layout::Builtin(Int32 | Int16 | Int8 | Int1 | Usize) => Self::Primitive(I32, size),
Layout::Builtin(Int64) => Self::Primitive(I64, size),
Layout::Builtin(Float32) => Self::Primitive(F32, size),
Layout::Builtin(Float64) => Self::Primitive(F64, size),
Layout::Builtin(
Int128
| Decimal
| Float128
| Str
| Dict(_, _)
| Set(_)
| List(_)
| EmptyStr
| EmptyList
| EmptyDict
| EmptySet,
)
| Layout::Struct(_)
| Layout::LambdaSet(_)
| Layout::Union(NonRecursive(_)) => Self::StackMemory {
size,
alignment_bytes,
},
Layout::Union(
Recursive(_)
| NonNullableUnwrapped(_)
| NullableWrapped { .. }
| NullableUnwrapped { .. },
)
| Layout::RecursivePointer => Self::HeapMemory,
}
}
pub fn value_type(&self) -> ValueType {
match self {
Self::Primitive(type_, _) => *type_,
_ => PTR_TYPE,
}
}
#[allow(dead_code)]
pub fn stack_memory(&self) -> u32 {
match self {
Self::StackMemory { size, .. } => *size,
_ => 0,
}
}
}