use crate::Builder;
#[derive(Clone, Copy, Debug)]
pub struct Pointer<B: Builder> {
pub ty: B::Type,
pub base: PointerBase<B>,
}
#[derive(Clone, Copy, Debug)]
pub enum PointerBase<B: Builder> {
Address(B::Value),
StackSlot(B::StackSlot),
}
impl<B: Builder> Pointer<B> {
pub fn new_stack_slot(bcx: &mut B, ty: B::Type, name: &str) -> Self {
let slot = bcx.new_stack_slot_raw(ty, name);
Self { ty, base: PointerBase::StackSlot(slot) }
}
pub fn new_address(ty: B::Type, value: B::Value) -> Self {
Self { ty, base: PointerBase::Address(value) }
}
pub fn is_address(&self) -> bool {
matches!(self.base, PointerBase::Address(_))
}
pub fn is_stack_slot(&self) -> bool {
matches!(self.base, PointerBase::StackSlot(_))
}
pub fn into_address(self) -> Option<B::Value> {
match self.base {
PointerBase::Address(ptr) => Some(ptr),
PointerBase::StackSlot(_) => None,
}
}
pub fn into_stack_slot(self) -> Option<B::StackSlot> {
match self.base {
PointerBase::Address(_) => None,
PointerBase::StackSlot(slot) => Some(slot),
}
}
pub fn load(&self, bcx: &mut B, name: &str) -> B::Value {
match self.base {
PointerBase::Address(ptr) => bcx.load(self.ty, ptr, name),
PointerBase::StackSlot(slot) => bcx.stack_load(self.ty, slot, name),
}
}
pub fn store(&self, bcx: &mut B, value: B::Value) {
match self.base {
PointerBase::Address(ptr) => bcx.store(value, ptr),
PointerBase::StackSlot(slot) => bcx.stack_store(value, slot),
}
}
pub fn store_imm(&self, bcx: &mut B, value: i64) {
let value = bcx.iconst(self.ty, value);
self.store(bcx, value)
}
pub fn addr(&self, bcx: &mut B) -> B::Value {
match self.base {
PointerBase::Address(ptr) => ptr,
PointerBase::StackSlot(slot) => bcx.stack_addr(self.ty, slot),
}
}
}