forked from M-Labs/nac3
1
0
Fork 0

core/model/ptr: renaming and add notes on upgrading to LLVM 15

This commit is contained in:
lyken 2024-08-25 14:21:46 +08:00
parent 7701691794
commit 6c48adff4d
No known key found for this signature in database
GPG Key ID: 3BD5FC6AC8325DD8
1 changed files with 22 additions and 3 deletions

View File

@ -9,14 +9,27 @@ use crate::codegen::{llvm_intrinsics::call_memcpy_generic, CodeGenContext, CodeG
use super::*; use super::*;
/// A model for [`PointerType`].
// TODO: LLVM 15: `Item` is a Rust type-hint for the LLVM type of value the `.store()/.load()` family
// of functions return. If a truly opaque pointer is needed, tell the programmer to use `OpaquePtr`.
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone, Copy, Default)]
pub struct Ptr<Item>(pub Item); pub struct Ptr<Item>(pub Item);
/// An opaque pointer. Like [`Ptr`] but without any Rust type-hints about its element type.
///
/// `.load()/.store()` is not available for [`Instance`]s of opaque pointers.
pub type OpaquePtr = Ptr<()>;
// TODO: LLVM 15: `Item: Model<'ctx>` don't even need to be a model anymore. It will only be
// a type-hint for the `.load()/.store()` functions for the `pointee_ty`.
//
// See https://thedan64.github.io/inkwell/inkwell/builder/struct.Builder.html#method.build_load.
impl<'ctx, Item: Model<'ctx>> Model<'ctx> for Ptr<Item> { 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 get_type<G: CodeGenerator + ?Sized>(&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.get_type(generator, ctx).ptr_type(AddressSpace::default())
} }
@ -48,13 +61,13 @@ impl<'ctx, Item: Model<'ctx>> Model<'ctx> for Ptr<Item> {
} }
} }
impl<'ctx, Element: Model<'ctx>> Ptr<Element> { impl<'ctx, Item: Model<'ctx>> Ptr<Item> {
/// Return a ***constant*** nullptr. /// Return a ***constant*** nullptr.
pub fn nullptr<G: CodeGenerator + ?Sized>( pub fn nullptr<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &'ctx Context, ctx: &'ctx Context,
) -> Instance<'ctx, Ptr<Element>> { ) -> Instance<'ctx, Ptr<Item>> {
let ptr = self.get_type(generator, ctx).const_null(); let ptr = self.get_type(generator, ctx).const_null();
self.believe_value(ptr) self.believe_value(ptr)
} }
@ -65,7 +78,12 @@ impl<'ctx, Element: Model<'ctx>> Ptr<Element> {
generator: &mut G, generator: &mut G,
ctx: &CodeGenContext<'ctx, '_>, ctx: &CodeGenContext<'ctx, '_>,
ptr: PointerValue<'ctx>, ptr: PointerValue<'ctx>,
) -> Instance<'ctx, Ptr<Element>> { ) -> Instance<'ctx, Ptr<Item>> {
// TODO: LLVM 15: Write in an impl where `Item` does not have to be `Model<'ctx>`.
// TODO: LLVM 15: This function will only have to be:
// ```
// return self.believe_value(ptr);
// ```
let t = self.get_type(generator, ctx.ctx); let t = self.get_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) self.believe_value(ptr)
@ -153,6 +171,7 @@ impl<'ctx, Item: Model<'ctx>> Instance<'ctx, Ptr<Item>> {
ctx: &CodeGenContext<'ctx, '_>, ctx: &CodeGenContext<'ctx, '_>,
new_item: NewItem, new_item: NewItem,
) -> Instance<'ctx, Ptr<NewItem>> { ) -> Instance<'ctx, Ptr<NewItem>> {
// TODO: LLVM 15: Write in an impl where `Item` does not have to be `Model<'ctx>`.
Ptr(new_item).pointer_cast(generator, ctx, self.value) Ptr(new_item).pointer_cast(generator, ctx, self.value)
} }