mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00

Result makes sense where I have something meaningful to say to the user like "X is not implemented yet". And also for public functions that may interface with other parts of the project like Backend. But for private functions internal to gen_wasm, it's just unhelpful to get a stack trace to where the Result is unwrapped! I want a stack trace to the root cause. I always end up temporarily rewriting Err("oops") to panic!("oops") and then waiting for it to recompile. This feels like a more balanced approach, using each technique where it makes sense.
146 lines
4.3 KiB
Rust
146 lines
4.3 KiB
Rust
use crate::{copy_memory, LocalId, ALIGN_1, ALIGN_2, ALIGN_4, ALIGN_8};
|
|
use parity_wasm::elements::{Instruction, Instruction::*, ValueType};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum SymbolStorage {
|
|
VarPrimitive {
|
|
local_id: LocalId,
|
|
value_type: ValueType,
|
|
size: u32,
|
|
},
|
|
ParamPrimitive {
|
|
local_id: LocalId,
|
|
value_type: ValueType,
|
|
size: u32,
|
|
},
|
|
VarStackMemory {
|
|
local_id: LocalId,
|
|
size: u32,
|
|
offset: u32,
|
|
alignment_bytes: u32,
|
|
},
|
|
ParamStackMemory {
|
|
local_id: LocalId,
|
|
size: u32,
|
|
alignment_bytes: u32,
|
|
},
|
|
VarHeapMemory {
|
|
local_id: LocalId,
|
|
},
|
|
}
|
|
|
|
impl SymbolStorage {
|
|
pub fn local_id(&self) -> LocalId {
|
|
match self {
|
|
Self::ParamPrimitive { local_id, .. } => *local_id,
|
|
Self::ParamStackMemory { local_id, .. } => *local_id,
|
|
Self::VarPrimitive { local_id, .. } => *local_id,
|
|
Self::VarStackMemory { local_id, .. } => *local_id,
|
|
Self::VarHeapMemory { local_id, .. } => *local_id,
|
|
}
|
|
}
|
|
|
|
pub fn value_type(&self) -> ValueType {
|
|
match self {
|
|
Self::ParamPrimitive { value_type, .. } => *value_type,
|
|
Self::VarPrimitive { value_type, .. } => *value_type,
|
|
Self::ParamStackMemory { .. } => ValueType::I32,
|
|
Self::VarStackMemory { .. } => ValueType::I32,
|
|
Self::VarHeapMemory { .. } => ValueType::I32,
|
|
}
|
|
}
|
|
|
|
pub fn has_stack_memory(&self) -> bool {
|
|
match self {
|
|
Self::ParamStackMemory { .. } => true,
|
|
Self::VarStackMemory { .. } => true,
|
|
Self::ParamPrimitive { .. } => false,
|
|
Self::VarPrimitive { .. } => false,
|
|
Self::VarHeapMemory { .. } => false,
|
|
}
|
|
}
|
|
|
|
pub fn stack_size_and_alignment(&self) -> (u32, u32) {
|
|
match self {
|
|
Self::VarStackMemory {
|
|
size,
|
|
alignment_bytes,
|
|
..
|
|
}
|
|
| Self::ParamStackMemory {
|
|
size,
|
|
alignment_bytes,
|
|
..
|
|
} => (*size, *alignment_bytes),
|
|
|
|
_ => (0, 0),
|
|
}
|
|
}
|
|
|
|
pub fn copy_to_memory(
|
|
&self,
|
|
instructions: &mut Vec<Instruction>,
|
|
to_pointer: LocalId,
|
|
to_offset: u32,
|
|
) -> u32 {
|
|
match self {
|
|
Self::ParamPrimitive {
|
|
local_id,
|
|
value_type,
|
|
size,
|
|
..
|
|
}
|
|
| Self::VarPrimitive {
|
|
local_id,
|
|
value_type,
|
|
size,
|
|
..
|
|
} => {
|
|
let store_instruction = match (value_type, size) {
|
|
(ValueType::I64, 8) => I64Store(ALIGN_8, to_offset),
|
|
(ValueType::I32, 4) => I32Store(ALIGN_4, to_offset),
|
|
(ValueType::I32, 2) => I32Store16(ALIGN_2, to_offset),
|
|
(ValueType::I32, 1) => I32Store8(ALIGN_1, to_offset),
|
|
(ValueType::F32, 4) => F32Store(ALIGN_4, to_offset),
|
|
(ValueType::F64, 8) => F64Store(ALIGN_8, to_offset),
|
|
_ => {
|
|
panic!("Cannot store {:?} with alignment of {:?}", value_type, size);
|
|
}
|
|
};
|
|
instructions.push(GetLocal(to_pointer.0));
|
|
instructions.push(GetLocal(local_id.0));
|
|
instructions.push(store_instruction);
|
|
*size
|
|
}
|
|
|
|
Self::ParamStackMemory {
|
|
local_id,
|
|
size,
|
|
alignment_bytes,
|
|
}
|
|
| Self::VarStackMemory {
|
|
local_id,
|
|
size,
|
|
alignment_bytes,
|
|
..
|
|
} => {
|
|
copy_memory(
|
|
instructions,
|
|
*local_id,
|
|
to_pointer,
|
|
*size,
|
|
*alignment_bytes,
|
|
to_offset,
|
|
);
|
|
*size
|
|
}
|
|
|
|
Self::VarHeapMemory { local_id, .. } => {
|
|
instructions.push(GetLocal(to_pointer.0));
|
|
instructions.push(GetLocal(local_id.0));
|
|
instructions.push(I32Store(ALIGN_4, to_offset));
|
|
4
|
|
}
|
|
}
|
|
}
|
|
}
|