core: DO NOT MERGE - Add ArrayAllocaValue
This commit is contained in:
parent
bfb00523c9
commit
faf7a0f8c0
|
@ -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>) {}
|
||||
|
||||
|
|
Loading…
Reference in New Issue