forked from M-Labs/nac3
[core] Move alloca and map_value of ProxyType to implementations
These functions may not be invokable by the same set of parameters as some classes has associated states.
This commit is contained in:
parent
d62c6b95fd
commit
06092ad29b
@ -18,7 +18,7 @@ use nac3core::{
|
|||||||
irrt::call_ndarray_calc_size,
|
irrt::call_ndarray_calc_size,
|
||||||
llvm_intrinsics::{call_int_smax, call_memcpy_generic, call_stackrestore, call_stacksave},
|
llvm_intrinsics::{call_int_smax, call_memcpy_generic, call_stackrestore, call_stacksave},
|
||||||
stmt::{gen_block, gen_for_callback_incrementing, gen_if_callback, gen_with},
|
stmt::{gen_block, gen_for_callback_incrementing, gen_if_callback, gen_with},
|
||||||
types::{NDArrayType, ProxyType},
|
types::NDArrayType,
|
||||||
values::{
|
values::{
|
||||||
ArrayLikeIndexer, ArrayLikeValue, ArraySliceValue, ListValue, NDArrayValue, ProxyValue,
|
ArrayLikeIndexer, ArrayLikeValue, ArraySliceValue, ListValue, NDArrayValue, ProxyValue,
|
||||||
RangeValue, UntypedArrayLikeAccessor,
|
RangeValue, UntypedArrayLikeAccessor,
|
||||||
@ -460,12 +460,20 @@ fn format_rpc_arg<'ctx>(
|
|||||||
|
|
||||||
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, arg_ty);
|
let (elem_ty, _) = unpack_ndarray_var_tys(&mut ctx.unifier, arg_ty);
|
||||||
let llvm_elem_ty = ctx.get_llvm_type(generator, elem_ty);
|
let llvm_elem_ty = ctx.get_llvm_type(generator, elem_ty);
|
||||||
let llvm_arg_ty = NDArrayType::new(generator, ctx.ctx, llvm_elem_ty);
|
let llvm_arg = NDArrayValue::from_pointer_value(
|
||||||
let llvm_arg = llvm_arg_ty.map_value(arg.into_pointer_value(), None);
|
arg.into_pointer_value(),
|
||||||
|
llvm_elem_ty,
|
||||||
|
llvm_usize,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
let llvm_usize_sizeof = ctx
|
let llvm_usize_sizeof = ctx
|
||||||
.builder
|
.builder
|
||||||
.build_int_truncate_or_bit_cast(llvm_arg_ty.size_type().size_of(), llvm_usize, "")
|
.build_int_truncate_or_bit_cast(
|
||||||
|
llvm_arg.get_type().size_type().size_of(),
|
||||||
|
llvm_usize,
|
||||||
|
"",
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let llvm_pdata_sizeof = ctx
|
let llvm_pdata_sizeof = ctx
|
||||||
.builder
|
.builder
|
||||||
@ -598,7 +606,7 @@ fn format_rpc_ret<'ctx>(
|
|||||||
|
|
||||||
// Allocate the resulting ndarray
|
// Allocate the resulting ndarray
|
||||||
// A condition after format_rpc_ret ensures this will not be popped this off.
|
// A condition after format_rpc_ret ensures this will not be popped this off.
|
||||||
let ndarray = llvm_ret_ty.new_value(generator, ctx, Some("rpc.result"));
|
let ndarray = llvm_ret_ty.alloca(generator, ctx, Some("rpc.result"));
|
||||||
|
|
||||||
// Setup ndims
|
// Setup ndims
|
||||||
let ndims =
|
let ndims =
|
||||||
|
@ -32,7 +32,7 @@ use super::{
|
|||||||
gen_for_callback_incrementing, gen_if_callback, gen_if_else_expr_callback, gen_raise,
|
gen_for_callback_incrementing, gen_if_callback, gen_if_else_expr_callback, gen_raise,
|
||||||
gen_var,
|
gen_var,
|
||||||
},
|
},
|
||||||
types::{ListType, ProxyType},
|
types::ListType,
|
||||||
values::{
|
values::{
|
||||||
ArrayLikeIndexer, ArrayLikeValue, ListValue, NDArrayValue, ProxyValue, RangeValue,
|
ArrayLikeIndexer, ArrayLikeValue, ListValue, NDArrayValue, ProxyValue, RangeValue,
|
||||||
TypedArrayLikeAccessor, UntypedArrayLikeAccessor,
|
TypedArrayLikeAccessor, UntypedArrayLikeAccessor,
|
||||||
@ -1112,7 +1112,7 @@ pub fn allocate_list<'ctx, G: CodeGenerator + ?Sized>(
|
|||||||
|
|
||||||
// List structure; type { ty*, size_t }
|
// List structure; type { ty*, size_t }
|
||||||
let arr_ty = ListType::new(generator, ctx.ctx, llvm_elem_ty);
|
let arr_ty = ListType::new(generator, ctx.ctx, llvm_elem_ty);
|
||||||
let list = arr_ty.new_value(generator, ctx, name);
|
let list = arr_ty.alloca(generator, ctx, name);
|
||||||
|
|
||||||
let length = ctx.builder.build_int_z_extend(length, llvm_usize, "").unwrap();
|
let length = ctx.builder.build_int_z_extend(length, llvm_usize, "").unwrap();
|
||||||
list.store_size(ctx, generator, length);
|
list.store_size(ctx, generator, length);
|
||||||
|
@ -111,6 +111,31 @@ impl<'ctx> ListType<'ctx> {
|
|||||||
.map(PointerType::get_element_type)
|
.map(PointerType::get_element_type)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocates an instance of [`ListValue`] as if by calling `alloca` on the base type.
|
||||||
|
#[must_use]
|
||||||
|
pub fn alloca<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> <Self as ProxyType<'ctx>>::Value {
|
||||||
|
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||||
|
self.raw_alloca(generator, ctx, name),
|
||||||
|
self.llvm_usize,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts an existing value into a [`ListValue`].
|
||||||
|
#[must_use]
|
||||||
|
pub fn map_value(
|
||||||
|
&self,
|
||||||
|
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> <Self as ProxyType<'ctx>>::Value {
|
||||||
|
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, self.llvm_usize, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
||||||
@ -137,25 +162,22 @@ impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
|||||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_value<G: CodeGenerator + ?Sized>(
|
fn raw_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Self::Value {
|
) -> <Self::Value as ProxyValue<'ctx>>::Base {
|
||||||
self.map_value(
|
|
||||||
generator
|
generator
|
||||||
.gen_var_alloc(
|
.gen_var_alloc(
|
||||||
ctx,
|
ctx,
|
||||||
self.as_base_type().get_element_type().into_struct_type().into(),
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
name,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_array_value<G: CodeGenerator + ?Sized>(
|
fn array_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
@ -172,14 +194,6 @@ impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_value(
|
|
||||||
&self,
|
|
||||||
value: <Self::Value as ProxyValue<'ctx>>::Base,
|
|
||||||
name: Option<&'ctx str>,
|
|
||||||
) -> Self::Value {
|
|
||||||
Self::Value::from_pointer_value(value, self.llvm_usize, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_base_type(&self) -> Self::Base {
|
fn as_base_type(&self) -> Self::Base {
|
||||||
self.ty
|
self.ty
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
//! This module contains abstraction over all intrinsic composite types of NAC3.
|
||||||
|
//!
|
||||||
|
//! # `raw_alloca` vs `alloca` vs `construct`
|
||||||
|
//!
|
||||||
|
//! There are three ways of creating a new object instance using the abstractions provided by this
|
||||||
|
//! module.
|
||||||
|
//!
|
||||||
|
//! - `raw_alloca`: Allocates the object on the stack, returning an instance of
|
||||||
|
//! [`impl BasicValue`][inkwell::values::BasicValue]. This is similar to a `malloc` expression in
|
||||||
|
//! C++ but the object is allocated on the stack.
|
||||||
|
//! - `alloca`: Similar to `raw_alloca`, but also wraps the allocated object with
|
||||||
|
//! [`<Self as ProxyType<'ctx>>::Value`][ProxyValue], and returns the wrapped object. The returned
|
||||||
|
//! object will not initialize any value or fields. This is similar to a type-safe `malloc`
|
||||||
|
//! expression in C++ but the object is allocated on the stack.
|
||||||
|
//! - `construct`: Similar to `alloca`, but performs some initialization on the value or fields of
|
||||||
|
//! the returned object. This is similar to a `new` expression in C++ but the object is allocated
|
||||||
|
//! on the stack.
|
||||||
|
|
||||||
use inkwell::{context::Context, types::BasicType, values::IntValue};
|
use inkwell::{context::Context, types::BasicType, values::IntValue};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -35,16 +53,17 @@ pub trait ProxyType<'ctx>: Into<Self::Base> {
|
|||||||
llvm_ty: Self::Base,
|
llvm_ty: Self::Base,
|
||||||
) -> Result<(), String>;
|
) -> Result<(), String>;
|
||||||
|
|
||||||
/// Creates a new value of this type.
|
/// Creates a new value of this type, returning the LLVM instance of this value.
|
||||||
fn new_value<G: CodeGenerator + ?Sized>(
|
fn raw_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Self::Value;
|
) -> <Self::Value as ProxyValue<'ctx>>::Base;
|
||||||
|
|
||||||
/// Creates a new array value of this type.
|
/// Creates a new array value of this type, returning an [`ArraySliceValue`] encapsulating the
|
||||||
fn new_array_value<G: CodeGenerator + ?Sized>(
|
/// resulting array.
|
||||||
|
fn array_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
@ -52,13 +71,6 @@ pub trait ProxyType<'ctx>: Into<Self::Base> {
|
|||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> ArraySliceValue<'ctx>;
|
) -> ArraySliceValue<'ctx>;
|
||||||
|
|
||||||
/// Converts an existing value into a [`ProxyValue`] of this type.
|
|
||||||
fn map_value(
|
|
||||||
&self,
|
|
||||||
value: <Self::Value as ProxyValue<'ctx>>::Base,
|
|
||||||
name: Option<&'ctx str>,
|
|
||||||
) -> Self::Value;
|
|
||||||
|
|
||||||
/// 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;
|
||||||
}
|
}
|
||||||
|
@ -175,6 +175,37 @@ impl<'ctx> NDArrayType<'ctx> {
|
|||||||
pub fn element_type(&self) -> BasicTypeEnum<'ctx> {
|
pub fn element_type(&self) -> BasicTypeEnum<'ctx> {
|
||||||
self.dtype
|
self.dtype
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocates an instance of [`NDArrayValue`] as if by calling `alloca` on the base type.
|
||||||
|
#[must_use]
|
||||||
|
pub fn alloca<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> <Self as ProxyType<'ctx>>::Value {
|
||||||
|
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||||
|
self.raw_alloca(generator, ctx, name),
|
||||||
|
self.dtype,
|
||||||
|
self.llvm_usize,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts an existing value into a [`NDArrayValue`].
|
||||||
|
#[must_use]
|
||||||
|
pub fn map_value(
|
||||||
|
&self,
|
||||||
|
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> <Self as ProxyType<'ctx>>::Value {
|
||||||
|
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||||
|
value,
|
||||||
|
self.dtype,
|
||||||
|
self.llvm_usize,
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
||||||
@ -201,25 +232,22 @@ impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
|||||||
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
Self::is_representable(llvm_ty, generator.get_size_type(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_value<G: CodeGenerator + ?Sized>(
|
fn raw_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Self::Value {
|
) -> <Self::Value as ProxyValue<'ctx>>::Base {
|
||||||
self.map_value(
|
|
||||||
generator
|
generator
|
||||||
.gen_var_alloc(
|
.gen_var_alloc(
|
||||||
ctx,
|
ctx,
|
||||||
self.as_base_type().get_element_type().into_struct_type().into(),
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
name,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_array_value<G: CodeGenerator + ?Sized>(
|
fn array_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
@ -236,16 +264,6 @@ impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_value(
|
|
||||||
&self,
|
|
||||||
value: <Self::Value as ProxyValue<'ctx>>::Base,
|
|
||||||
name: Option<&'ctx str>,
|
|
||||||
) -> Self::Value {
|
|
||||||
debug_assert_eq!(value.get_type(), self.as_base_type());
|
|
||||||
|
|
||||||
NDArrayValue::from_pointer_value(value, self.dtype, self.llvm_usize, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_base_type(&self) -> Self::Base {
|
fn as_base_type(&self) -> Self::Base {
|
||||||
self.ty
|
self.ty
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,30 @@ impl<'ctx> RangeType<'ctx> {
|
|||||||
pub fn value_type(&self) -> IntType<'ctx> {
|
pub fn value_type(&self) -> IntType<'ctx> {
|
||||||
self.as_base_type().get_element_type().into_array_type().get_element_type().into_int_type()
|
self.as_base_type().get_element_type().into_array_type().get_element_type().into_int_type()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type.
|
||||||
|
#[must_use]
|
||||||
|
pub fn alloca<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> <Self as ProxyType<'ctx>>::Value {
|
||||||
|
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
|
||||||
|
self.raw_alloca(generator, ctx, name),
|
||||||
|
name,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts an existing value into a [`RangeValue`].
|
||||||
|
#[must_use]
|
||||||
|
pub fn map_value(
|
||||||
|
&self,
|
||||||
|
value: <<Self as ProxyType<'ctx>>::Value as ProxyValue<'ctx>>::Base,
|
||||||
|
name: Option<&'ctx str>,
|
||||||
|
) -> <Self as ProxyType<'ctx>>::Value {
|
||||||
|
<Self as ProxyType<'ctx>>::Value::from_pointer_value(value, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
||||||
@ -102,25 +126,22 @@ impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
|||||||
Self::is_representable(llvm_ty)
|
Self::is_representable(llvm_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_value<G: CodeGenerator + ?Sized>(
|
fn raw_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
name: Option<&'ctx str>,
|
name: Option<&'ctx str>,
|
||||||
) -> Self::Value {
|
) -> <Self::Value as ProxyValue<'ctx>>::Base {
|
||||||
self.map_value(
|
|
||||||
generator
|
generator
|
||||||
.gen_var_alloc(
|
.gen_var_alloc(
|
||||||
ctx,
|
ctx,
|
||||||
self.as_base_type().get_element_type().into_struct_type().into(),
|
self.as_base_type().get_element_type().into_struct_type().into(),
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
name,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_array_value<G: CodeGenerator + ?Sized>(
|
fn array_alloca<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
@ -137,16 +158,6 @@ impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_value(
|
|
||||||
&self,
|
|
||||||
value: <Self::Value as ProxyValue<'ctx>>::Base,
|
|
||||||
name: Option<&'ctx str>,
|
|
||||||
) -> Self::Value {
|
|
||||||
debug_assert_eq!(value.get_type(), self.as_base_type());
|
|
||||||
|
|
||||||
RangeValue::from_pointer_value(value, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_base_type(&self) -> Self::Base {
|
fn as_base_type(&self) -> Self::Base {
|
||||||
self.ty
|
self.ty
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user