Implement abstractions over Structs and NDArray #554
|
@ -14,10 +14,7 @@ use pyo3::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use nac3core::{
|
use nac3core::{
|
||||||
codegen::{
|
codegen::{classes::NDArrayType, CodeGenContext, CodeGenerator},
|
||||||
classes::{NDArrayType, ProxyType},
|
|
||||||
CodeGenContext, CodeGenerator,
|
|
||||||
},
|
|
||||||
inkwell::{
|
inkwell::{
|
||||||
module::Linkage,
|
module::Linkage,
|
||||||
types::{BasicType, BasicTypeEnum},
|
types::{BasicType, BasicTypeEnum},
|
||||||
|
@ -1096,7 +1093,7 @@ impl InnerResolver {
|
||||||
if self.global_value_ids.read().contains_key(&id) {
|
if self.global_value_ids.read().contains_key(&id) {
|
||||||
let global = ctx.module.get_global(&id_str).unwrap_or_else(|| {
|
let global = ctx.module.get_global(&id_str).unwrap_or_else(|| {
|
||||||
ctx.module.add_global(
|
ctx.module.add_global(
|
||||||
ndarray_llvm_ty.as_underlying_type(),
|
ndarray_llvm_ty.element_type().into_struct_type(),
|
||||||
Some(AddressSpace::default()),
|
Some(AddressSpace::default()),
|
||||||
&id_str,
|
&id_str,
|
||||||
)
|
)
|
||||||
|
@ -1190,7 +1187,7 @@ impl InnerResolver {
|
||||||
data_global.set_initializer(&data);
|
data_global.set_initializer(&data);
|
||||||
|
|
||||||
// create a global for the ndarray object and initialize it
|
// create a global for the ndarray object and initialize it
|
||||||
let value = ndarray_llvm_ty.as_underlying_type().const_named_struct(&[
|
let value = ndarray_llvm_ty.element_type().into_struct_type().const_named_struct(&[
|
||||||
llvm_usize.const_int(ndarray_ndims, false).into(),
|
llvm_usize.const_int(ndarray_ndims, false).into(),
|
||||||
shape_global
|
shape_global
|
||||||
.as_pointer_value()
|
.as_pointer_value()
|
||||||
|
@ -1203,7 +1200,7 @@ impl InnerResolver {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let ndarray = ctx.module.add_global(
|
let ndarray = ctx.module.add_global(
|
||||||
ndarray_llvm_ty.as_underlying_type(),
|
ndarray_llvm_ty.element_type().into_struct_type(),
|
||||||
Some(AddressSpace::default()),
|
Some(AddressSpace::default()),
|
||||||
&id_str,
|
&id_str,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
context::Context,
|
context::Context,
|
||||||
types::{AnyTypeEnum, ArrayType, BasicType, BasicTypeEnum, IntType, PointerType, StructType},
|
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
|
||||||
values::{ArrayValue, BasicValue, BasicValueEnum, IntValue, PointerValue, StructValue},
|
values::{BasicValue, BasicValueEnum, IntValue, PointerValue},
|
||||||
AddressSpace, IntPredicate,
|
AddressSpace, IntPredicate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,10 +18,6 @@ pub trait ProxyType<'ctx>: Into<Self::Base> {
|
||||||
/// [LLVM pointer type][PointerType].
|
/// [LLVM pointer type][PointerType].
|
||||||
type Base: BasicType<'ctx>;
|
type Base: BasicType<'ctx>;
|
||||||
|
|
||||||
/// The underlying LLVM type used to represent values. This is usually the element type of
|
|
||||||
/// [`Base`] if it is a pointer, otherwise this is the same type as `Base`.
|
|
||||||
type Underlying: BasicType<'ctx>;
|
|
||||||
|
|
||||||
/// The type of values represented by this type.
|
/// The type of values represented by this type.
|
||||||
type Value: ProxyValue<'ctx>;
|
type Value: ProxyValue<'ctx>;
|
||||||
|
|
||||||
|
@ -40,11 +36,7 @@ pub trait ProxyType<'ctx>: Into<Self::Base> {
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
size: IntValue<'ctx>,
|
size: IntValue<'ctx>,
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> ArraySliceValue<'ctx> {
|
) -> ArraySliceValue<'ctx>;
|
||||||
generator
|
|
||||||
.gen_array_var_alloc(ctx, self.as_underlying_type().as_basic_type_enum(), size, name)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a [`value`][ProxyValue] with this as its type.
|
/// Creates a [`value`][ProxyValue] with this as its type.
|
||||||
fn create_value(
|
fn create_value(
|
||||||
|
@ -55,9 +47,6 @@ pub trait ProxyType<'ctx>: Into<Self::Base> {
|
||||||
|
|
||||||
/// Returns the [base type][Self::Base] of this proxy.
|
/// Returns the [base type][Self::Base] of this proxy.
|
||||||
fn as_base_type(&self) -> Self::Base;
|
fn as_base_type(&self) -> Self::Base;
|
||||||
|
|
||||||
/// Returns the [underlying type][Self::Underlying] of this proxy.
|
|
||||||
fn as_underlying_type(&self) -> Self::Underlying;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A LLVM type that is used to represent a non-primitive value in NAC3.
|
/// A LLVM type that is used to represent a non-primitive value in NAC3.
|
||||||
|
@ -66,10 +55,6 @@ pub trait ProxyValue<'ctx>: Into<Self::Base> {
|
||||||
/// [LLVM pointer type][PointerValue].
|
/// [LLVM pointer type][PointerValue].
|
||||||
type Base: BasicValue<'ctx>;
|
type Base: BasicValue<'ctx>;
|
||||||
|
|
||||||
/// The underlying type of LLVM values represented by this instance. This is usually the element
|
|
||||||
/// type of [`Base`] if it is a pointer, otherwise this is the same type as `Base`.
|
|
||||||
type Underlying: BasicValue<'ctx>;
|
|
||||||
|
|
||||||
/// The type of this value.
|
/// The type of this value.
|
||||||
type Type: ProxyType<'ctx>;
|
type Type: ProxyType<'ctx>;
|
||||||
|
|
||||||
|
@ -79,13 +64,13 @@ pub trait ProxyValue<'ctx>: Into<Self::Base> {
|
||||||
/// Returns the [base value][Self::Base] of this proxy.
|
/// Returns the [base value][Self::Base] of this proxy.
|
||||||
fn as_base_value(&self) -> Self::Base;
|
fn as_base_value(&self) -> Self::Base;
|
||||||
|
|
||||||
/// Loads this value into its [underlying representation][Self::Underlying]. Usually involves a
|
// /// Loads this value into its [underlying representation][Self::Underlying]. Usually involves a
|
||||||
/// `getelementptr` if [`Self::Base`] is a [pointer value][PointerValue].
|
// /// `getelementptr` if [`Self::Base`] is a [pointer value][PointerValue].
|
||||||
fn as_underlying_value(
|
// fn as_underlying_value(
|
||||||
&self,
|
// &self,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
// ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
name: Option<&'ctx str>,
|
// name: Option<&'ctx str>,
|
||||||
) -> Self::Underlying;
|
// ) -> Self::Underlying;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An LLVM value that is array-like, i.e. it contains a contiguous, sequenced collection of
|
/// An LLVM value that is array-like, i.e. it contains a contiguous, sequenced collection of
|
||||||
|
@ -600,7 +585,6 @@ impl<'ctx> ListType<'ctx> {
|
||||||
|
|
||||||
impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
||||||
type Base = PointerType<'ctx>;
|
type Base = PointerType<'ctx>;
|
||||||
type Underlying = StructType<'ctx>;
|
|
||||||
type Value = ListValue<'ctx>;
|
type Value = ListValue<'ctx>;
|
||||||
|
|
||||||
fn new_value<G: CodeGenerator + ?Sized>(
|
fn new_value<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -610,9 +594,32 @@ impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Self::Value {
|
) -> Self::Value {
|
||||||
self.create_value(
|
self.create_value(
|
||||||
generator.gen_var_alloc(ctx, self.as_underlying_type().into(), name).unwrap(),
|
generator
|
||||||
|
.gen_var_alloc(
|
||||||
|
ctx,
|
||||||
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
|
.unwrap(),
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_array_value<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
size: IntValue<'ctx>,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> ArraySliceValue<'ctx> {
|
||||||
|
generator
|
||||||
|
.gen_array_var_alloc(
|
||||||
|
ctx,
|
||||||
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
|
size,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_value(
|
fn create_value(
|
||||||
|
@ -628,10 +635,6 @@ impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
||||||
fn as_base_type(&self) -> Self::Base {
|
fn as_base_type(&self) -> Self::Base {
|
||||||
self.ty
|
self.ty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_underlying_type(&self) -> Self::Underlying {
|
|
||||||
self.as_base_type().get_element_type().into_struct_type()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> From<ListType<'ctx>> for PointerType<'ctx> {
|
impl<'ctx> From<ListType<'ctx>> for PointerType<'ctx> {
|
||||||
|
@ -770,7 +773,6 @@ impl<'ctx> ListValue<'ctx> {
|
||||||
|
|
||||||
impl<'ctx> ProxyValue<'ctx> for ListValue<'ctx> {
|
impl<'ctx> ProxyValue<'ctx> for ListValue<'ctx> {
|
||||||
type Base = PointerValue<'ctx>;
|
type Base = PointerValue<'ctx>;
|
||||||
type Underlying = StructValue<'ctx>;
|
|
||||||
type Type = ListType<'ctx>;
|
type Type = ListType<'ctx>;
|
||||||
|
|
||||||
fn get_type(&self) -> Self::Type {
|
fn get_type(&self) -> Self::Type {
|
||||||
|
@ -780,17 +782,6 @@ impl<'ctx> ProxyValue<'ctx> for ListValue<'ctx> {
|
||||||
fn as_base_value(&self) -> Self::Base {
|
fn as_base_value(&self) -> Self::Base {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_underlying_value(
|
|
||||||
&self,
|
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
|
||||||
name: Option<&'ctx str>,
|
|
||||||
) -> Self::Underlying {
|
|
||||||
ctx.builder
|
|
||||||
.build_load(self.as_base_value(), name.unwrap_or_default())
|
|
||||||
.map(BasicValueEnum::into_struct_value)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> From<ListValue<'ctx>> for PointerValue<'ctx> {
|
impl<'ctx> From<ListValue<'ctx>> for PointerValue<'ctx> {
|
||||||
|
@ -940,7 +931,6 @@ impl<'ctx> RangeType<'ctx> {
|
||||||
|
|
||||||
impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
||||||
type Base = PointerType<'ctx>;
|
type Base = PointerType<'ctx>;
|
||||||
type Underlying = ArrayType<'ctx>;
|
|
||||||
type Value = RangeValue<'ctx>;
|
type Value = RangeValue<'ctx>;
|
||||||
|
|
||||||
fn new_value<G: CodeGenerator + ?Sized>(
|
fn new_value<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -950,7 +940,13 @@ impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Self::Value {
|
) -> Self::Value {
|
||||||
self.create_value(
|
self.create_value(
|
||||||
generator.gen_var_alloc(ctx, self.as_underlying_type().into(), name).unwrap(),
|
generator
|
||||||
|
.gen_var_alloc(
|
||||||
|
ctx,
|
||||||
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -965,12 +961,25 @@ impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
||||||
RangeValue { value, name }
|
RangeValue { value, name }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_base_type(&self) -> Self::Base {
|
fn new_array_value<G: CodeGenerator + ?Sized>(
|
||||||
self.ty
|
&self,
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
size: IntValue<'ctx>,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> ArraySliceValue<'ctx> {
|
||||||
|
generator
|
||||||
|
.gen_array_var_alloc(
|
||||||
|
ctx,
|
||||||
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
|
size,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_underlying_type(&self) -> Self::Underlying {
|
fn as_base_type(&self) -> Self::Base {
|
||||||
self.as_base_type().get_element_type().into_array_type()
|
self.ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1112,7 +1121,6 @@ impl<'ctx> RangeValue<'ctx> {
|
||||||
|
|
||||||
impl<'ctx> ProxyValue<'ctx> for RangeValue<'ctx> {
|
impl<'ctx> ProxyValue<'ctx> for RangeValue<'ctx> {
|
||||||
type Base = PointerValue<'ctx>;
|
type Base = PointerValue<'ctx>;
|
||||||
type Underlying = ArrayValue<'ctx>;
|
|
||||||
type Type = RangeType<'ctx>;
|
type Type = RangeType<'ctx>;
|
||||||
|
|
||||||
fn get_type(&self) -> Self::Type {
|
fn get_type(&self) -> Self::Type {
|
||||||
|
@ -1122,17 +1130,6 @@ impl<'ctx> ProxyValue<'ctx> for RangeValue<'ctx> {
|
||||||
fn as_base_value(&self) -> Self::Base {
|
fn as_base_value(&self) -> Self::Base {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_underlying_value(
|
|
||||||
&self,
|
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
|
||||||
name: Option<&'ctx str>,
|
|
||||||
) -> Self::Underlying {
|
|
||||||
ctx.builder
|
|
||||||
.build_load(self.as_base_value(), name.unwrap_or_default())
|
|
||||||
.map(BasicValueEnum::into_array_value)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> From<RangeValue<'ctx>> for PointerValue<'ctx> {
|
impl<'ctx> From<RangeValue<'ctx>> for PointerValue<'ctx> {
|
||||||
|
@ -1262,7 +1259,6 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||||
|
|
||||||
impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
||||||
type Base = PointerType<'ctx>;
|
type Base = PointerType<'ctx>;
|
||||||
type Underlying = StructType<'ctx>;
|
|
||||||
type Value = NDArrayValue<'ctx>;
|
type Value = NDArrayValue<'ctx>;
|
||||||
|
|
||||||
fn new_value<G: CodeGenerator + ?Sized>(
|
fn new_value<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -1272,9 +1268,32 @@ impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Self::Value {
|
) -> Self::Value {
|
||||||
self.create_value(
|
self.create_value(
|
||||||
generator.gen_var_alloc(ctx, self.as_underlying_type().into(), name).unwrap(),
|
generator
|
||||||
|
.gen_var_alloc(
|
||||||
|
ctx,
|
||||||
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
|
.unwrap(),
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_array_value<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
size: IntValue<'ctx>,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> ArraySliceValue<'ctx> {
|
||||||
|
generator
|
||||||
|
.gen_array_var_alloc(
|
||||||
|
ctx,
|
||||||
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
|
size,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_value(
|
fn create_value(
|
||||||
|
@ -1290,10 +1309,6 @@ impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
||||||
fn as_base_type(&self) -> Self::Base {
|
fn as_base_type(&self) -> Self::Base {
|
||||||
self.ty
|
self.ty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_underlying_type(&self) -> Self::Underlying {
|
|
||||||
self.as_base_type().get_element_type().into_struct_type()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> From<NDArrayType<'ctx>> for PointerType<'ctx> {
|
impl<'ctx> From<NDArrayType<'ctx>> for PointerType<'ctx> {
|
||||||
|
@ -1445,7 +1460,6 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||||
|
|
||||||
impl<'ctx> ProxyValue<'ctx> for NDArrayValue<'ctx> {
|
impl<'ctx> ProxyValue<'ctx> for NDArrayValue<'ctx> {
|
||||||
type Base = PointerValue<'ctx>;
|
type Base = PointerValue<'ctx>;
|
||||||
type Underlying = StructValue<'ctx>;
|
|
||||||
type Type = NDArrayType<'ctx>;
|
type Type = NDArrayType<'ctx>;
|
||||||
|
|
||||||
fn get_type(&self) -> Self::Type {
|
fn get_type(&self) -> Self::Type {
|
||||||
|
@ -1455,17 +1469,6 @@ impl<'ctx> ProxyValue<'ctx> for NDArrayValue<'ctx> {
|
||||||
fn as_base_value(&self) -> Self::Base {
|
fn as_base_value(&self) -> Self::Base {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_underlying_value(
|
|
||||||
&self,
|
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
|
||||||
name: Option<&'ctx str>,
|
|
||||||
) -> Self::Underlying {
|
|
||||||
ctx.builder
|
|
||||||
.build_load(self.as_base_value(), name.unwrap_or_default())
|
|
||||||
.map(BasicValueEnum::into_struct_value)
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> From<NDArrayValue<'ctx>> for PointerValue<'ctx> {
|
impl<'ctx> From<NDArrayValue<'ctx>> for PointerValue<'ctx> {
|
||||||
|
|
Loading…
Reference in New Issue