core: DO NOT MERGE - Add ArrayAllocaValue

This commit is contained in:
David Mak 2024-03-19 01:00:57 +08:00
parent bfb00523c9
commit faf7a0f8c0
1 changed files with 87 additions and 0 deletions

View File

@ -160,6 +160,93 @@ pub trait TypedArrayLikeMutator<'ctx, T, Index = IntValue<'ctx>>: UntypedArrayLi
}
}
#[derive(Copy, Clone)]
pub struct ArrayAllocaValue<'ctx>(PointerValue<'ctx>, IntValue<'ctx>, Option<&'ctx str>);
impl<'ctx> ArrayAllocaValue<'ctx> {
/// Creates an [`ListValue`] from a [`PointerValue`].
#[must_use]
pub fn from_ptr_val(
ptr: PointerValue<'ctx>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> Self {
ArrayAllocaValue(ptr, size, name)
}
/// Returns the underlying [`PointerValue`] pointing to the `list` instance.
#[must_use]
pub fn as_ptr_value(&self) -> PointerValue<'ctx> {
self.0
}
}
impl<'ctx> From<ArrayAllocaValue<'ctx>> for PointerValue<'ctx> {
fn from(value: ArrayAllocaValue<'ctx>) -> Self {
value.as_ptr_value()
}
}
impl<'ctx> ArrayLikeValue<'ctx> for ArrayAllocaValue<'ctx> {
fn cast_elem_to_type(
_: &mut CodeGenContext<'ctx, '_>,
value: BasicValueEnum<'ctx>,
) -> BasicValueEnum<'ctx> {
value
}
fn size<G: CodeGenerator + ?Sized>(
&self,
_: &mut CodeGenContext<'ctx, '_>,
_: &mut G,
) -> IntValue<'ctx> {
self.1
}
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
_: &mut G,
idx: IntValue<'ctx>,
name: Option<&str>,
) -> PointerValue<'ctx> {
let var_name = name
.map(|v| format!("{v}.addr"))
.unwrap_or_default();
ctx.builder.build_in_bounds_gep(
self.as_ptr_value(),
&[idx],
var_name.as_str(),
).unwrap()
}
fn ptr_offset<G: CodeGenerator + ?Sized>(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
generator: &mut G,
idx: IntValue<'ctx>,
name: Option<&str>,
) -> PointerValue<'ctx> {
debug_assert_eq!(idx.get_type(), generator.get_size_type(ctx.ctx));
let size = self.size(ctx, generator);
let in_range = ctx.builder.build_int_compare(IntPredicate::ULT, idx, size, "").unwrap();
ctx.make_assert(
generator,
in_range,
"0:IndexError",
"list index out of range",
[None, None, None],
ctx.current_loc,
);
unsafe {
self.ptr_offset_unchecked(ctx, generator, idx, name)
}
}
}
#[cfg(not(debug_assertions))]
pub fn assert_is_list<'ctx>(_value: PointerValue<'ctx>, _llvm_usize: IntType<'ctx>) {}