forked from M-Labs/nac3
unsafe Model::believe_value
This commit is contained in:
parent
7c7e1b3ab8
commit
36af473816
|
@ -18,7 +18,7 @@ impl<'ctx> Model<'ctx> for Any<'ctx> {
|
||||||
type Value = BasicValueEnum<'ctx>;
|
type Value = BasicValueEnum<'ctx>;
|
||||||
type Type = BasicTypeEnum<'ctx>;
|
type Type = BasicTypeEnum<'ctx>;
|
||||||
|
|
||||||
fn get_type<G: CodeGenerator + ?Sized>(
|
fn llvm_type<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
_generator: &G,
|
_generator: &G,
|
||||||
_ctx: &'ctx Context,
|
_ctx: &'ctx Context,
|
||||||
|
|
|
@ -50,8 +50,12 @@ impl<'ctx, Len: ArrayLen, Item: Model<'ctx>> Model<'ctx> for Array<Len, Item> {
|
||||||
type Value = ArrayValue<'ctx>;
|
type Value = ArrayValue<'ctx>;
|
||||||
type Type = ArrayType<'ctx>;
|
type Type = ArrayType<'ctx>;
|
||||||
|
|
||||||
fn get_type<G: CodeGenerator + ?Sized>(&self, generator: &G, ctx: &'ctx Context) -> Self::Type {
|
fn llvm_type<G: CodeGenerator + ?Sized>(
|
||||||
self.item.get_type(generator, ctx).array_type(self.len.length())
|
&self,
|
||||||
|
generator: &G,
|
||||||
|
ctx: &'ctx Context,
|
||||||
|
) -> Self::Type {
|
||||||
|
self.item.llvm_type(generator, ctx).array_type(self.len.length())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_type<T: BasicType<'ctx>, G: CodeGenerator + ?Sized>(
|
fn check_type<T: BasicType<'ctx>, G: CodeGenerator + ?Sized>(
|
||||||
|
@ -91,7 +95,7 @@ impl<'ctx, Len: ArrayLen, Item: Model<'ctx>> Instance<'ctx, Ptr<Array<Len, Item>
|
||||||
let zero = ctx.ctx.i32_type().const_zero();
|
let zero = ctx.ctx.i32_type().const_zero();
|
||||||
let ptr = unsafe { ctx.builder.build_in_bounds_gep(self.value, &[zero, i], "").unwrap() };
|
let ptr = unsafe { ctx.builder.build_in_bounds_gep(self.value, &[zero, i], "").unwrap() };
|
||||||
|
|
||||||
Ptr(self.model.0.item).believe_value(ptr)
|
unsafe { Ptr(self.model.0.item).believe_value(ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like `gep` but `i` is a constant.
|
/// Like `gep` but `i` is a constant.
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::codegen::{CodeGenContext, CodeGenerator};
|
||||||
pub struct ModelError(pub String);
|
pub struct ModelError(pub String);
|
||||||
|
|
||||||
impl ModelError {
|
impl ModelError {
|
||||||
// Append a context message to the error.
|
/// Append a context message to the error.
|
||||||
pub(super) fn under_context(mut self, context: &str) -> Self {
|
pub(super) fn under_context(mut self, context: &str) -> Self {
|
||||||
self.0.push_str(" ... in ");
|
self.0.push_str(" ... in ");
|
||||||
self.0.push_str(context);
|
self.0.push_str(context);
|
||||||
|
@ -47,7 +47,7 @@ impl ModelError {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ### Notes on converting between Inkwell and model.
|
/// ### Notes on converting between Inkwell and model/ge.
|
||||||
///
|
///
|
||||||
/// Suppose you have an [`IntValue`], and you want to pass it into a function that takes a [`Instance<'ctx, Int<Int32>>`]. You can do use
|
/// Suppose you have an [`IntValue`], and you want to pass it into a function that takes a [`Instance<'ctx, Int<Int32>>`]. You can do use
|
||||||
/// [`Model::check_value`] or [`Model::believe_value`].
|
/// [`Model::check_value`] or [`Model::believe_value`].
|
||||||
|
@ -68,7 +68,8 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
|
|
||||||
/// Return the [`BasicType`] of this model.
|
/// Return the [`BasicType`] of this model.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn get_type<G: CodeGenerator + ?Sized>(&self, generator: &G, ctx: &'ctx Context) -> Self::Type;
|
fn llvm_type<G: CodeGenerator + ?Sized>(&self, generator: &G, ctx: &'ctx Context)
|
||||||
|
-> Self::Type;
|
||||||
|
|
||||||
/// Get the number of bytes of the [`BasicType`] of this model.
|
/// Get the number of bytes of the [`BasicType`] of this model.
|
||||||
fn size_of<G: CodeGenerator + ?Sized>(
|
fn size_of<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -76,7 +77,7 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &'ctx Context,
|
ctx: &'ctx Context,
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
self.get_type(generator, ctx).size_of().unwrap()
|
self.llvm_type(generator, ctx).size_of().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a [`BasicType`] matches the [`BasicType`] of this model.
|
/// Check if a [`BasicType`] matches the [`BasicType`] of this model.
|
||||||
|
@ -89,9 +90,11 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
|
|
||||||
/// Create an instance from a value.
|
/// Create an instance from a value.
|
||||||
///
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
/// Caller must make sure the type of `value` and the type of this `model` are equivalent.
|
/// Caller must make sure the type of `value` and the type of this `model` are equivalent.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn believe_value(&self, value: Self::Value) -> Instance<'ctx, Self> {
|
unsafe fn believe_value(&self, value: Self::Value) -> Instance<'ctx, Self> {
|
||||||
Instance { model: *self, value }
|
Instance { model: *self, value }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +113,7 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
let Ok(value) = Self::Value::try_from(value) else {
|
let Ok(value) = Self::Value::try_from(value) else {
|
||||||
unreachable!("check_type() has bad implementation")
|
unreachable!("check_type() has bad implementation")
|
||||||
};
|
};
|
||||||
Ok(self.believe_value(value))
|
unsafe { Ok(self.believe_value(value)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a value on the stack and return its pointer.
|
// Allocate a value on the stack and return its pointer.
|
||||||
|
@ -119,8 +122,8 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &CodeGenContext<'ctx, '_>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
) -> Instance<'ctx, Ptr<Self>> {
|
) -> Instance<'ctx, Ptr<Self>> {
|
||||||
let p = ctx.builder.build_alloca(self.get_type(generator, ctx.ctx), "").unwrap();
|
let p = ctx.builder.build_alloca(self.llvm_type(generator, ctx.ctx), "").unwrap();
|
||||||
Ptr(*self).believe_value(p)
|
unsafe { Ptr(*self).believe_value(p) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate an array on the stack and return its pointer.
|
// Allocate an array on the stack and return its pointer.
|
||||||
|
@ -130,8 +133,9 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
ctx: &CodeGenContext<'ctx, '_>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
len: IntValue<'ctx>,
|
len: IntValue<'ctx>,
|
||||||
) -> Instance<'ctx, Ptr<Self>> {
|
) -> Instance<'ctx, Ptr<Self>> {
|
||||||
let p = ctx.builder.build_array_alloca(self.get_type(generator, ctx.ctx), len, "").unwrap();
|
let p =
|
||||||
Ptr(*self).believe_value(p)
|
ctx.builder.build_array_alloca(self.llvm_type(generator, ctx.ctx), len, "").unwrap();
|
||||||
|
unsafe { Ptr(*self).believe_value(p) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn var_alloca<G: CodeGenerator + ?Sized>(
|
fn var_alloca<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -140,9 +144,9 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
) -> Result<Instance<'ctx, Ptr<Self>>, String> {
|
) -> Result<Instance<'ctx, Ptr<Self>>, String> {
|
||||||
let ty = self.get_type(generator, ctx.ctx).as_basic_type_enum();
|
let ty = self.llvm_type(generator, ctx.ctx).as_basic_type_enum();
|
||||||
let p = generator.gen_var_alloc(ctx, ty, name)?;
|
let p = generator.gen_var_alloc(ctx, ty, name)?;
|
||||||
Ok(Ptr(*self).believe_value(p))
|
unsafe { Ok(Ptr(*self).believe_value(p)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn array_var_alloca<G: CodeGenerator + ?Sized>(
|
fn array_var_alloca<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -153,9 +157,9 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Result<Instance<'ctx, Ptr<Self>>, String> {
|
) -> Result<Instance<'ctx, Ptr<Self>>, String> {
|
||||||
// TODO: Remove ArraySliceValue
|
// TODO: Remove ArraySliceValue
|
||||||
let ty = self.get_type(generator, ctx.ctx).as_basic_type_enum();
|
let ty = self.llvm_type(generator, ctx.ctx).as_basic_type_enum();
|
||||||
let p = generator.gen_array_var_alloc(ctx, ty, len, name)?;
|
let p = generator.gen_array_var_alloc(ctx, ty, len, name)?;
|
||||||
Ok(Ptr(*self).believe_value(PointerValue::from(p)))
|
unsafe { Ok(Ptr(*self).believe_value(PointerValue::from(p))) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a constant array.
|
/// Allocate a constant array.
|
||||||
|
@ -176,7 +180,7 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = match self.get_type(generator, ctx).as_basic_type_enum() {
|
let value = match self.llvm_type(generator, ctx).as_basic_type_enum() {
|
||||||
BasicTypeEnum::ArrayType(t) => make!(t, BasicValueEnum::into_array_value),
|
BasicTypeEnum::ArrayType(t) => make!(t, BasicValueEnum::into_array_value),
|
||||||
BasicTypeEnum::IntType(t) => make!(t, BasicValueEnum::into_int_value),
|
BasicTypeEnum::IntType(t) => make!(t, BasicValueEnum::into_int_value),
|
||||||
BasicTypeEnum::FloatType(t) => make!(t, BasicValueEnum::into_float_value),
|
BasicTypeEnum::FloatType(t) => make!(t, BasicValueEnum::into_float_value),
|
||||||
|
|
|
@ -63,7 +63,11 @@ impl<'ctx, N: FloatKind<'ctx>> Model<'ctx> for Float<N> {
|
||||||
type Value = FloatValue<'ctx>;
|
type Value = FloatValue<'ctx>;
|
||||||
type Type = FloatType<'ctx>;
|
type Type = FloatType<'ctx>;
|
||||||
|
|
||||||
fn get_type<G: CodeGenerator + ?Sized>(&self, generator: &G, ctx: &'ctx Context) -> Self::Type {
|
fn llvm_type<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &G,
|
||||||
|
ctx: &'ctx Context,
|
||||||
|
) -> Self::Type {
|
||||||
self.0.get_float_type(generator, ctx)
|
self.0.get_float_type(generator, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl<'ctx, 'a, 'b, 'c, 'd, G: CodeGenerator + ?Sized> CallFunction<'ctx, 'a, 'b,
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn arg<M: Model<'ctx>>(mut self, arg: Instance<'ctx, M>) -> Self {
|
pub fn arg<M: Model<'ctx>>(mut self, arg: Instance<'ctx, M>) -> Self {
|
||||||
let arg = Arg {
|
let arg = Arg {
|
||||||
ty: arg.model.get_type(self.generator, self.ctx.ctx).as_basic_type_enum().into(),
|
ty: arg.model.llvm_type(self.generator, self.ctx.ctx).as_basic_type_enum().into(),
|
||||||
val: arg.value.as_basic_value_enum().into(),
|
val: arg.value.as_basic_value_enum().into(),
|
||||||
};
|
};
|
||||||
self.args.push(arg);
|
self.args.push(arg);
|
||||||
|
@ -73,7 +73,7 @@ impl<'ctx, 'a, 'b, 'c, 'd, G: CodeGenerator + ?Sized> CallFunction<'ctx, 'a, 'b,
|
||||||
/// Call the function and expect the function to return a value of type of `return_model`.
|
/// Call the function and expect the function to return a value of type of `return_model`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn returning<M: Model<'ctx>>(self, name: &str, return_model: M) -> Instance<'ctx, M> {
|
pub fn returning<M: Model<'ctx>>(self, name: &str, return_model: M) -> Instance<'ctx, M> {
|
||||||
let ret_ty = return_model.get_type(self.generator, self.ctx.ctx);
|
let ret_ty = return_model.llvm_type(self.generator, self.ctx.ctx);
|
||||||
|
|
||||||
let ret = self.call(|tys| ret_ty.fn_type(tys, false), name);
|
let ret = self.call(|tys| ret_ty.fn_type(tys, false), name);
|
||||||
let ret = BasicValueEnum::try_from(ret.as_any_value_enum()).unwrap(); // Must work
|
let ret = BasicValueEnum::try_from(ret.as_any_value_enum()).unwrap(); // Must work
|
||||||
|
|
|
@ -100,7 +100,11 @@ impl<'ctx, N: IntKind<'ctx>> Model<'ctx> for Int<N> {
|
||||||
type Value = IntValue<'ctx>;
|
type Value = IntValue<'ctx>;
|
||||||
type Type = IntType<'ctx>;
|
type Type = IntType<'ctx>;
|
||||||
|
|
||||||
fn get_type<G: CodeGenerator + ?Sized>(&self, generator: &G, ctx: &'ctx Context) -> Self::Type {
|
fn llvm_type<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &G,
|
||||||
|
ctx: &'ctx Context,
|
||||||
|
) -> Self::Type {
|
||||||
self.0.get_int_type(generator, ctx)
|
self.0.get_int_type(generator, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,8 +139,8 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
ctx: &'ctx Context,
|
ctx: &'ctx Context,
|
||||||
value: u64,
|
value: u64,
|
||||||
) -> Instance<'ctx, Self> {
|
) -> Instance<'ctx, Self> {
|
||||||
let value = self.get_type(generator, ctx).const_int(value, false);
|
let value = self.llvm_type(generator, ctx).const_int(value, false);
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_0<G: CodeGenerator + ?Sized>(
|
pub fn const_0<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -144,8 +148,8 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &'ctx Context,
|
ctx: &'ctx Context,
|
||||||
) -> Instance<'ctx, Self> {
|
) -> Instance<'ctx, Self> {
|
||||||
let value = self.get_type(generator, ctx).const_zero();
|
let value = self.llvm_type(generator, ctx).const_zero();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn const_1<G: CodeGenerator + ?Sized>(
|
pub fn const_1<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -161,8 +165,8 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &'ctx Context,
|
ctx: &'ctx Context,
|
||||||
) -> Instance<'ctx, Self> {
|
) -> Instance<'ctx, Self> {
|
||||||
let value = self.get_type(generator, ctx).const_all_ones();
|
let value = self.llvm_type(generator, ctx).const_all_ones();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn s_extend_or_bit_cast<G: CodeGenerator + ?Sized>(
|
pub fn s_extend_or_bit_cast<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -177,9 +181,9 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
);
|
);
|
||||||
let value = ctx
|
let value = ctx
|
||||||
.builder
|
.builder
|
||||||
.build_int_s_extend_or_bit_cast(value, self.get_type(generator, ctx.ctx), "")
|
.build_int_s_extend_or_bit_cast(value, self.llvm_type(generator, ctx.ctx), "")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn s_extend<G: CodeGenerator + ?Sized>(
|
pub fn s_extend<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -193,8 +197,8 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
< self.0.get_int_type(generator, ctx.ctx).get_bit_width()
|
< self.0.get_int_type(generator, ctx.ctx).get_bit_width()
|
||||||
);
|
);
|
||||||
let value =
|
let value =
|
||||||
ctx.builder.build_int_s_extend(value, self.get_type(generator, ctx.ctx), "").unwrap();
|
ctx.builder.build_int_s_extend(value, self.llvm_type(generator, ctx.ctx), "").unwrap();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn z_extend_or_bit_cast<G: CodeGenerator + ?Sized>(
|
pub fn z_extend_or_bit_cast<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -209,9 +213,9 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
);
|
);
|
||||||
let value = ctx
|
let value = ctx
|
||||||
.builder
|
.builder
|
||||||
.build_int_z_extend_or_bit_cast(value, self.get_type(generator, ctx.ctx), "")
|
.build_int_z_extend_or_bit_cast(value, self.llvm_type(generator, ctx.ctx), "")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn z_extend<G: CodeGenerator + ?Sized>(
|
pub fn z_extend<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -225,8 +229,8 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
< self.0.get_int_type(generator, ctx.ctx).get_bit_width()
|
< self.0.get_int_type(generator, ctx.ctx).get_bit_width()
|
||||||
);
|
);
|
||||||
let value =
|
let value =
|
||||||
ctx.builder.build_int_z_extend(value, self.get_type(generator, ctx.ctx), "").unwrap();
|
ctx.builder.build_int_z_extend(value, self.llvm_type(generator, ctx.ctx), "").unwrap();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn truncate_or_bit_cast<G: CodeGenerator + ?Sized>(
|
pub fn truncate_or_bit_cast<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -241,9 +245,9 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
);
|
);
|
||||||
let value = ctx
|
let value = ctx
|
||||||
.builder
|
.builder
|
||||||
.build_int_truncate_or_bit_cast(value, self.get_type(generator, ctx.ctx), "")
|
.build_int_truncate_or_bit_cast(value, self.llvm_type(generator, ctx.ctx), "")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn truncate<G: CodeGenerator + ?Sized>(
|
pub fn truncate<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -257,8 +261,8 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
> self.0.get_int_type(generator, ctx.ctx).get_bit_width()
|
> self.0.get_int_type(generator, ctx.ctx).get_bit_width()
|
||||||
);
|
);
|
||||||
let value =
|
let value =
|
||||||
ctx.builder.build_int_truncate(value, self.get_type(generator, ctx.ctx), "").unwrap();
|
ctx.builder.build_int_truncate(value, self.llvm_type(generator, ctx.ctx), "").unwrap();
|
||||||
self.believe_value(value)
|
unsafe { self.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `sext` or `trunc` an int to this model's int type. Does nothing if equal bit-widths.
|
/// `sext` or `trunc` an int to this model's int type. Does nothing if equal bit-widths.
|
||||||
|
@ -272,7 +276,7 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
let our_width = self.0.get_int_type(generator, ctx.ctx).get_bit_width();
|
let our_width = self.0.get_int_type(generator, ctx.ctx).get_bit_width();
|
||||||
match their_width.cmp(&our_width) {
|
match their_width.cmp(&our_width) {
|
||||||
Ordering::Less => self.s_extend(generator, ctx, value),
|
Ordering::Less => self.s_extend(generator, ctx, value),
|
||||||
Ordering::Equal => self.believe_value(value),
|
Ordering::Equal => unsafe { self.believe_value(value) },
|
||||||
Ordering::Greater => self.truncate(generator, ctx, value),
|
Ordering::Greater => self.truncate(generator, ctx, value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,7 +292,7 @@ impl<'ctx, N: IntKind<'ctx>> Int<N> {
|
||||||
let our_width = self.0.get_int_type(generator, ctx.ctx).get_bit_width();
|
let our_width = self.0.get_int_type(generator, ctx.ctx).get_bit_width();
|
||||||
match their_width.cmp(&our_width) {
|
match their_width.cmp(&our_width) {
|
||||||
Ordering::Less => self.z_extend(generator, ctx, value),
|
Ordering::Less => self.z_extend(generator, ctx, value),
|
||||||
Ordering::Equal => self.believe_value(value),
|
Ordering::Equal => unsafe { self.believe_value(value) },
|
||||||
Ordering::Greater => self.truncate(generator, ctx, value),
|
Ordering::Greater => self.truncate(generator, ctx, value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,19 +394,19 @@ impl<'ctx, N: IntKind<'ctx>> Instance<'ctx, Int<N>> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn add(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self {
|
pub fn add(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self {
|
||||||
let value = ctx.builder.build_int_add(self.value, other.value, "").unwrap();
|
let value = ctx.builder.build_int_add(self.value, other.value, "").unwrap();
|
||||||
self.model.believe_value(value)
|
unsafe { self.model.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn sub(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self {
|
pub fn sub(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self {
|
||||||
let value = ctx.builder.build_int_sub(self.value, other.value, "").unwrap();
|
let value = ctx.builder.build_int_sub(self.value, other.value, "").unwrap();
|
||||||
self.model.believe_value(value)
|
unsafe { self.model.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn mul(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self {
|
pub fn mul(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self {
|
||||||
let value = ctx.builder.build_int_mul(self.value, other.value, "").unwrap();
|
let value = ctx.builder.build_int_mul(self.value, other.value, "").unwrap();
|
||||||
self.model.believe_value(value)
|
unsafe { self.model.believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compare(
|
pub fn compare(
|
||||||
|
@ -412,6 +416,6 @@ impl<'ctx, N: IntKind<'ctx>> Instance<'ctx, Int<N>> {
|
||||||
other: Self,
|
other: Self,
|
||||||
) -> Instance<'ctx, Int<Bool>> {
|
) -> Instance<'ctx, Int<Bool>> {
|
||||||
let value = ctx.builder.build_int_compare(op, self.value, other.value, "").unwrap();
|
let value = ctx.builder.build_int_compare(op, self.value, other.value, "").unwrap();
|
||||||
Int(Bool).believe_value(value)
|
unsafe { Int(Bool).believe_value(value) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,13 @@ impl<'ctx, Item: Model<'ctx>> Model<'ctx> for Ptr<Item> {
|
||||||
type Value = PointerValue<'ctx>;
|
type Value = PointerValue<'ctx>;
|
||||||
type Type = PointerType<'ctx>;
|
type Type = PointerType<'ctx>;
|
||||||
|
|
||||||
fn get_type<G: CodeGenerator + ?Sized>(&self, generator: &G, ctx: &'ctx Context) -> Self::Type {
|
fn llvm_type<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &G,
|
||||||
|
ctx: &'ctx Context,
|
||||||
|
) -> Self::Type {
|
||||||
// TODO: LLVM 15: ctx.ptr_type(AddressSpace::default())
|
// TODO: LLVM 15: ctx.ptr_type(AddressSpace::default())
|
||||||
self.0.get_type(generator, ctx).ptr_type(AddressSpace::default())
|
self.0.llvm_type(generator, ctx).ptr_type(AddressSpace::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_type<T: BasicType<'ctx>, G: CodeGenerator + ?Sized>(
|
fn check_type<T: BasicType<'ctx>, G: CodeGenerator + ?Sized>(
|
||||||
|
@ -71,8 +75,8 @@ impl<'ctx, Item: Model<'ctx>> Ptr<Item> {
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &'ctx Context,
|
ctx: &'ctx Context,
|
||||||
) -> Instance<'ctx, Ptr<Item>> {
|
) -> Instance<'ctx, Ptr<Item>> {
|
||||||
let ptr = self.get_type(generator, ctx).const_null();
|
let ptr = self.llvm_type(generator, ctx).const_null();
|
||||||
self.believe_value(ptr)
|
unsafe { self.believe_value(ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cast a pointer into this model with [`inkwell::builder::Builder::build_pointer_cast`]
|
/// Cast a pointer into this model with [`inkwell::builder::Builder::build_pointer_cast`]
|
||||||
|
@ -87,9 +91,9 @@ impl<'ctx, Item: Model<'ctx>> Ptr<Item> {
|
||||||
// ```
|
// ```
|
||||||
// return self.believe_value(ptr);
|
// return self.believe_value(ptr);
|
||||||
// ```
|
// ```
|
||||||
let t = self.get_type(generator, ctx.ctx);
|
let t = self.llvm_type(generator, ctx.ctx);
|
||||||
let ptr = ctx.builder.build_pointer_cast(ptr, t, "").unwrap();
|
let ptr = ctx.builder.build_pointer_cast(ptr, t, "").unwrap();
|
||||||
self.believe_value(ptr)
|
unsafe { self.believe_value(ptr) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +106,7 @@ impl<'ctx, Item: Model<'ctx>> Instance<'ctx, Ptr<Item>> {
|
||||||
offset: IntValue<'ctx>,
|
offset: IntValue<'ctx>,
|
||||||
) -> Instance<'ctx, Ptr<Item>> {
|
) -> Instance<'ctx, Ptr<Item>> {
|
||||||
let p = unsafe { ctx.builder.build_in_bounds_gep(self.value, &[offset], "").unwrap() };
|
let p = unsafe { ctx.builder.build_in_bounds_gep(self.value, &[offset], "").unwrap() };
|
||||||
self.model.believe_value(p)
|
unsafe { self.model.believe_value(p) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Offset the pointer by [`inkwell::builder::Builder::build_in_bounds_gep`] by a constant offset.
|
/// Offset the pointer by [`inkwell::builder::Builder::build_in_bounds_gep`] by a constant offset.
|
||||||
|
@ -181,13 +185,13 @@ impl<'ctx, Item: Model<'ctx>> Instance<'ctx, Ptr<Item>> {
|
||||||
/// Check if the pointer is null with [`inkwell::builder::Builder::build_is_null`].
|
/// Check if the pointer is null with [`inkwell::builder::Builder::build_is_null`].
|
||||||
pub fn is_null(&self, ctx: &CodeGenContext<'ctx, '_>) -> Instance<'ctx, Int<Bool>> {
|
pub fn is_null(&self, ctx: &CodeGenContext<'ctx, '_>) -> Instance<'ctx, Int<Bool>> {
|
||||||
let value = ctx.builder.build_is_null(self.value, "").unwrap();
|
let value = ctx.builder.build_is_null(self.value, "").unwrap();
|
||||||
Int(Bool).believe_value(value)
|
unsafe { Int(Bool).believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the pointer is not null with [`inkwell::builder::Builder::build_is_not_null`].
|
/// Check if the pointer is not null with [`inkwell::builder::Builder::build_is_not_null`].
|
||||||
pub fn is_not_null(&self, ctx: &CodeGenContext<'ctx, '_>) -> Instance<'ctx, Int<Bool>> {
|
pub fn is_not_null(&self, ctx: &CodeGenContext<'ctx, '_>) -> Instance<'ctx, Int<Bool>> {
|
||||||
let value = ctx.builder.build_is_not_null(self.value, "").unwrap();
|
let value = ctx.builder.build_is_not_null(self.value, "").unwrap();
|
||||||
Int(Bool).believe_value(value)
|
unsafe { Int(Bool).believe_value(value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `memcpy` from another pointer.
|
/// `memcpy` from another pointer.
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl<'ctx, 'a, G: CodeGenerator + ?Sized> FieldTraversal<'ctx> for TypeFieldTrav
|
||||||
type Out<M> = (); // Checking types return nothing.
|
type Out<M> = (); // Checking types return nothing.
|
||||||
|
|
||||||
fn add<M: Model<'ctx>>(&mut self, _name: &'static str, model: M) -> Self::Out<M> {
|
fn add<M: Model<'ctx>>(&mut self, _name: &'static str, model: M) -> Self::Out<M> {
|
||||||
let t = model.get_type(self.generator, self.ctx).as_basic_type_enum();
|
let t = model.llvm_type(self.generator, self.ctx).as_basic_type_enum();
|
||||||
self.field_types.push(t);
|
self.field_types.push(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,11 @@ impl<'ctx, S: StructKind<'ctx>> Model<'ctx> for Struct<S> {
|
||||||
type Value = StructValue<'ctx>;
|
type Value = StructValue<'ctx>;
|
||||||
type Type = StructType<'ctx>;
|
type Type = StructType<'ctx>;
|
||||||
|
|
||||||
fn get_type<G: CodeGenerator + ?Sized>(&self, generator: &G, ctx: &'ctx Context) -> Self::Type {
|
fn llvm_type<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &G,
|
||||||
|
ctx: &'ctx Context,
|
||||||
|
) -> Self::Type {
|
||||||
self.0.get_struct_type(generator, ctx)
|
self.0.get_struct_type(generator, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +331,7 @@ impl<'ctx, S: StructKind<'ctx>> Instance<'ctx, Ptr<Struct<S>>> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ptr(field.model).believe_value(ptr)
|
unsafe { Ptr(field.model).believe_value(ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function equivalent to `.gep(...).load(...)`.
|
/// Convenience function equivalent to `.gep(...).load(...)`.
|
||||||
|
|
Loading…
Reference in New Issue