core: Minor refactor allocate_list
This commit is contained in:
parent
2e6a64a1de
commit
806f65815f
|
@ -765,32 +765,55 @@ pub fn destructure_range<'ctx, 'a>(
|
||||||
(start, end, step)
|
(start, end, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocates a List structure with the given [type][ty] and [length]. The name of the resulting
|
||||||
|
/// LLVM value is `{name}.addr`, or `list.addr` if [name] is not specified.
|
||||||
|
///
|
||||||
|
/// Returns an instance of [PointerValue] pointing to the List structure. The List structure is
|
||||||
|
/// defined as `type { ty*, size_t }` in LLVM, where the first element stores the pointer to the
|
||||||
|
/// data, and the second element stores the size of the List.
|
||||||
pub fn allocate_list<'ctx, 'a, G: CodeGenerator>(
|
pub fn allocate_list<'ctx, 'a, G: CodeGenerator>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
ty: BasicTypeEnum<'ctx>,
|
ty: BasicTypeEnum<'ctx>,
|
||||||
length: IntValue<'ctx>,
|
length: IntValue<'ctx>,
|
||||||
|
name: Option<&str>,
|
||||||
) -> PointerValue<'ctx> {
|
) -> PointerValue<'ctx> {
|
||||||
let arr_ptr = ctx.builder.build_array_alloca(ty, length, "tmparr");
|
|
||||||
let size_t = generator.get_size_type(ctx.ctx);
|
let size_t = generator.get_size_type(ctx.ctx);
|
||||||
let i32_t = ctx.ctx.i32_type();
|
let i32_t = ctx.ctx.i32_type();
|
||||||
let arr_ty =
|
// List structure; type { ty*, size_t }
|
||||||
ctx.ctx.struct_type(&[ty.ptr_type(AddressSpace::default()).into(), size_t.into()], false);
|
let arr_ty = ctx.ctx
|
||||||
|
.struct_type(&[ty.ptr_type(AddressSpace::default()).into(), size_t.into()], false);
|
||||||
let zero = ctx.ctx.i32_type().const_zero();
|
let zero = ctx.ctx.i32_type().const_zero();
|
||||||
let arr_str_ptr = ctx.builder.build_alloca(arr_ty, "tmparrstr");
|
|
||||||
|
let arr_str_ptr = ctx.builder.build_alloca(
|
||||||
|
arr_ty, format!("{}.addr", name.unwrap_or("list")).as_str()
|
||||||
|
);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// Pointer to the `length` element of the list structure
|
||||||
let len_ptr = ctx.builder.build_in_bounds_gep(
|
let len_ptr = ctx.builder.build_in_bounds_gep(
|
||||||
arr_str_ptr,
|
arr_str_ptr,
|
||||||
&[zero, i32_t.const_int(1, false)],
|
&[zero, i32_t.const_int(1, false)],
|
||||||
"len_ptr",
|
""
|
||||||
|
);
|
||||||
|
let length = ctx.builder.build_int_z_extend(
|
||||||
|
length,
|
||||||
|
size_t,
|
||||||
|
""
|
||||||
);
|
);
|
||||||
let length = ctx.builder.build_int_z_extend(length, size_t, "zext");
|
|
||||||
ctx.builder.build_store(len_ptr, length);
|
ctx.builder.build_store(len_ptr, length);
|
||||||
let ptr_to_arr =
|
|
||||||
ctx.builder.build_in_bounds_gep(arr_str_ptr, &[zero, i32_t.const_zero()], "ptr_to_arr");
|
// Pointer to the `data` element of the list structure
|
||||||
|
let arr_ptr = ctx.builder.build_array_alloca(ty, length, "");
|
||||||
|
let ptr_to_arr = ctx.builder.build_in_bounds_gep(
|
||||||
|
arr_str_ptr,
|
||||||
|
&[zero, i32_t.const_zero()],
|
||||||
|
""
|
||||||
|
);
|
||||||
ctx.builder.build_store(ptr_to_arr, arr_ptr);
|
ctx.builder.build_store(ptr_to_arr, arr_ptr);
|
||||||
arr_str_ptr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arr_str_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
||||||
|
@ -849,11 +872,18 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
||||||
ctx,
|
ctx,
|
||||||
elem_ty,
|
elem_ty,
|
||||||
ctx.builder.build_int_z_extend_or_bit_cast(length, size_t, "z_ext_len"),
|
ctx.builder.build_int_z_extend_or_bit_cast(length, size_t, "z_ext_len"),
|
||||||
|
Some("listcomp"),
|
||||||
);
|
);
|
||||||
ctx.builder.build_unconditional_branch(list_init);
|
ctx.builder.build_unconditional_branch(list_init);
|
||||||
|
|
||||||
ctx.builder.position_at_end(empty);
|
ctx.builder.position_at_end(empty);
|
||||||
let list_b = allocate_list(generator, ctx, elem_ty, zero_size_t);
|
let list_b = allocate_list(
|
||||||
|
generator,
|
||||||
|
ctx,
|
||||||
|
elem_ty,
|
||||||
|
zero_size_t,
|
||||||
|
Some("list_b")
|
||||||
|
);
|
||||||
ctx.builder.build_unconditional_branch(list_init);
|
ctx.builder.build_unconditional_branch(list_init);
|
||||||
|
|
||||||
ctx.builder.position_at_end(list_init);
|
ctx.builder.position_at_end(list_init);
|
||||||
|
@ -898,7 +928,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
|
||||||
Some("length"),
|
Some("length"),
|
||||||
)
|
)
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
list = allocate_list(generator, ctx, elem_ty, length);
|
list = allocate_list(generator, ctx, elem_ty, length, Some("listcomp"));
|
||||||
list_content =
|
list_content =
|
||||||
ctx.build_gep_and_load(list, &[zero_size_t, zero_32], Some("list_content")).into_pointer_value();
|
ctx.build_gep_and_load(list, &[zero_size_t, zero_32], Some("list_content")).into_pointer_value();
|
||||||
let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("counter.addr"))?;
|
let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("counter.addr"))?;
|
||||||
|
@ -1089,7 +1119,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
|
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
|
||||||
Some((ptr, None, _)) => ctx.builder.build_load(*ptr, "load").into(),
|
Some((ptr, None, _)) => ctx.builder.build_load(*ptr, id.to_string().as_str()).into(),
|
||||||
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
|
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
|
||||||
None => {
|
None => {
|
||||||
let resolver = ctx.resolver.clone();
|
let resolver = ctx.resolver.clone();
|
||||||
|
@ -1120,8 +1150,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
||||||
elements[0].get_type()
|
elements[0].get_type()
|
||||||
};
|
};
|
||||||
let length = generator.get_size_type(ctx.ctx).const_int(elements.len() as u64, false);
|
let length = generator.get_size_type(ctx.ctx).const_int(elements.len() as u64, false);
|
||||||
let arr_str_ptr = allocate_list(generator, ctx, ty, length);
|
let arr_str_ptr = allocate_list(generator, ctx, ty, length, Some("list"));
|
||||||
let arr_ptr = ctx.build_gep_and_load(arr_str_ptr, &[zero, zero], Some("arr.addr"))
|
let arr_ptr = ctx.build_gep_and_load(arr_str_ptr, &[zero, zero], Some("list.ptr.addr"))
|
||||||
.into_pointer_value();
|
.into_pointer_value();
|
||||||
unsafe {
|
unsafe {
|
||||||
for (i, v) in elements.iter().enumerate() {
|
for (i, v) in elements.iter().enumerate() {
|
||||||
|
@ -1558,7 +1588,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
|
||||||
.into_int_value(),
|
.into_int_value(),
|
||||||
step,
|
step,
|
||||||
);
|
);
|
||||||
let res_array_ret = allocate_list(generator, ctx, ty, length);
|
let res_array_ret = allocate_list(generator, ctx, ty, length, Some("ret"));
|
||||||
let res_ind =
|
let res_ind =
|
||||||
handle_slice_indices(&None, &None, &None, ctx, generator, res_array_ret)?;
|
handle_slice_indices(&None, &None, &None, ctx, generator, res_array_ret)?;
|
||||||
list_slice_assignment(
|
list_slice_assignment(
|
||||||
|
|
Loading…
Reference in New Issue