From 36af473816c7867e6b9b1c055ef7fc71169e5f18 Mon Sep 17 00:00:00 2001 From: lyken Date: Tue, 27 Aug 2024 17:18:01 +0800 Subject: [PATCH] unsafe Model::believe_value --- nac3core/src/codegen/model/any.rs | 2 +- nac3core/src/codegen/model/array.rs | 10 +++-- nac3core/src/codegen/model/core.rs | 34 +++++++++------- nac3core/src/codegen/model/float.rs | 6 ++- nac3core/src/codegen/model/function.rs | 4 +- nac3core/src/codegen/model/int.rs | 54 +++++++++++++------------ nac3core/src/codegen/model/ptr.rs | 22 +++++----- nac3core/src/codegen/model/structure.rs | 10 +++-- 8 files changed, 83 insertions(+), 59 deletions(-) diff --git a/nac3core/src/codegen/model/any.rs b/nac3core/src/codegen/model/any.rs index 9df863e8..cdf21d17 100644 --- a/nac3core/src/codegen/model/any.rs +++ b/nac3core/src/codegen/model/any.rs @@ -18,7 +18,7 @@ impl<'ctx> Model<'ctx> for Any<'ctx> { type Value = BasicValueEnum<'ctx>; type Type = BasicTypeEnum<'ctx>; - fn get_type( + fn llvm_type( &self, _generator: &G, _ctx: &'ctx Context, diff --git a/nac3core/src/codegen/model/array.rs b/nac3core/src/codegen/model/array.rs index 81c7a401..7191da6d 100644 --- a/nac3core/src/codegen/model/array.rs +++ b/nac3core/src/codegen/model/array.rs @@ -50,8 +50,12 @@ impl<'ctx, Len: ArrayLen, Item: Model<'ctx>> Model<'ctx> for Array { type Value = ArrayValue<'ctx>; type Type = ArrayType<'ctx>; - fn get_type(&self, generator: &G, ctx: &'ctx Context) -> Self::Type { - self.item.get_type(generator, ctx).array_type(self.len.length()) + fn llvm_type( + &self, + generator: &G, + ctx: &'ctx Context, + ) -> Self::Type { + self.item.llvm_type(generator, ctx).array_type(self.len.length()) } fn check_type, G: CodeGenerator + ?Sized>( @@ -91,7 +95,7 @@ impl<'ctx, Len: ArrayLen, Item: Model<'ctx>> Instance<'ctx, Ptr let zero = ctx.ctx.i32_type().const_zero(); 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. diff --git a/nac3core/src/codegen/model/core.rs b/nac3core/src/codegen/model/core.rs index 5ff34d10..a9da660a 100644 --- a/nac3core/src/codegen/model/core.rs +++ b/nac3core/src/codegen/model/core.rs @@ -11,7 +11,7 @@ use crate::codegen::{CodeGenContext, CodeGenerator}; pub struct ModelError(pub String); 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 { self.0.push_str(" ... in "); 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>`]. You can do use /// [`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. #[must_use] - fn get_type(&self, generator: &G, ctx: &'ctx Context) -> Self::Type; + fn llvm_type(&self, generator: &G, ctx: &'ctx Context) + -> Self::Type; /// Get the number of bytes of the [`BasicType`] of this model. fn size_of( @@ -76,7 +77,7 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy { generator: &mut G, ctx: &'ctx Context, ) -> 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. @@ -89,9 +90,11 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy { /// Create an instance from a value. /// + /// # Safety + /// /// Caller must make sure the type of `value` and the type of this `model` are equivalent. #[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 } } @@ -110,7 +113,7 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy { let Ok(value) = Self::Value::try_from(value) else { 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. @@ -119,8 +122,8 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy { generator: &mut G, ctx: &CodeGenContext<'ctx, '_>, ) -> Instance<'ctx, Ptr> { - let p = ctx.builder.build_alloca(self.get_type(generator, ctx.ctx), "").unwrap(); - Ptr(*self).believe_value(p) + let p = ctx.builder.build_alloca(self.llvm_type(generator, ctx.ctx), "").unwrap(); + unsafe { Ptr(*self).believe_value(p) } } // 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, '_>, len: IntValue<'ctx>, ) -> Instance<'ctx, Ptr> { - let p = ctx.builder.build_array_alloca(self.get_type(generator, ctx.ctx), len, "").unwrap(); - Ptr(*self).believe_value(p) + let p = + ctx.builder.build_array_alloca(self.llvm_type(generator, ctx.ctx), len, "").unwrap(); + unsafe { Ptr(*self).believe_value(p) } } fn var_alloca( @@ -140,9 +144,9 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy { ctx: &mut CodeGenContext<'ctx, '_>, name: Option<&str>, ) -> Result>, 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)?; - Ok(Ptr(*self).believe_value(p)) + unsafe { Ok(Ptr(*self).believe_value(p)) } } fn array_var_alloca( @@ -153,9 +157,9 @@ pub trait Model<'ctx>: fmt::Debug + Clone + Copy { name: Option<&'ctx str>, ) -> Result>, String> { // 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)?; - Ok(Ptr(*self).believe_value(PointerValue::from(p))) + unsafe { Ok(Ptr(*self).believe_value(PointerValue::from(p))) } } /// 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::IntType(t) => make!(t, BasicValueEnum::into_int_value), BasicTypeEnum::FloatType(t) => make!(t, BasicValueEnum::into_float_value), diff --git a/nac3core/src/codegen/model/float.rs b/nac3core/src/codegen/model/float.rs index 88bff80b..6636d614 100644 --- a/nac3core/src/codegen/model/float.rs +++ b/nac3core/src/codegen/model/float.rs @@ -63,7 +63,11 @@ impl<'ctx, N: FloatKind<'ctx>> Model<'ctx> for Float { type Value = FloatValue<'ctx>; type Type = FloatType<'ctx>; - fn get_type(&self, generator: &G, ctx: &'ctx Context) -> Self::Type { + fn llvm_type( + &self, + generator: &G, + ctx: &'ctx Context, + ) -> Self::Type { self.0.get_float_type(generator, ctx) } diff --git a/nac3core/src/codegen/model/function.rs b/nac3core/src/codegen/model/function.rs index 7ff2d746..0b9d4d37 100644 --- a/nac3core/src/codegen/model/function.rs +++ b/nac3core/src/codegen/model/function.rs @@ -63,7 +63,7 @@ impl<'ctx, 'a, 'b, 'c, 'd, G: CodeGenerator + ?Sized> CallFunction<'ctx, 'a, 'b, #[must_use] pub fn arg>(mut self, arg: Instance<'ctx, M>) -> Self { 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(), }; 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`. #[must_use] pub fn returning>(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 = BasicValueEnum::try_from(ret.as_any_value_enum()).unwrap(); // Must work diff --git a/nac3core/src/codegen/model/int.rs b/nac3core/src/codegen/model/int.rs index 3a8a4fe3..db262b28 100644 --- a/nac3core/src/codegen/model/int.rs +++ b/nac3core/src/codegen/model/int.rs @@ -100,7 +100,11 @@ impl<'ctx, N: IntKind<'ctx>> Model<'ctx> for Int { type Value = IntValue<'ctx>; type Type = IntType<'ctx>; - fn get_type(&self, generator: &G, ctx: &'ctx Context) -> Self::Type { + fn llvm_type( + &self, + generator: &G, + ctx: &'ctx Context, + ) -> Self::Type { self.0.get_int_type(generator, ctx) } @@ -135,8 +139,8 @@ impl<'ctx, N: IntKind<'ctx>> Int { ctx: &'ctx Context, value: u64, ) -> Instance<'ctx, Self> { - let value = self.get_type(generator, ctx).const_int(value, false); - self.believe_value(value) + let value = self.llvm_type(generator, ctx).const_int(value, false); + unsafe { self.believe_value(value) } } pub fn const_0( @@ -144,8 +148,8 @@ impl<'ctx, N: IntKind<'ctx>> Int { generator: &mut G, ctx: &'ctx Context, ) -> Instance<'ctx, Self> { - let value = self.get_type(generator, ctx).const_zero(); - self.believe_value(value) + let value = self.llvm_type(generator, ctx).const_zero(); + unsafe { self.believe_value(value) } } pub fn const_1( @@ -161,8 +165,8 @@ impl<'ctx, N: IntKind<'ctx>> Int { generator: &mut G, ctx: &'ctx Context, ) -> Instance<'ctx, Self> { - let value = self.get_type(generator, ctx).const_all_ones(); - self.believe_value(value) + let value = self.llvm_type(generator, ctx).const_all_ones(); + unsafe { self.believe_value(value) } } pub fn s_extend_or_bit_cast( @@ -177,9 +181,9 @@ impl<'ctx, N: IntKind<'ctx>> Int { ); let value = ctx .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(); - self.believe_value(value) + unsafe { self.believe_value(value) } } pub fn s_extend( @@ -193,8 +197,8 @@ impl<'ctx, N: IntKind<'ctx>> Int { < self.0.get_int_type(generator, ctx.ctx).get_bit_width() ); let value = - ctx.builder.build_int_s_extend(value, self.get_type(generator, ctx.ctx), "").unwrap(); - self.believe_value(value) + ctx.builder.build_int_s_extend(value, self.llvm_type(generator, ctx.ctx), "").unwrap(); + unsafe { self.believe_value(value) } } pub fn z_extend_or_bit_cast( @@ -209,9 +213,9 @@ impl<'ctx, N: IntKind<'ctx>> Int { ); let value = ctx .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(); - self.believe_value(value) + unsafe { self.believe_value(value) } } pub fn z_extend( @@ -225,8 +229,8 @@ impl<'ctx, N: IntKind<'ctx>> Int { < self.0.get_int_type(generator, ctx.ctx).get_bit_width() ); let value = - ctx.builder.build_int_z_extend(value, self.get_type(generator, ctx.ctx), "").unwrap(); - self.believe_value(value) + ctx.builder.build_int_z_extend(value, self.llvm_type(generator, ctx.ctx), "").unwrap(); + unsafe { self.believe_value(value) } } pub fn truncate_or_bit_cast( @@ -241,9 +245,9 @@ impl<'ctx, N: IntKind<'ctx>> Int { ); let value = ctx .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(); - self.believe_value(value) + unsafe { self.believe_value(value) } } pub fn truncate( @@ -257,8 +261,8 @@ impl<'ctx, N: IntKind<'ctx>> Int { > self.0.get_int_type(generator, ctx.ctx).get_bit_width() ); let value = - ctx.builder.build_int_truncate(value, self.get_type(generator, ctx.ctx), "").unwrap(); - self.believe_value(value) + ctx.builder.build_int_truncate(value, self.llvm_type(generator, ctx.ctx), "").unwrap(); + unsafe { self.believe_value(value) } } /// `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 { let our_width = self.0.get_int_type(generator, ctx.ctx).get_bit_width(); match their_width.cmp(&our_width) { 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), } } @@ -288,7 +292,7 @@ impl<'ctx, N: IntKind<'ctx>> Int { let our_width = self.0.get_int_type(generator, ctx.ctx).get_bit_width(); match their_width.cmp(&our_width) { 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), } } @@ -390,19 +394,19 @@ impl<'ctx, N: IntKind<'ctx>> Instance<'ctx, Int> { #[must_use] pub fn add(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self { 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] pub fn sub(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self { 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] pub fn mul(&self, ctx: &CodeGenContext<'ctx, '_>, other: Self) -> Self { 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( @@ -412,6 +416,6 @@ impl<'ctx, N: IntKind<'ctx>> Instance<'ctx, Int> { other: Self, ) -> Instance<'ctx, Int> { let value = ctx.builder.build_int_compare(op, self.value, other.value, "").unwrap(); - Int(Bool).believe_value(value) + unsafe { Int(Bool).believe_value(value) } } } diff --git a/nac3core/src/codegen/model/ptr.rs b/nac3core/src/codegen/model/ptr.rs index 956b02f3..1721c0a4 100644 --- a/nac3core/src/codegen/model/ptr.rs +++ b/nac3core/src/codegen/model/ptr.rs @@ -31,9 +31,13 @@ impl<'ctx, Item: Model<'ctx>> Model<'ctx> for Ptr { type Value = PointerValue<'ctx>; type Type = PointerType<'ctx>; - fn get_type(&self, generator: &G, ctx: &'ctx Context) -> Self::Type { + fn llvm_type( + &self, + generator: &G, + ctx: &'ctx Context, + ) -> Self::Type { // 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, G: CodeGenerator + ?Sized>( @@ -71,8 +75,8 @@ impl<'ctx, Item: Model<'ctx>> Ptr { generator: &mut G, ctx: &'ctx Context, ) -> Instance<'ctx, Ptr> { - let ptr = self.get_type(generator, ctx).const_null(); - self.believe_value(ptr) + let ptr = self.llvm_type(generator, ctx).const_null(); + unsafe { self.believe_value(ptr) } } /// Cast a pointer into this model with [`inkwell::builder::Builder::build_pointer_cast`] @@ -87,9 +91,9 @@ impl<'ctx, Item: Model<'ctx>> 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(); - self.believe_value(ptr) + unsafe { self.believe_value(ptr) } } } @@ -102,7 +106,7 @@ impl<'ctx, Item: Model<'ctx>> Instance<'ctx, Ptr> { offset: IntValue<'ctx>, ) -> Instance<'ctx, Ptr> { 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. @@ -181,13 +185,13 @@ impl<'ctx, Item: Model<'ctx>> Instance<'ctx, Ptr> { /// Check if the pointer is null with [`inkwell::builder::Builder::build_is_null`]. pub fn is_null(&self, ctx: &CodeGenContext<'ctx, '_>) -> Instance<'ctx, Int> { 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`]. pub fn is_not_null(&self, ctx: &CodeGenContext<'ctx, '_>) -> Instance<'ctx, Int> { 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. diff --git a/nac3core/src/codegen/model/structure.rs b/nac3core/src/codegen/model/structure.rs index a9899049..67985805 100644 --- a/nac3core/src/codegen/model/structure.rs +++ b/nac3core/src/codegen/model/structure.rs @@ -68,7 +68,7 @@ impl<'ctx, 'a, G: CodeGenerator + ?Sized> FieldTraversal<'ctx> for TypeFieldTrav type Out = (); // Checking types return nothing. fn add>(&mut self, _name: &'static str, model: M) -> Self::Out { - 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); } } @@ -242,7 +242,11 @@ impl<'ctx, S: StructKind<'ctx>> Model<'ctx> for Struct { type Value = StructValue<'ctx>; type Type = StructType<'ctx>; - fn get_type(&self, generator: &G, ctx: &'ctx Context) -> Self::Type { + fn llvm_type( + &self, + generator: &G, + ctx: &'ctx Context, + ) -> Self::Type { self.0.get_struct_type(generator, ctx) } @@ -327,7 +331,7 @@ impl<'ctx, S: StructKind<'ctx>> Instance<'ctx, Ptr>> { .unwrap() }; - Ptr(field.model).believe_value(ptr) + unsafe { Ptr(field.model).believe_value(ptr) } } /// Convenience function equivalent to `.gep(...).load(...)`.