mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
use zig dict type
This commit is contained in:
parent
1e101599e0
commit
41c1878d8d
8 changed files with 128 additions and 351 deletions
|
@ -122,16 +122,13 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
||||||
set_name(*argument, name.ident_string(&env.interns));
|
set_name(*argument, name.ident_string(&env.interns));
|
||||||
}
|
}
|
||||||
|
|
||||||
let closure_type =
|
let closure_type = basic_type_from_layout(env, function_layout).ptr_type(AddressSpace::Generic);
|
||||||
basic_type_from_layout(env.arena, env.context, function_layout, env.ptr_bytes)
|
|
||||||
.ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
let mut arguments_cast =
|
let mut arguments_cast =
|
||||||
bumpalo::collections::Vec::with_capacity_in(arguments.len(), env.arena);
|
bumpalo::collections::Vec::with_capacity_in(arguments.len(), env.arena);
|
||||||
|
|
||||||
for (argument_ptr, layout) in arguments.iter().zip(argument_layouts) {
|
for (argument_ptr, layout) in arguments.iter().zip(argument_layouts) {
|
||||||
let basic_type = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes)
|
let basic_type = basic_type_from_layout(env, layout).ptr_type(AddressSpace::Generic);
|
||||||
.ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
let argument_cast = env
|
let argument_cast = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -278,8 +275,7 @@ pub fn build_rc_wrapper<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
set_name(value_ptr.into(), Symbol::ARG_1.ident_string(&env.interns));
|
set_name(value_ptr.into(), Symbol::ARG_1.ident_string(&env.interns));
|
||||||
|
|
||||||
let value_type = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes)
|
let value_type = basic_type_from_layout(env, layout).ptr_type(AddressSpace::Generic);
|
||||||
.ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
let value_cast = env
|
let value_cast = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -352,8 +348,7 @@ pub fn build_eq_wrapper<'a, 'ctx, 'env>(
|
||||||
set_name(value_ptr1.into(), Symbol::ARG_1.ident_string(&env.interns));
|
set_name(value_ptr1.into(), Symbol::ARG_1.ident_string(&env.interns));
|
||||||
set_name(value_ptr2.into(), Symbol::ARG_2.ident_string(&env.interns));
|
set_name(value_ptr2.into(), Symbol::ARG_2.ident_string(&env.interns));
|
||||||
|
|
||||||
let value_type = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes)
|
let value_type = basic_type_from_layout(env, layout).ptr_type(AddressSpace::Generic);
|
||||||
.ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
let value_cast1 = env
|
let value_cast1 = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -434,7 +429,7 @@ pub fn build_compare_wrapper<'a, 'ctx, 'env>(
|
||||||
set_name(value_ptr1.into(), Symbol::ARG_2.ident_string(&env.interns));
|
set_name(value_ptr1.into(), Symbol::ARG_2.ident_string(&env.interns));
|
||||||
set_name(value_ptr2.into(), Symbol::ARG_3.ident_string(&env.interns));
|
set_name(value_ptr2.into(), Symbol::ARG_3.ident_string(&env.interns));
|
||||||
|
|
||||||
let value_type = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes);
|
let value_type = basic_type_from_layout(env, layout);
|
||||||
let function_type = env
|
let function_type = env
|
||||||
.context
|
.context
|
||||||
.i8_type()
|
.i8_type()
|
||||||
|
|
|
@ -896,12 +896,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// The layout of the struct expects them to be dropped!
|
// The layout of the struct expects them to be dropped!
|
||||||
let (field_expr, field_layout) = load_symbol_and_layout(scope, symbol);
|
let (field_expr, field_layout) = load_symbol_and_layout(scope, symbol);
|
||||||
if !field_layout.is_dropped_because_empty() {
|
if !field_layout.is_dropped_because_empty() {
|
||||||
field_types.push(basic_type_from_layout(
|
field_types.push(basic_type_from_layout(env, &field_layout));
|
||||||
env.arena,
|
|
||||||
env.context,
|
|
||||||
&field_layout,
|
|
||||||
env.ptr_bytes,
|
|
||||||
));
|
|
||||||
|
|
||||||
field_vals.push(field_expr);
|
field_vals.push(field_expr);
|
||||||
}
|
}
|
||||||
|
@ -953,12 +948,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
for field_symbol in it {
|
for field_symbol in it {
|
||||||
let (val, field_layout) = load_symbol_and_layout(scope, field_symbol);
|
let (val, field_layout) = load_symbol_and_layout(scope, field_symbol);
|
||||||
if !field_layout.is_dropped_because_empty() {
|
if !field_layout.is_dropped_because_empty() {
|
||||||
let field_type = basic_type_from_layout(
|
let field_type = basic_type_from_layout(env, &field_layout);
|
||||||
env.arena,
|
|
||||||
env.context,
|
|
||||||
&field_layout,
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
field_vals.push(val);
|
field_vals.push(val);
|
||||||
|
@ -1000,7 +990,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
||||||
|
|
||||||
debug_assert!(*union_size > 1);
|
debug_assert!(*union_size > 1);
|
||||||
let ptr_size = env.ptr_bytes;
|
|
||||||
|
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
@ -1018,8 +1007,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// Zero-sized fields have no runtime representation.
|
// Zero-sized fields have no runtime representation.
|
||||||
// The layout of the struct expects them to be dropped!
|
// The layout of the struct expects them to be dropped!
|
||||||
if !tag_field_layout.is_dropped_because_empty() {
|
if !tag_field_layout.is_dropped_because_empty() {
|
||||||
let field_type =
|
let field_type = basic_type_from_layout(env, tag_field_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, tag_field_layout, ptr_size);
|
|
||||||
|
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
|
|
||||||
|
@ -1076,8 +1064,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// This tricks comes from
|
// This tricks comes from
|
||||||
// https://github.com/raviqqe/ssf/blob/bc32aae68940d5bddf5984128e85af75ca4f4686/ssf-llvm/src/expression_compiler.rs#L116
|
// https://github.com/raviqqe/ssf/blob/bc32aae68940d5bddf5984128e85af75ca4f4686/ssf-llvm/src/expression_compiler.rs#L116
|
||||||
|
|
||||||
let internal_type =
|
let internal_type = basic_type_from_layout(env, &tag_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &tag_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
cast_tag_to_block_of_memory(builder, struct_val.into_struct_value(), internal_type)
|
cast_tag_to_block_of_memory(builder, struct_val.into_struct_value(), internal_type)
|
||||||
}
|
}
|
||||||
|
@ -1091,7 +1078,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
||||||
|
|
||||||
debug_assert!(*union_size > 1);
|
debug_assert!(*union_size > 1);
|
||||||
let ptr_size = env.ptr_bytes;
|
|
||||||
|
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
@ -1109,8 +1095,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// Zero-sized fields have no runtime representation.
|
// Zero-sized fields have no runtime representation.
|
||||||
// The layout of the struct expects them to be dropped!
|
// The layout of the struct expects them to be dropped!
|
||||||
if !tag_field_layout.is_dropped_because_empty() {
|
if !tag_field_layout.is_dropped_because_empty() {
|
||||||
let field_type =
|
let field_type = basic_type_from_layout(env, tag_field_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, tag_field_layout, ptr_size);
|
|
||||||
|
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
|
|
||||||
|
@ -1172,7 +1157,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
let struct_layout =
|
let struct_layout =
|
||||||
Layout::Union(UnionLayout::NonRecursive(env.arena.alloc([*fields])));
|
Layout::Union(UnionLayout::NonRecursive(env.arena.alloc([*fields])));
|
||||||
|
|
||||||
let ptr_size = env.ptr_bytes;
|
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
|
@ -1187,8 +1171,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// Zero-sized fields have no runtime representation.
|
// Zero-sized fields have no runtime representation.
|
||||||
// The layout of the struct expects them to be dropped!
|
// The layout of the struct expects them to be dropped!
|
||||||
if !tag_field_layout.is_dropped_because_empty() {
|
if !tag_field_layout.is_dropped_because_empty() {
|
||||||
let field_type =
|
let field_type = basic_type_from_layout(env, tag_field_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, tag_field_layout, ptr_size);
|
|
||||||
|
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
|
|
||||||
|
@ -1247,8 +1230,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
let tag_layout = Layout::Union(UnionLayout::NonRecursive(fields));
|
||||||
let tag_struct_type =
|
let tag_struct_type = basic_type_from_layout(env, &tag_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &tag_layout, env.ptr_bytes);
|
|
||||||
if *tag_id == *nullable_id as u8 {
|
if *tag_id == *nullable_id as u8 {
|
||||||
let output_type = tag_struct_type.ptr_type(AddressSpace::Generic);
|
let output_type = tag_struct_type.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
@ -1256,7 +1238,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(*union_size > 1);
|
debug_assert!(*union_size > 1);
|
||||||
let ptr_size = env.ptr_bytes;
|
|
||||||
|
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
@ -1281,8 +1262,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// Zero-sized fields have no runtime representation.
|
// Zero-sized fields have no runtime representation.
|
||||||
// The layout of the struct expects them to be dropped!
|
// The layout of the struct expects them to be dropped!
|
||||||
if !tag_field_layout.is_dropped_because_empty() {
|
if !tag_field_layout.is_dropped_because_empty() {
|
||||||
let field_type =
|
let field_type = basic_type_from_layout(env, tag_field_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, tag_field_layout, ptr_size);
|
|
||||||
|
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
|
|
||||||
|
@ -1359,7 +1339,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
debug_assert!(!arguments.is_empty());
|
debug_assert!(!arguments.is_empty());
|
||||||
|
|
||||||
debug_assert!(*union_size == 2);
|
debug_assert!(*union_size == 2);
|
||||||
let ptr_size = env.ptr_bytes;
|
|
||||||
|
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
@ -1382,8 +1361,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// Zero-sized fields have no runtime representation.
|
// Zero-sized fields have no runtime representation.
|
||||||
// The layout of the struct expects them to be dropped!
|
// The layout of the struct expects them to be dropped!
|
||||||
if !tag_field_layout.is_dropped_because_empty() {
|
if !tag_field_layout.is_dropped_because_empty() {
|
||||||
let field_type =
|
let field_type = basic_type_from_layout(env, tag_field_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, tag_field_layout, ptr_size);
|
|
||||||
|
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
|
|
||||||
|
@ -1484,12 +1462,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
Layout::Union(UnionLayout::NonNullableUnwrapped(fields)),
|
Layout::Union(UnionLayout::NonNullableUnwrapped(fields)),
|
||||||
) => {
|
) => {
|
||||||
let struct_layout = Layout::Struct(fields);
|
let struct_layout = Layout::Struct(fields);
|
||||||
let struct_type = basic_type_from_layout(
|
let struct_type = basic_type_from_layout(env, &struct_layout);
|
||||||
env.arena,
|
|
||||||
env.context,
|
|
||||||
&struct_layout,
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
let cast_argument = env
|
let cast_argument = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -1531,11 +1504,9 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
||||||
// Determine types, assumes the descriminant is in the field layouts
|
// Determine types, assumes the descriminant is in the field layouts
|
||||||
let num_fields = field_layouts.len();
|
let num_fields = field_layouts.len();
|
||||||
let mut field_types = Vec::with_capacity_in(num_fields, env.arena);
|
let mut field_types = Vec::with_capacity_in(num_fields, env.arena);
|
||||||
let ptr_bytes = env.ptr_bytes;
|
|
||||||
|
|
||||||
for field_layout in field_layouts.iter() {
|
for field_layout in field_layouts.iter() {
|
||||||
let field_type =
|
let field_type = basic_type_from_layout(env, &field_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &field_layout, ptr_bytes);
|
|
||||||
field_types.push(field_type);
|
field_types.push(field_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1727,7 +1698,7 @@ fn lookup_at_index_ptr<'a, 'ctx, 'env>(
|
||||||
// a pointer to the block of memory representation
|
// a pointer to the block of memory representation
|
||||||
builder.build_bitcast(
|
builder.build_bitcast(
|
||||||
result,
|
result,
|
||||||
basic_type_from_layout(env.arena, env.context, structure_layout, env.ptr_bytes),
|
basic_type_from_layout(env, structure_layout),
|
||||||
"cast_rec_pointer_lookup_at_index_ptr",
|
"cast_rec_pointer_lookup_at_index_ptr",
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1773,7 +1744,7 @@ pub fn allocate_with_refcount_help<'a, 'ctx, 'env>(
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
|
|
||||||
let value_type = basic_type_from_layout(env.arena, ctx, layout, env.ptr_bytes);
|
let value_type = basic_type_from_layout(env, layout);
|
||||||
let len_type = env.ptr_int();
|
let len_type = env.ptr_int();
|
||||||
|
|
||||||
let extra_bytes = layout.alignment_bytes(env.ptr_bytes).max(env.ptr_bytes);
|
let extra_bytes = layout.alignment_bytes(env.ptr_bytes).max(env.ptr_bytes);
|
||||||
|
@ -2189,8 +2160,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
cond_layout,
|
cond_layout,
|
||||||
cond_symbol,
|
cond_symbol,
|
||||||
} => {
|
} => {
|
||||||
let ret_type =
|
let ret_type = basic_type_from_layout(env, &ret_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &ret_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
let switch_args = SwitchArgsIr {
|
let switch_args = SwitchArgsIr {
|
||||||
cond_layout: *cond_layout,
|
cond_layout: *cond_layout,
|
||||||
|
@ -2214,8 +2184,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
let mut joinpoint_args = Vec::with_capacity_in(parameters.len(), env.arena);
|
let mut joinpoint_args = Vec::with_capacity_in(parameters.len(), env.arena);
|
||||||
|
|
||||||
for param in parameters.iter() {
|
for param in parameters.iter() {
|
||||||
let btype =
|
let btype = basic_type_from_layout(env, ¶m.layout);
|
||||||
basic_type_from_layout(env.arena, env.context, ¶m.layout, env.ptr_bytes);
|
|
||||||
joinpoint_args.push(create_entry_block_alloca(
|
joinpoint_args.push(create_entry_block_alloca(
|
||||||
env,
|
env,
|
||||||
parent,
|
parent,
|
||||||
|
@ -3077,7 +3046,6 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let args = proc.args;
|
let args = proc.args;
|
||||||
let arena = env.arena;
|
let arena = env.arena;
|
||||||
let context = &env.context;
|
|
||||||
|
|
||||||
let fn_name = layout_ids
|
let fn_name = layout_ids
|
||||||
.get(symbol, layout)
|
.get(symbol, layout)
|
||||||
|
@ -3114,11 +3082,11 @@ pub fn build_proc_header<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret_type = basic_type_from_layout(arena, context, &proc.ret_layout, env.ptr_bytes);
|
let ret_type = basic_type_from_layout(env, &proc.ret_layout);
|
||||||
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
|
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
|
||||||
|
|
||||||
for (layout, _) in args.iter() {
|
for (layout, _) in args.iter() {
|
||||||
let arg_type = basic_type_from_layout(arena, env.context, &layout, env.ptr_bytes);
|
let arg_type = basic_type_from_layout(env, &layout);
|
||||||
|
|
||||||
arg_basic_types.push(arg_type);
|
arg_basic_types.push(arg_type);
|
||||||
}
|
}
|
||||||
|
@ -3167,7 +3135,7 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
let mut argument_types = Vec::with_capacity_in(arguments.len() + 3, env.arena);
|
let mut argument_types = Vec::with_capacity_in(arguments.len() + 3, env.arena);
|
||||||
|
|
||||||
for layout in arguments {
|
for layout in arguments {
|
||||||
let arg_type = basic_type_from_layout(arena, context, layout, env.ptr_bytes);
|
let arg_type = basic_type_from_layout(env, layout);
|
||||||
let arg_ptr_type = arg_type.ptr_type(AddressSpace::Generic);
|
let arg_ptr_type = arg_type.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
argument_types.push(arg_ptr_type.into());
|
argument_types.push(arg_ptr_type.into());
|
||||||
|
@ -3178,23 +3146,18 @@ pub fn build_closure_caller<'a, 'ctx, 'env>(
|
||||||
ClosureLayout::extend_function_layout(arena, arguments, *closure, result);
|
ClosureLayout::extend_function_layout(arena, arguments, *closure, result);
|
||||||
|
|
||||||
// this is already a (function) pointer type
|
// this is already a (function) pointer type
|
||||||
basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes)
|
basic_type_from_layout(env, &function_layout)
|
||||||
};
|
};
|
||||||
argument_types.push(function_pointer_type);
|
argument_types.push(function_pointer_type);
|
||||||
|
|
||||||
let closure_argument_type = {
|
let closure_argument_type = {
|
||||||
let basic_type = basic_type_from_layout(
|
let basic_type = basic_type_from_layout(env, &closure.as_block_of_memory_layout());
|
||||||
arena,
|
|
||||||
context,
|
|
||||||
&closure.as_block_of_memory_layout(),
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
basic_type.ptr_type(AddressSpace::Generic)
|
basic_type.ptr_type(AddressSpace::Generic)
|
||||||
};
|
};
|
||||||
argument_types.push(closure_argument_type.into());
|
argument_types.push(closure_argument_type.into());
|
||||||
|
|
||||||
let result_type = basic_type_from_layout(arena, context, result, env.ptr_bytes);
|
let result_type = basic_type_from_layout(env, result);
|
||||||
|
|
||||||
let roc_call_result_type =
|
let roc_call_result_type =
|
||||||
context.struct_type(&[context.i64_type().into(), result_type], false);
|
context.struct_type(&[context.i64_type().into(), result_type], false);
|
||||||
|
@ -3263,7 +3226,6 @@ pub fn build_function_caller<'a, 'ctx, 'env>(
|
||||||
) {
|
) {
|
||||||
use inkwell::types::BasicType;
|
use inkwell::types::BasicType;
|
||||||
|
|
||||||
let arena = env.arena;
|
|
||||||
let context = &env.context;
|
let context = &env.context;
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
|
@ -3279,7 +3241,7 @@ pub fn build_function_caller<'a, 'ctx, 'env>(
|
||||||
let mut argument_types = Vec::with_capacity_in(arguments.len() + 3, env.arena);
|
let mut argument_types = Vec::with_capacity_in(arguments.len() + 3, env.arena);
|
||||||
|
|
||||||
for layout in arguments {
|
for layout in arguments {
|
||||||
let arg_type = basic_type_from_layout(arena, context, layout, env.ptr_bytes);
|
let arg_type = basic_type_from_layout(env, layout);
|
||||||
let arg_ptr_type = arg_type.ptr_type(AddressSpace::Generic);
|
let arg_ptr_type = arg_type.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
argument_types.push(arg_ptr_type.into());
|
argument_types.push(arg_ptr_type.into());
|
||||||
|
@ -3295,19 +3257,18 @@ pub fn build_function_caller<'a, 'ctx, 'env>(
|
||||||
let function_layout = Layout::FunctionPointer(&args, result);
|
let function_layout = Layout::FunctionPointer(&args, result);
|
||||||
|
|
||||||
// this is already a (function) pointer type
|
// this is already a (function) pointer type
|
||||||
basic_type_from_layout(arena, context, &function_layout, env.ptr_bytes)
|
basic_type_from_layout(env, &function_layout)
|
||||||
};
|
};
|
||||||
argument_types.push(function_pointer_type);
|
argument_types.push(function_pointer_type);
|
||||||
|
|
||||||
let closure_argument_type = {
|
let closure_argument_type = {
|
||||||
let basic_type =
|
let basic_type = basic_type_from_layout(env, &Layout::Struct(&[]));
|
||||||
basic_type_from_layout(arena, context, &Layout::Struct(&[]), env.ptr_bytes);
|
|
||||||
|
|
||||||
basic_type.ptr_type(AddressSpace::Generic)
|
basic_type.ptr_type(AddressSpace::Generic)
|
||||||
};
|
};
|
||||||
argument_types.push(closure_argument_type.into());
|
argument_types.push(closure_argument_type.into());
|
||||||
|
|
||||||
let result_type = basic_type_from_layout(arena, context, result, env.ptr_bytes);
|
let result_type = basic_type_from_layout(env, result);
|
||||||
|
|
||||||
let roc_call_result_type =
|
let roc_call_result_type =
|
||||||
context.struct_type(&[context.i64_type().into(), result_type], false);
|
context.struct_type(&[context.i64_type().into(), result_type], false);
|
||||||
|
@ -3338,12 +3299,8 @@ pub fn build_function_caller<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
// let closure_data = context.struct_type(&[], false).const_zero().into();
|
// let closure_data = context.struct_type(&[], false).const_zero().into();
|
||||||
|
|
||||||
let actual_function_type = basic_type_from_layout(
|
let actual_function_type =
|
||||||
arena,
|
basic_type_from_layout(env, &Layout::FunctionPointer(arguments, result));
|
||||||
context,
|
|
||||||
&Layout::FunctionPointer(arguments, result),
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
let function_ptr = builder
|
let function_ptr = builder
|
||||||
.build_bitcast(function_ptr, actual_function_type, "cast")
|
.build_bitcast(function_ptr, actual_function_type, "cast")
|
||||||
|
@ -3387,7 +3344,7 @@ fn build_host_exposed_alias_size<'a, 'ctx, 'env>(
|
||||||
def_name,
|
def_name,
|
||||||
alias_symbol,
|
alias_symbol,
|
||||||
None,
|
None,
|
||||||
basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes),
|
basic_type_from_layout(env, layout),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4115,8 +4072,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let arg = load_symbol(scope, &args[0]).into_int_value();
|
let arg = load_symbol(scope, &args[0]).into_int_value();
|
||||||
|
|
||||||
let to = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes)
|
let to = basic_type_from_layout(env, layout).into_int_type();
|
||||||
.into_int_type();
|
|
||||||
|
|
||||||
env.builder.build_int_cast(arg, to, "inc_cast").into()
|
env.builder.build_int_cast(arg, to, "inc_cast").into()
|
||||||
}
|
}
|
||||||
|
@ -4455,7 +4411,7 @@ fn build_foreign_symbol_return_result<'a, 'ctx, 'env>(
|
||||||
for arg in arguments.iter() {
|
for arg in arguments.iter() {
|
||||||
let (value, layout) = load_symbol_and_layout(scope, arg);
|
let (value, layout) = load_symbol_and_layout(scope, arg);
|
||||||
arg_vals.push(value);
|
arg_vals.push(value);
|
||||||
let arg_type = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes);
|
let arg_type = basic_type_from_layout(env, layout);
|
||||||
debug_assert_eq!(arg_type, value.get_type());
|
debug_assert_eq!(arg_type, value.get_type());
|
||||||
arg_types.push(arg_type);
|
arg_types.push(arg_type);
|
||||||
}
|
}
|
||||||
|
@ -4482,7 +4438,7 @@ fn build_foreign_symbol_write_result_into_ptr<'a, 'ctx, 'env>(
|
||||||
for arg in arguments.iter() {
|
for arg in arguments.iter() {
|
||||||
let (value, layout) = load_symbol_and_layout(scope, arg);
|
let (value, layout) = load_symbol_and_layout(scope, arg);
|
||||||
arg_vals.push(value);
|
arg_vals.push(value);
|
||||||
let arg_type = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes);
|
let arg_type = basic_type_from_layout(env, layout);
|
||||||
debug_assert_eq!(arg_type, value.get_type());
|
debug_assert_eq!(arg_type, value.get_type());
|
||||||
arg_types.push(arg_type);
|
arg_types.push(arg_type);
|
||||||
}
|
}
|
||||||
|
@ -4504,7 +4460,7 @@ fn build_foreign_symbol<'a, 'ctx, 'env>(
|
||||||
ret_layout: &Layout<'a>,
|
ret_layout: &Layout<'a>,
|
||||||
call_or_invoke: ForeignCallOrInvoke<'a>,
|
call_or_invoke: ForeignCallOrInvoke<'a>,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let ret_type = basic_type_from_layout(env.arena, env.context, ret_layout, env.ptr_bytes);
|
let ret_type = basic_type_from_layout(env, ret_layout);
|
||||||
let return_pointer = env.builder.build_alloca(ret_type, "return_value");
|
let return_pointer = env.builder.build_alloca(ret_type, "return_value");
|
||||||
|
|
||||||
// crude approximation of the C calling convention
|
// crude approximation of the C calling convention
|
||||||
|
@ -4611,9 +4567,8 @@ where
|
||||||
Layout::Builtin(Builtin::List(MemoryMode::Refcounted, _)) => {
|
Layout::Builtin(Builtin::List(MemoryMode::Refcounted, _)) => {
|
||||||
// no static guarantees, but all is not lost: we can check the refcount
|
// no static guarantees, but all is not lost: we can check the refcount
|
||||||
// if it is one, we hold the final reference, and can mutate it in-place!
|
// if it is one, we hold the final reference, and can mutate it in-place!
|
||||||
let ctx = env.context;
|
|
||||||
|
|
||||||
let ret_type = basic_type_from_layout(env.arena, ctx, list_layout, env.ptr_bytes);
|
let ret_type = basic_type_from_layout(env, list_layout);
|
||||||
|
|
||||||
let refcount_ptr = PointerToRefcount::from_list_wrapper(env, original_wrapper);
|
let refcount_ptr = PointerToRefcount::from_list_wrapper(env, original_wrapper);
|
||||||
let refcount = refcount_ptr.get_refcount(env);
|
let refcount = refcount_ptr.get_refcount(env);
|
||||||
|
@ -5109,7 +5064,7 @@ fn builtin_to_int_type<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
builtin: &Builtin<'a>,
|
builtin: &Builtin<'a>,
|
||||||
) -> IntType<'ctx> {
|
) -> IntType<'ctx> {
|
||||||
let result = basic_type_from_builtin(env.arena, env.context, builtin, env.ptr_bytes);
|
let result = basic_type_from_builtin(env, builtin);
|
||||||
debug_assert!(result.is_int_type());
|
debug_assert!(result.is_int_type());
|
||||||
|
|
||||||
result.into_int_type()
|
result.into_int_type()
|
||||||
|
@ -5229,10 +5184,7 @@ fn int_abs_with_overflow<'a, 'ctx, 'env>(
|
||||||
let bits_to_shift = ((arg_layout.stack_size(env.ptr_bytes) as u64) * 8) - 1;
|
let bits_to_shift = ((arg_layout.stack_size(env.ptr_bytes) as u64) * 8) - 1;
|
||||||
let shift_val = ctx.i64_type().const_int(bits_to_shift, false);
|
let shift_val = ctx.i64_type().const_int(bits_to_shift, false);
|
||||||
let shifted = bd.build_right_shift(arg, shift_val, true, shifted_name);
|
let shifted = bd.build_right_shift(arg, shift_val, true, shifted_name);
|
||||||
let alloca = bd.build_alloca(
|
let alloca = bd.build_alloca(basic_type_from_builtin(env, arg_layout), "#int_abs_help");
|
||||||
basic_type_from_builtin(env.arena, ctx, arg_layout, env.ptr_bytes),
|
|
||||||
"#int_abs_help",
|
|
||||||
);
|
|
||||||
|
|
||||||
// shifted = arg >>> 63
|
// shifted = arg >>> 63
|
||||||
bd.build_store(alloca, shifted);
|
bd.build_store(alloca, shifted);
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::llvm::bitcode::{
|
||||||
use crate::llvm::build::{
|
use crate::llvm::build::{
|
||||||
complex_bitcast, load_symbol, load_symbol_and_layout, set_name, Env, Scope,
|
complex_bitcast, load_symbol, load_symbol_and_layout, set_name, Env, Scope,
|
||||||
};
|
};
|
||||||
use crate::llvm::convert::{self, as_const_zero, basic_type_from_layout, collection};
|
use crate::llvm::convert::{as_const_zero, basic_type_from_layout, collection};
|
||||||
use crate::llvm::refcounting::Mode;
|
use crate::llvm::refcounting::Mode;
|
||||||
use inkwell::attributes::{Attribute, AttributeLoc};
|
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||||
use inkwell::types::BasicType;
|
use inkwell::types::BasicType;
|
||||||
|
@ -83,12 +83,7 @@ pub fn dict_empty<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
call_void_bitcode_fn(env, &[result_alloc.into()], &bitcode::DICT_EMPTY);
|
call_void_bitcode_fn(env, &[result_alloc.into()], &bitcode::DICT_EMPTY);
|
||||||
|
|
||||||
let result = env
|
env.builder.build_load(result_alloc, "load_result")
|
||||||
.builder
|
|
||||||
.build_load(result_alloc, "load_result")
|
|
||||||
.into_struct_value();
|
|
||||||
|
|
||||||
zig_dict_to_struct(env, result).into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -110,8 +105,7 @@ pub fn dict_insert<'a, 'ctx, 'env>(
|
||||||
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
||||||
let value_ptr = builder.build_alloca(value.get_type(), "value_ptr");
|
let value_ptr = builder.build_alloca(value.get_type(), "value_ptr");
|
||||||
|
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
env.builder.build_store(key_ptr, key);
|
env.builder.build_store(key_ptr, key);
|
||||||
env.builder.build_store(value_ptr, value);
|
env.builder.build_store(value_ptr, value);
|
||||||
|
|
||||||
|
@ -152,15 +146,6 @@ pub fn dict_insert<'a, 'ctx, 'env>(
|
||||||
&bitcode::DICT_INSERT,
|
&bitcode::DICT_INSERT,
|
||||||
);
|
);
|
||||||
|
|
||||||
let result_ptr = env
|
|
||||||
.builder
|
|
||||||
.build_bitcast(
|
|
||||||
result_ptr,
|
|
||||||
convert::dict(env.context, env.ptr_bytes).ptr_type(AddressSpace::Generic),
|
|
||||||
"to_roc_dict",
|
|
||||||
)
|
|
||||||
.into_pointer_value();
|
|
||||||
|
|
||||||
env.builder.build_load(result_ptr, "load_result")
|
env.builder.build_load(result_ptr, "load_result")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +166,7 @@ pub fn dict_remove<'a, 'ctx, 'env>(
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
||||||
|
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
env.builder.build_store(key_ptr, key);
|
env.builder.build_store(key_ptr, key);
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
|
@ -221,15 +205,6 @@ pub fn dict_remove<'a, 'ctx, 'env>(
|
||||||
&bitcode::DICT_REMOVE,
|
&bitcode::DICT_REMOVE,
|
||||||
);
|
);
|
||||||
|
|
||||||
let result_ptr = env
|
|
||||||
.builder
|
|
||||||
.build_bitcast(
|
|
||||||
result_ptr,
|
|
||||||
convert::dict(env.context, env.ptr_bytes).ptr_type(AddressSpace::Generic),
|
|
||||||
"to_roc_dict",
|
|
||||||
)
|
|
||||||
.into_pointer_value();
|
|
||||||
|
|
||||||
env.builder.build_load(result_ptr, "load_result")
|
env.builder.build_load(result_ptr, "load_result")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +225,7 @@ pub fn dict_contains<'a, 'ctx, 'env>(
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
||||||
|
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
env.builder.build_store(key_ptr, key);
|
env.builder.build_store(key_ptr, key);
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
|
@ -300,8 +274,7 @@ pub fn dict_get<'a, 'ctx, 'env>(
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
let key_ptr = builder.build_alloca(key.get_type(), "key_ptr");
|
||||||
|
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
env.builder.build_store(key_ptr, key);
|
env.builder.build_store(key_ptr, key);
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
|
@ -355,7 +328,7 @@ pub fn dict_get<'a, 'ctx, 'env>(
|
||||||
let if_not_null = env.context.append_basic_block(parent, "if_not_null");
|
let if_not_null = env.context.append_basic_block(parent, "if_not_null");
|
||||||
let done_block = env.context.append_basic_block(parent, "done");
|
let done_block = env.context.append_basic_block(parent, "done");
|
||||||
|
|
||||||
let value_bt = basic_type_from_layout(env.arena, env.context, value_layout, env.ptr_bytes);
|
let value_bt = basic_type_from_layout(env, value_layout);
|
||||||
let default = as_const_zero(&value_bt);
|
let default = as_const_zero(&value_bt);
|
||||||
|
|
||||||
env.builder
|
env.builder
|
||||||
|
@ -411,8 +384,7 @@ pub fn dict_elements_rc<'a, 'ctx, 'env>(
|
||||||
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
|
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
|
||||||
|
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
.ptr_int()
|
.ptr_int()
|
||||||
|
@ -457,8 +429,7 @@ pub fn dict_keys<'a, 'ctx, 'env>(
|
||||||
let zig_list_type = env.module.get_struct_type("list.RocList").unwrap();
|
let zig_list_type = env.module.get_struct_type("list.RocList").unwrap();
|
||||||
|
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
.ptr_int()
|
.ptr_int()
|
||||||
|
@ -516,15 +487,8 @@ pub fn dict_union<'a, 'ctx, 'env>(
|
||||||
let dict1_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict1_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
let dict2_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict2_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
|
|
||||||
env.builder.build_store(
|
env.builder.build_store(dict1_ptr, dict1);
|
||||||
dict1_ptr,
|
env.builder.build_store(dict2_ptr, dict2);
|
||||||
struct_to_zig_dict(env, dict1.into_struct_value()),
|
|
||||||
);
|
|
||||||
|
|
||||||
env.builder.build_store(
|
|
||||||
dict2_ptr,
|
|
||||||
struct_to_zig_dict(env, dict2.into_struct_value()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
.ptr_int()
|
.ptr_int()
|
||||||
|
@ -562,15 +526,6 @@ pub fn dict_union<'a, 'ctx, 'env>(
|
||||||
&bitcode::DICT_UNION,
|
&bitcode::DICT_UNION,
|
||||||
);
|
);
|
||||||
|
|
||||||
let output_ptr = env
|
|
||||||
.builder
|
|
||||||
.build_bitcast(
|
|
||||||
output_ptr,
|
|
||||||
convert::dict(env.context, env.ptr_bytes).ptr_type(AddressSpace::Generic),
|
|
||||||
"to_roc_dict",
|
|
||||||
)
|
|
||||||
.into_pointer_value();
|
|
||||||
|
|
||||||
env.builder.build_load(output_ptr, "load_output_ptr")
|
env.builder.build_load(output_ptr, "load_output_ptr")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,15 +586,8 @@ fn dict_intersect_or_difference<'a, 'ctx, 'env>(
|
||||||
let dict1_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict1_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
let dict2_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict2_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
|
|
||||||
env.builder.build_store(
|
env.builder.build_store(dict1_ptr, dict1);
|
||||||
dict1_ptr,
|
env.builder.build_store(dict2_ptr, dict2);
|
||||||
struct_to_zig_dict(env, dict1.into_struct_value()),
|
|
||||||
);
|
|
||||||
|
|
||||||
env.builder.build_store(
|
|
||||||
dict2_ptr,
|
|
||||||
struct_to_zig_dict(env, dict2.into_struct_value()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
.ptr_int()
|
.ptr_int()
|
||||||
|
@ -677,15 +625,6 @@ fn dict_intersect_or_difference<'a, 'ctx, 'env>(
|
||||||
op,
|
op,
|
||||||
);
|
);
|
||||||
|
|
||||||
let output_ptr = env
|
|
||||||
.builder
|
|
||||||
.build_bitcast(
|
|
||||||
output_ptr,
|
|
||||||
convert::dict(env.context, env.ptr_bytes).ptr_type(AddressSpace::Generic),
|
|
||||||
"to_roc_dict",
|
|
||||||
)
|
|
||||||
.into_pointer_value();
|
|
||||||
|
|
||||||
env.builder.build_load(output_ptr, "load_output_ptr")
|
env.builder.build_load(output_ptr, "load_output_ptr")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,8 +646,7 @@ pub fn dict_walk<'a, 'ctx, 'env>(
|
||||||
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
|
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
|
||||||
|
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
|
|
||||||
let stepper_ptr = builder.build_alloca(stepper.get_type(), "stepper_ptr");
|
let stepper_ptr = builder.build_alloca(stepper.get_type(), "stepper_ptr");
|
||||||
env.builder.build_store(stepper_ptr, stepper);
|
env.builder.build_store(stepper_ptr, stepper);
|
||||||
|
@ -722,7 +660,7 @@ pub fn dict_walk<'a, 'ctx, 'env>(
|
||||||
.as_global_value()
|
.as_global_value()
|
||||||
.as_pointer_value();
|
.as_pointer_value();
|
||||||
|
|
||||||
let accum_bt = basic_type_from_layout(env.arena, env.context, accum_layout, env.ptr_bytes);
|
let accum_bt = basic_type_from_layout(env, accum_layout);
|
||||||
let accum_ptr = builder.build_alloca(accum_bt, "accum_ptr");
|
let accum_ptr = builder.build_alloca(accum_bt, "accum_ptr");
|
||||||
env.builder.build_store(accum_ptr, accum);
|
env.builder.build_store(accum_ptr, accum);
|
||||||
|
|
||||||
|
@ -781,8 +719,7 @@ pub fn dict_values<'a, 'ctx, 'env>(
|
||||||
let zig_list_type = env.module.get_struct_type("list.RocList").unwrap();
|
let zig_list_type = env.module.get_struct_type("list.RocList").unwrap();
|
||||||
|
|
||||||
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
let dict_ptr = builder.build_alloca(zig_dict_type, "dict_ptr");
|
||||||
env.builder
|
env.builder.build_store(dict_ptr, dict);
|
||||||
.build_store(dict_ptr, struct_to_zig_dict(env, dict.into_struct_value()));
|
|
||||||
|
|
||||||
let key_width = env
|
let key_width = env
|
||||||
.ptr_int()
|
.ptr_int()
|
||||||
|
@ -833,8 +770,6 @@ pub fn set_from_list<'a, 'ctx, 'env>(
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
|
|
||||||
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
|
|
||||||
|
|
||||||
let list_alloca = builder.build_alloca(list.get_type(), "list_alloca");
|
let list_alloca = builder.build_alloca(list.get_type(), "list_alloca");
|
||||||
let list_ptr = env.builder.build_bitcast(
|
let list_ptr = env.builder.build_bitcast(
|
||||||
list_alloca,
|
list_alloca,
|
||||||
|
@ -850,13 +785,7 @@ pub fn set_from_list<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let value_width = env.ptr_int().const_zero();
|
let value_width = env.ptr_int().const_zero();
|
||||||
|
|
||||||
let result_alloca =
|
let result_alloca = builder.build_alloca(zig_dict_type(env), "result_alloca");
|
||||||
builder.build_alloca(convert::dict(env.context, env.ptr_bytes), "result_alloca");
|
|
||||||
let result_ptr = builder.build_bitcast(
|
|
||||||
result_alloca,
|
|
||||||
zig_dict_type.ptr_type(AddressSpace::Generic),
|
|
||||||
"to_zig_dict",
|
|
||||||
);
|
|
||||||
|
|
||||||
let alignment =
|
let alignment =
|
||||||
Alignment::from_key_value_layout(key_layout, &Layout::Struct(&[]), env.ptr_bytes);
|
Alignment::from_key_value_layout(key_layout, &Layout::Struct(&[]), env.ptr_bytes);
|
||||||
|
@ -878,7 +807,7 @@ pub fn set_from_list<'a, 'ctx, 'env>(
|
||||||
hash_fn.as_global_value().as_pointer_value().into(),
|
hash_fn.as_global_value().as_pointer_value().into(),
|
||||||
eq_fn.as_global_value().as_pointer_value().into(),
|
eq_fn.as_global_value().as_pointer_value().into(),
|
||||||
dec_key_fn.as_global_value().as_pointer_value().into(),
|
dec_key_fn.as_global_value().as_pointer_value().into(),
|
||||||
result_ptr,
|
result_alloca.into(),
|
||||||
],
|
],
|
||||||
&bitcode::SET_FROM_LIST,
|
&bitcode::SET_FROM_LIST,
|
||||||
);
|
);
|
||||||
|
@ -929,8 +858,7 @@ fn build_hash_wrapper<'a, 'ctx, 'env>(
|
||||||
set_name(seed_arg.into(), Symbol::ARG_1.ident_string(&env.interns));
|
set_name(seed_arg.into(), Symbol::ARG_1.ident_string(&env.interns));
|
||||||
set_name(value_ptr.into(), Symbol::ARG_2.ident_string(&env.interns));
|
set_name(value_ptr.into(), Symbol::ARG_2.ident_string(&env.interns));
|
||||||
|
|
||||||
let value_type = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes)
|
let value_type = basic_type_from_layout(env, layout).ptr_type(AddressSpace::Generic);
|
||||||
.ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
let value_cast = env
|
let value_cast = env
|
||||||
.builder
|
.builder
|
||||||
|
@ -968,31 +896,6 @@ fn dict_symbol_to_zig_dict<'a, 'ctx, 'env>(
|
||||||
.into_struct_value()
|
.into_struct_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zig_dict_to_struct<'a, 'ctx, 'env>(
|
fn zig_dict_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> inkwell::types::StructType<'ctx> {
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env.module.get_struct_type("dict.RocDict").unwrap()
|
||||||
zig_dict: StructValue<'ctx>,
|
|
||||||
) -> StructValue<'ctx> {
|
|
||||||
complex_bitcast(
|
|
||||||
env.builder,
|
|
||||||
zig_dict.into(),
|
|
||||||
crate::llvm::convert::dict(env.context, env.ptr_bytes).into(),
|
|
||||||
"to_zig_dict",
|
|
||||||
)
|
|
||||||
.into_struct_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn struct_to_zig_dict<'a, 'ctx, 'env>(
|
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
|
||||||
struct_dict: StructValue<'ctx>,
|
|
||||||
) -> StructValue<'ctx> {
|
|
||||||
// get the RocStr type defined by zig
|
|
||||||
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
|
|
||||||
|
|
||||||
complex_bitcast(
|
|
||||||
env.builder,
|
|
||||||
struct_dict.into(),
|
|
||||||
zig_dict_type.into(),
|
|
||||||
"to_zig_dict",
|
|
||||||
)
|
|
||||||
.into_struct_value()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ fn build_hash_layout<'a, 'ctx, 'env>(
|
||||||
WhenRecursive::Loop(union_layout) => {
|
WhenRecursive::Loop(union_layout) => {
|
||||||
let layout = Layout::Union(union_layout);
|
let layout = Layout::Union(union_layout);
|
||||||
|
|
||||||
let bt = basic_type_from_layout(env.arena, env.context, &layout, env.ptr_bytes);
|
let bt = basic_type_from_layout(env, &layout);
|
||||||
|
|
||||||
// cast the i64 pointer to a pointer to block of memory
|
// cast the i64 pointer to a pointer to block of memory
|
||||||
let field_cast = env
|
let field_cast = env
|
||||||
|
@ -190,12 +190,9 @@ fn build_hash_struct<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let arena = env.arena;
|
|
||||||
|
|
||||||
let seed_type = env.context.i64_type();
|
let seed_type = env.context.i64_type();
|
||||||
|
|
||||||
let arg_type =
|
let arg_type = basic_type_from_layout(env, &struct_layout);
|
||||||
basic_type_from_layout(arena, env.context, &struct_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
let function_value = crate::llvm::refcounting::build_header_help(
|
let function_value = crate::llvm::refcounting::build_header_help(
|
||||||
env,
|
env,
|
||||||
|
@ -289,12 +286,7 @@ fn hash_struct<'a, 'ctx, 'env>(
|
||||||
WhenRecursive::Loop(union_layout) => {
|
WhenRecursive::Loop(union_layout) => {
|
||||||
let field_layout = Layout::Union(*union_layout);
|
let field_layout = Layout::Union(*union_layout);
|
||||||
|
|
||||||
let bt = basic_type_from_layout(
|
let bt = basic_type_from_layout(env, &field_layout);
|
||||||
env.arena,
|
|
||||||
env.context,
|
|
||||||
&field_layout,
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
// cast the i64 pointer to a pointer to block of memory
|
// cast the i64 pointer to a pointer to block of memory
|
||||||
let field_cast = env
|
let field_cast = env
|
||||||
|
@ -346,11 +338,9 @@ fn build_hash_tag<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let arena = env.arena;
|
|
||||||
|
|
||||||
let seed_type = env.context.i64_type();
|
let seed_type = env.context.i64_type();
|
||||||
|
|
||||||
let arg_type = basic_type_from_layout(arena, env.context, &layout, env.ptr_bytes);
|
let arg_type = basic_type_from_layout(env, &layout);
|
||||||
|
|
||||||
let function_value = crate::llvm::refcounting::build_header_help(
|
let function_value = crate::llvm::refcounting::build_header_help(
|
||||||
env,
|
env,
|
||||||
|
@ -435,8 +425,7 @@ fn hash_tag<'a, 'ctx, 'env>(
|
||||||
// TODO drop tag id?
|
// TODO drop tag id?
|
||||||
let struct_layout = Layout::Struct(field_layouts);
|
let struct_layout = Layout::Struct(field_layouts);
|
||||||
|
|
||||||
let wrapper_type =
|
let wrapper_type = basic_type_from_layout(env, &struct_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &struct_layout, env.ptr_bytes);
|
|
||||||
debug_assert!(wrapper_type.is_struct_type());
|
debug_assert!(wrapper_type.is_struct_type());
|
||||||
|
|
||||||
let as_struct =
|
let as_struct =
|
||||||
|
@ -622,11 +611,9 @@ fn build_hash_list<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let arena = env.arena;
|
|
||||||
|
|
||||||
let seed_type = env.context.i64_type();
|
let seed_type = env.context.i64_type();
|
||||||
|
|
||||||
let arg_type = basic_type_from_layout(arena, env.context, &layout, env.ptr_bytes);
|
let arg_type = basic_type_from_layout(env, &layout);
|
||||||
|
|
||||||
let function_value = crate::llvm::refcounting::build_header_help(
|
let function_value = crate::llvm::refcounting::build_header_help(
|
||||||
env,
|
env,
|
||||||
|
@ -710,8 +697,7 @@ fn hash_list<'a, 'ctx, 'env>(
|
||||||
let done_block = env.context.append_basic_block(parent, "done");
|
let done_block = env.context.append_basic_block(parent, "done");
|
||||||
let loop_block = env.context.append_basic_block(parent, "loop");
|
let loop_block = env.context.append_basic_block(parent, "loop");
|
||||||
|
|
||||||
let element_type =
|
let element_type = basic_type_from_layout(env, element_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, element_layout, env.ptr_bytes);
|
|
||||||
let ptr_type = element_type.ptr_type(inkwell::AddressSpace::Generic);
|
let ptr_type = element_type.ptr_type(inkwell::AddressSpace::Generic);
|
||||||
|
|
||||||
let (length, ptr) = load_list(env.builder, value, ptr_type);
|
let (length, ptr) = load_list(env.builder, value, ptr_type);
|
||||||
|
@ -788,8 +774,7 @@ fn hash_ptr_to_struct<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let struct_layout = Layout::Struct(field_layouts);
|
let struct_layout = Layout::Struct(field_layouts);
|
||||||
|
|
||||||
let wrapper_type =
|
let wrapper_type = basic_type_from_layout(env, &struct_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &struct_layout, env.ptr_bytes);
|
|
||||||
debug_assert!(wrapper_type.is_struct_type());
|
debug_assert!(wrapper_type.is_struct_type());
|
||||||
|
|
||||||
// cast the opaque pointer to a pointer of the correct shape
|
// cast the opaque pointer to a pointer of the correct shape
|
||||||
|
@ -822,7 +807,7 @@ fn store_and_use_as_u8_ptr<'a, 'ctx, 'env>(
|
||||||
value: BasicValueEnum<'ctx>,
|
value: BasicValueEnum<'ctx>,
|
||||||
layout: &Layout<'a>,
|
layout: &Layout<'a>,
|
||||||
) -> PointerValue<'ctx> {
|
) -> PointerValue<'ctx> {
|
||||||
let basic_type = basic_type_from_layout(env.arena, env.context, &layout, env.ptr_bytes);
|
let basic_type = basic_type_from_layout(env, &layout);
|
||||||
let alloc = env.builder.build_alloca(basic_type, "store");
|
let alloc = env.builder.build_alloca(basic_type, "store");
|
||||||
env.builder.build_store(alloc, value);
|
env.builder.build_store(alloc, value);
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ pub fn list_prepend<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
// Load the usize length from the wrapper.
|
// Load the usize length from the wrapper.
|
||||||
let len = list_len(builder, original_wrapper);
|
let len = list_len(builder, original_wrapper);
|
||||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
let elem_type = basic_type_from_layout(env, elem_layout);
|
||||||
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||||
let list_ptr = load_list_ptr(builder, original_wrapper, ptr_type);
|
let list_ptr = load_list_ptr(builder, original_wrapper, ptr_type);
|
||||||
|
|
||||||
|
@ -185,11 +185,10 @@ pub fn list_join<'a, 'ctx, 'env>(
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
|
|
||||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
let elem_type = basic_type_from_layout(env, elem_layout);
|
||||||
let elem_ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
let elem_ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||||
|
|
||||||
let inner_list_type =
|
let inner_list_type = basic_type_from_layout(env, &inner_list_layout);
|
||||||
basic_type_from_layout(env.arena, ctx, &inner_list_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
let outer_list_wrapper = outer_list.into_struct_value();
|
let outer_list_wrapper = outer_list.into_struct_value();
|
||||||
let outer_list_len = list_len(builder, outer_list_wrapper);
|
let outer_list_len = list_len(builder, outer_list_wrapper);
|
||||||
|
@ -395,8 +394,7 @@ pub fn list_get_unsafe<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
match list_layout {
|
match list_layout {
|
||||||
Layout::Builtin(Builtin::List(_, elem_layout)) => {
|
Layout::Builtin(Builtin::List(_, elem_layout)) => {
|
||||||
let ctx = env.context;
|
let elem_type = basic_type_from_layout(env, elem_layout);
|
||||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
|
||||||
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||||
// Load the pointer to the array data
|
// Load the pointer to the array data
|
||||||
let array_data_ptr = load_list_ptr(builder, wrapper_struct, ptr_type);
|
let array_data_ptr = load_list_ptr(builder, wrapper_struct, ptr_type);
|
||||||
|
@ -497,7 +495,7 @@ pub fn list_set<'a, 'ctx, 'env>(
|
||||||
let build_then = || {
|
let build_then = || {
|
||||||
let (elem, elem_layout) = args[2];
|
let (elem, elem_layout) = args[2];
|
||||||
let ctx = env.context;
|
let ctx = env.context;
|
||||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
let elem_type = basic_type_from_layout(env, elem_layout);
|
||||||
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||||
|
|
||||||
let (new_wrapper, array_data_ptr) = match input_inplace {
|
let (new_wrapper, array_data_ptr) = match input_inplace {
|
||||||
|
@ -1385,8 +1383,7 @@ pub fn list_concat<'a, 'ctx, 'env>(
|
||||||
let second_list_length_comparison = list_is_not_empty(env, second_list_len);
|
let second_list_length_comparison = list_is_not_empty(env, second_list_len);
|
||||||
|
|
||||||
let build_second_list_then = || {
|
let build_second_list_then = || {
|
||||||
let elem_type =
|
let elem_type = basic_type_from_layout(env, elem_layout);
|
||||||
basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
|
||||||
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||||
|
|
||||||
let (new_wrapper, _) = clone_nonempty_list(
|
let (new_wrapper, _) = clone_nonempty_list(
|
||||||
|
@ -1413,7 +1410,7 @@ pub fn list_concat<'a, 'ctx, 'env>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let if_first_list_is_not_empty = || {
|
let if_first_list_is_not_empty = || {
|
||||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
let elem_type = basic_type_from_layout(env, elem_layout);
|
||||||
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||||
|
|
||||||
let if_second_list_is_empty = || {
|
let if_second_list_is_empty = || {
|
||||||
|
|
|
@ -172,7 +172,7 @@ fn build_eq<'a, 'ctx, 'env>(
|
||||||
WhenRecursive::Loop(union_layout) => {
|
WhenRecursive::Loop(union_layout) => {
|
||||||
let layout = Layout::Union(union_layout);
|
let layout = Layout::Union(union_layout);
|
||||||
|
|
||||||
let bt = basic_type_from_layout(env.arena, env.context, &layout, env.ptr_bytes);
|
let bt = basic_type_from_layout(env, &layout);
|
||||||
|
|
||||||
// cast the i64 pointer to a pointer to block of memory
|
// cast the i64 pointer to a pointer to block of memory
|
||||||
let field1_cast = env
|
let field1_cast = env
|
||||||
|
@ -377,8 +377,7 @@ fn build_list_eq<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let arena = env.arena;
|
let arg_type = basic_type_from_layout(env, &list_layout);
|
||||||
let arg_type = basic_type_from_layout(arena, env.context, &list_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
let function_value = crate::llvm::refcounting::build_header_help(
|
let function_value = crate::llvm::refcounting::build_header_help(
|
||||||
env,
|
env,
|
||||||
|
@ -475,8 +474,7 @@ fn build_list_eq_help<'a, 'ctx, 'env>(
|
||||||
env.builder.position_at_end(then_block);
|
env.builder.position_at_end(then_block);
|
||||||
|
|
||||||
let builder = env.builder;
|
let builder = env.builder;
|
||||||
let element_type =
|
let element_type = basic_type_from_layout(env, element_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, element_layout, env.ptr_bytes);
|
|
||||||
let ptr_type = get_ptr_type(&element_type, AddressSpace::Generic);
|
let ptr_type = get_ptr_type(&element_type, AddressSpace::Generic);
|
||||||
let ptr1 = load_list_ptr(env.builder, list1, ptr_type);
|
let ptr1 = load_list_ptr(env.builder, list1, ptr_type);
|
||||||
let ptr2 = load_list_ptr(env.builder, list2, ptr_type);
|
let ptr2 = load_list_ptr(env.builder, list2, ptr_type);
|
||||||
|
@ -587,9 +585,7 @@ fn build_struct_eq<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let arena = env.arena;
|
let arg_type = basic_type_from_layout(env, &struct_layout);
|
||||||
let arg_type =
|
|
||||||
basic_type_from_layout(arena, env.context, &struct_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
let function_value = crate::llvm::refcounting::build_header_help(
|
let function_value = crate::llvm::refcounting::build_header_help(
|
||||||
env,
|
env,
|
||||||
|
@ -692,12 +688,7 @@ fn build_struct_eq_help<'a, 'ctx, 'env>(
|
||||||
WhenRecursive::Loop(union_layout) => {
|
WhenRecursive::Loop(union_layout) => {
|
||||||
let field_layout = Layout::Union(*union_layout);
|
let field_layout = Layout::Union(*union_layout);
|
||||||
|
|
||||||
let bt = basic_type_from_layout(
|
let bt = basic_type_from_layout(env, &field_layout);
|
||||||
env.arena,
|
|
||||||
env.context,
|
|
||||||
&field_layout,
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
// cast the i64 pointer to a pointer to block of memory
|
// cast the i64 pointer to a pointer to block of memory
|
||||||
let field1_cast = env
|
let field1_cast = env
|
||||||
|
@ -777,8 +768,7 @@ fn build_tag_eq<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let arena = env.arena;
|
let arg_type = basic_type_from_layout(env, &tag_layout);
|
||||||
let arg_type = basic_type_from_layout(arena, env.context, &tag_layout, env.ptr_bytes);
|
|
||||||
|
|
||||||
let function_value = crate::llvm::refcounting::build_header_help(
|
let function_value = crate::llvm::refcounting::build_header_help(
|
||||||
env,
|
env,
|
||||||
|
@ -897,8 +887,7 @@ fn build_tag_eq_help<'a, 'ctx, 'env>(
|
||||||
// TODO drop tag id?
|
// TODO drop tag id?
|
||||||
let struct_layout = Layout::Struct(field_layouts);
|
let struct_layout = Layout::Struct(field_layouts);
|
||||||
|
|
||||||
let wrapper_type =
|
let wrapper_type = basic_type_from_layout(env, &struct_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &struct_layout, env.ptr_bytes);
|
|
||||||
debug_assert!(wrapper_type.is_struct_type());
|
debug_assert!(wrapper_type.is_struct_type());
|
||||||
|
|
||||||
let struct1 = cast_block_of_memory_to_tag(
|
let struct1 = cast_block_of_memory_to_tag(
|
||||||
|
@ -1197,8 +1186,7 @@ fn eq_ptr_to_struct<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let struct_layout = Layout::Struct(field_layouts);
|
let struct_layout = Layout::Struct(field_layouts);
|
||||||
|
|
||||||
let wrapper_type =
|
let wrapper_type = basic_type_from_layout(env, &struct_layout);
|
||||||
basic_type_from_layout(env.arena, env.context, &struct_layout, env.ptr_bytes);
|
|
||||||
debug_assert!(wrapper_type.is_struct_type());
|
debug_assert!(wrapper_type.is_struct_type());
|
||||||
|
|
||||||
// cast the opaque pointer to a pointer of the correct shape
|
// cast the opaque pointer to a pointer of the correct shape
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use bumpalo::Bump;
|
|
||||||
use inkwell::context::Context;
|
use inkwell::context::Context;
|
||||||
use inkwell::types::BasicTypeEnum::{self, *};
|
use inkwell::types::BasicTypeEnum::{self, *};
|
||||||
use inkwell::types::{ArrayType, BasicType, FunctionType, IntType, PointerType, StructType};
|
use inkwell::types::{ArrayType, BasicType, FunctionType, IntType, PointerType, StructType};
|
||||||
|
@ -61,21 +60,17 @@ pub fn as_const_zero<'ctx>(bt_enum: &BasicTypeEnum<'ctx>) -> BasicValueEnum<'ctx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn basic_type_from_function_layout<'ctx>(
|
fn basic_type_from_function_layout<'a, 'ctx, 'env>(
|
||||||
arena: &Bump,
|
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
||||||
context: &'ctx Context,
|
|
||||||
args: &[Layout<'_>],
|
args: &[Layout<'_>],
|
||||||
closure_type: Option<BasicTypeEnum<'ctx>>,
|
closure_type: Option<BasicTypeEnum<'ctx>>,
|
||||||
ret_layout: &Layout<'_>,
|
ret_layout: &Layout<'_>,
|
||||||
ptr_bytes: u32,
|
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
let ret_type = basic_type_from_layout(arena, context, &ret_layout, ptr_bytes);
|
let ret_type = basic_type_from_layout(env, &ret_layout);
|
||||||
let mut arg_basic_types = Vec::with_capacity_in(args.len(), arena);
|
let mut arg_basic_types = Vec::with_capacity_in(args.len(), env.arena);
|
||||||
|
|
||||||
for arg_layout in args.iter() {
|
for arg_layout in args.iter() {
|
||||||
arg_basic_types.push(basic_type_from_layout(
|
arg_basic_types.push(basic_type_from_layout(env, arg_layout));
|
||||||
arena, context, arg_layout, ptr_bytes,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(closure) = closure_type {
|
if let Some(closure) = closure_type {
|
||||||
|
@ -88,63 +83,47 @@ fn basic_type_from_function_layout<'ctx>(
|
||||||
ptr_type.as_basic_type_enum()
|
ptr_type.as_basic_type_enum()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn basic_type_from_record<'ctx>(
|
fn basic_type_from_record<'a, 'ctx, 'env>(
|
||||||
arena: &Bump,
|
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
||||||
context: &'ctx Context,
|
|
||||||
fields: &[Layout<'_>],
|
fields: &[Layout<'_>],
|
||||||
ptr_bytes: u32,
|
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
let mut field_types = Vec::with_capacity_in(fields.len(), arena);
|
let mut field_types = Vec::with_capacity_in(fields.len(), env.arena);
|
||||||
|
|
||||||
for field_layout in fields.iter() {
|
for field_layout in fields.iter() {
|
||||||
field_types.push(basic_type_from_layout(
|
field_types.push(basic_type_from_layout(env, field_layout));
|
||||||
arena,
|
|
||||||
context,
|
|
||||||
field_layout,
|
|
||||||
ptr_bytes,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context
|
env.context
|
||||||
.struct_type(field_types.into_bump_slice(), false)
|
.struct_type(field_types.into_bump_slice(), false)
|
||||||
.as_basic_type_enum()
|
.as_basic_type_enum()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn basic_type_from_layout<'ctx>(
|
pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
||||||
arena: &Bump,
|
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
||||||
context: &'ctx Context,
|
|
||||||
layout: &Layout<'_>,
|
layout: &Layout<'_>,
|
||||||
ptr_bytes: u32,
|
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
use Layout::*;
|
use Layout::*;
|
||||||
|
|
||||||
match layout {
|
match layout {
|
||||||
FunctionPointer(args, ret_layout) => {
|
FunctionPointer(args, ret_layout) => {
|
||||||
basic_type_from_function_layout(arena, context, args, None, ret_layout, ptr_bytes)
|
basic_type_from_function_layout(env, args, None, ret_layout)
|
||||||
}
|
}
|
||||||
Closure(args, closure_layout, ret_layout) => {
|
Closure(args, closure_layout, ret_layout) => {
|
||||||
let closure_data_layout = closure_layout.as_block_of_memory_layout();
|
let closure_data_layout = closure_layout.as_block_of_memory_layout();
|
||||||
let closure_data =
|
let closure_data = basic_type_from_layout(env, &closure_data_layout);
|
||||||
basic_type_from_layout(arena, context, &closure_data_layout, ptr_bytes);
|
|
||||||
|
|
||||||
let function_pointer = basic_type_from_function_layout(
|
let function_pointer =
|
||||||
arena,
|
basic_type_from_function_layout(env, args, Some(closure_data), ret_layout);
|
||||||
context,
|
|
||||||
args,
|
|
||||||
Some(closure_data),
|
|
||||||
ret_layout,
|
|
||||||
ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
context
|
env.context
|
||||||
.struct_type(&[function_pointer, closure_data], false)
|
.struct_type(&[function_pointer, closure_data], false)
|
||||||
.as_basic_type_enum()
|
.as_basic_type_enum()
|
||||||
}
|
}
|
||||||
Pointer(layout) => basic_type_from_layout(arena, context, &layout, ptr_bytes)
|
Pointer(layout) => basic_type_from_layout(env, &layout)
|
||||||
.ptr_type(AddressSpace::Generic)
|
.ptr_type(AddressSpace::Generic)
|
||||||
.into(),
|
.into(),
|
||||||
PhantomEmptyStruct => context.struct_type(&[], false).into(),
|
PhantomEmptyStruct => env.context.struct_type(&[], false).into(),
|
||||||
Struct(sorted_fields) => basic_type_from_record(arena, context, sorted_fields, ptr_bytes),
|
Struct(sorted_fields) => basic_type_from_record(env, sorted_fields),
|
||||||
Union(variant) => {
|
Union(variant) => {
|
||||||
use UnionLayout::*;
|
use UnionLayout::*;
|
||||||
match variant {
|
match variant {
|
||||||
|
@ -152,40 +131,44 @@ pub fn basic_type_from_layout<'ctx>(
|
||||||
| NullableWrapped {
|
| NullableWrapped {
|
||||||
other_tags: tags, ..
|
other_tags: tags, ..
|
||||||
} => {
|
} => {
|
||||||
let block = block_of_memory_slices(context, tags, ptr_bytes);
|
let block = block_of_memory_slices(env.context, tags, env.ptr_bytes);
|
||||||
block.ptr_type(AddressSpace::Generic).into()
|
block.ptr_type(AddressSpace::Generic).into()
|
||||||
}
|
}
|
||||||
NullableUnwrapped { other_fields, .. } => {
|
NullableUnwrapped { other_fields, .. } => {
|
||||||
let block = block_of_memory_slices(context, &[&other_fields[1..]], ptr_bytes);
|
let block =
|
||||||
|
block_of_memory_slices(env.context, &[&other_fields[1..]], env.ptr_bytes);
|
||||||
block.ptr_type(AddressSpace::Generic).into()
|
block.ptr_type(AddressSpace::Generic).into()
|
||||||
}
|
}
|
||||||
NonNullableUnwrapped(fields) => {
|
NonNullableUnwrapped(fields) => {
|
||||||
let block = block_of_memory_slices(context, &[fields], ptr_bytes);
|
let block = block_of_memory_slices(env.context, &[fields], env.ptr_bytes);
|
||||||
block.ptr_type(AddressSpace::Generic).into()
|
block.ptr_type(AddressSpace::Generic).into()
|
||||||
}
|
}
|
||||||
NonRecursive(_) => block_of_memory(context, layout, ptr_bytes),
|
NonRecursive(_) => block_of_memory(env.context, layout, env.ptr_bytes),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecursivePointer => {
|
RecursivePointer => {
|
||||||
// TODO make this dynamic
|
// TODO make this dynamic
|
||||||
context
|
env.context
|
||||||
.i64_type()
|
.i64_type()
|
||||||
.ptr_type(AddressSpace::Generic)
|
.ptr_type(AddressSpace::Generic)
|
||||||
.as_basic_type_enum()
|
.as_basic_type_enum()
|
||||||
}
|
}
|
||||||
|
|
||||||
Builtin(builtin) => basic_type_from_builtin(arena, context, builtin, ptr_bytes),
|
Builtin(builtin) => basic_type_from_builtin(env, builtin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn basic_type_from_builtin<'ctx>(
|
pub fn basic_type_from_builtin<'a, 'ctx, 'env>(
|
||||||
_arena: &Bump,
|
env: &crate::llvm::build::Env<'a, 'ctx, 'env>,
|
||||||
context: &'ctx Context,
|
|
||||||
builtin: &Builtin<'_>,
|
builtin: &Builtin<'_>,
|
||||||
ptr_bytes: u32,
|
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
use Builtin::*;
|
use Builtin::*;
|
||||||
|
|
||||||
|
let zig_dict_type = env.module.get_struct_type("dict.RocDict").unwrap();
|
||||||
|
|
||||||
|
let context = env.context;
|
||||||
|
let ptr_bytes = env.ptr_bytes;
|
||||||
|
|
||||||
match builtin {
|
match builtin {
|
||||||
Int128 => context.i128_type().as_basic_type_enum(),
|
Int128 => context.i128_type().as_basic_type_enum(),
|
||||||
Int64 => context.i64_type().as_basic_type_enum(),
|
Int64 => context.i64_type().as_basic_type_enum(),
|
||||||
|
@ -198,8 +181,8 @@ pub fn basic_type_from_builtin<'ctx>(
|
||||||
Float64 => context.f64_type().as_basic_type_enum(),
|
Float64 => context.f64_type().as_basic_type_enum(),
|
||||||
Float32 => context.f32_type().as_basic_type_enum(),
|
Float32 => context.f32_type().as_basic_type_enum(),
|
||||||
Float16 => context.f16_type().as_basic_type_enum(),
|
Float16 => context.f16_type().as_basic_type_enum(),
|
||||||
Dict(_, _) | EmptyDict => dict(context, ptr_bytes).into(),
|
Dict(_, _) | EmptyDict => zig_dict_type.into(),
|
||||||
Set(_) | EmptySet => panic!("TODO layout_to_basic_type for Builtin::Set"),
|
Set(_) | EmptySet => zig_dict_type.into(),
|
||||||
List(_, _) | Str | EmptyStr => collection(context, ptr_bytes).into(),
|
List(_, _) | Str | EmptyStr => collection(context, ptr_bytes).into(),
|
||||||
EmptyList => BasicTypeEnum::StructType(collection(context, ptr_bytes)),
|
EmptyList => BasicTypeEnum::StructType(collection(context, ptr_bytes)),
|
||||||
}
|
}
|
||||||
|
@ -273,20 +256,6 @@ pub fn collection(ctx: &Context, ptr_bytes: u32) -> StructType<'_> {
|
||||||
ctx.struct_type(&[u8_ptr.into(), usize_type.into()], false)
|
ctx.struct_type(&[u8_ptr.into(), usize_type.into()], false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dict(ctx: &Context, ptr_bytes: u32) -> StructType<'_> {
|
|
||||||
let usize_type = ptr_int(ctx, ptr_bytes);
|
|
||||||
let u8_ptr = ctx.i8_type().ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
ctx.struct_type(
|
|
||||||
&[u8_ptr.into(), usize_type.into(), usize_type.into()],
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dict_ptr(ctx: &Context, ptr_bytes: u32) -> PointerType<'_> {
|
|
||||||
dict(ctx, ptr_bytes).ptr_type(AddressSpace::Generic)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ptr_int(ctx: &Context, ptr_bytes: u32) -> IntType<'_> {
|
pub fn ptr_int(ctx: &Context, ptr_bytes: u32) -> IntType<'_> {
|
||||||
match ptr_bytes {
|
match ptr_bytes {
|
||||||
1 => ctx.i8_type(),
|
1 => ctx.i8_type(),
|
||||||
|
|
|
@ -586,7 +586,7 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
||||||
WhenRecursive::Loop(union_layout) => {
|
WhenRecursive::Loop(union_layout) => {
|
||||||
let layout = Layout::Union(*union_layout);
|
let layout = Layout::Union(*union_layout);
|
||||||
|
|
||||||
let bt = basic_type_from_layout(env.arena, env.context, &layout, env.ptr_bytes);
|
let bt = basic_type_from_layout(env, &layout);
|
||||||
|
|
||||||
// cast the i64 pointer to a pointer to block of memory
|
// cast the i64 pointer to a pointer to block of memory
|
||||||
let field_cast = env
|
let field_cast = env
|
||||||
|
@ -634,7 +634,7 @@ fn modify_refcount_list<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let basic_type = basic_type_from_layout(env.arena, env.context, &layout, env.ptr_bytes);
|
let basic_type = basic_type_from_layout(env, &layout);
|
||||||
let function_value = build_header(env, basic_type, mode, &fn_name);
|
let function_value = build_header(env, basic_type, mode, &fn_name);
|
||||||
|
|
||||||
modify_refcount_list_help(
|
modify_refcount_list_help(
|
||||||
|
@ -711,9 +711,7 @@ fn modify_refcount_list_help<'a, 'ctx, 'env>(
|
||||||
builder.position_at_end(modification_block);
|
builder.position_at_end(modification_block);
|
||||||
|
|
||||||
if element_layout.contains_refcounted() {
|
if element_layout.contains_refcounted() {
|
||||||
let ptr_type =
|
let ptr_type = basic_type_from_layout(env, element_layout).ptr_type(AddressSpace::Generic);
|
||||||
basic_type_from_layout(env.arena, env.context, element_layout, env.ptr_bytes)
|
|
||||||
.ptr_type(AddressSpace::Generic);
|
|
||||||
|
|
||||||
let (len, ptr) = load_list(env.builder, original_wrapper, ptr_type);
|
let (len, ptr) = load_list(env.builder, original_wrapper, ptr_type);
|
||||||
|
|
||||||
|
@ -774,7 +772,7 @@ fn modify_refcount_str<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let basic_type = basic_type_from_layout(env.arena, env.context, &layout, env.ptr_bytes);
|
let basic_type = basic_type_from_layout(env, &layout);
|
||||||
let function_value = build_header(env, basic_type, mode, &fn_name);
|
let function_value = build_header(env, basic_type, mode, &fn_name);
|
||||||
|
|
||||||
modify_refcount_str_help(env, mode, layout, function_value);
|
modify_refcount_str_help(env, mode, layout, function_value);
|
||||||
|
@ -874,7 +872,7 @@ fn modify_refcount_dict<'a, 'ctx, 'env>(
|
||||||
let function = match env.module.get_function(fn_name.as_str()) {
|
let function = match env.module.get_function(fn_name.as_str()) {
|
||||||
Some(function_value) => function_value,
|
Some(function_value) => function_value,
|
||||||
None => {
|
None => {
|
||||||
let basic_type = basic_type_from_layout(env.arena, env.context, &layout, env.ptr_bytes);
|
let basic_type = basic_type_from_layout(env, &layout);
|
||||||
let function_value = build_header(env, basic_type, mode, &fn_name);
|
let function_value = build_header(env, basic_type, mode, &fn_name);
|
||||||
|
|
||||||
modify_refcount_dict_help(
|
modify_refcount_dict_help(
|
||||||
|
@ -1192,12 +1190,7 @@ fn build_rec_union_help<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
env.builder.position_at_end(block);
|
env.builder.position_at_end(block);
|
||||||
|
|
||||||
let wrapper_type = basic_type_from_layout(
|
let wrapper_type = basic_type_from_layout(env, &Layout::Struct(field_layouts));
|
||||||
env.arena,
|
|
||||||
env.context,
|
|
||||||
&Layout::Struct(field_layouts),
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
// cast the opaque pointer to a pointer of the correct shape
|
// cast the opaque pointer to a pointer of the correct shape
|
||||||
let struct_ptr = env
|
let struct_ptr = env
|
||||||
|
@ -1498,12 +1491,7 @@ fn modify_refcount_union_help<'a, 'ctx, 'env>(
|
||||||
let block = env.context.append_basic_block(parent, "tag_id_modify");
|
let block = env.context.append_basic_block(parent, "tag_id_modify");
|
||||||
env.builder.position_at_end(block);
|
env.builder.position_at_end(block);
|
||||||
|
|
||||||
let wrapper_type = basic_type_from_layout(
|
let wrapper_type = basic_type_from_layout(env, &Layout::Struct(field_layouts));
|
||||||
env.arena,
|
|
||||||
env.context,
|
|
||||||
&Layout::Struct(field_layouts),
|
|
||||||
env.ptr_bytes,
|
|
||||||
);
|
|
||||||
|
|
||||||
debug_assert!(wrapper_type.is_struct_type());
|
debug_assert!(wrapper_type.is_struct_type());
|
||||||
let wrapper_struct = cast_block_of_memory_to_tag(env.builder, wrapper_struct, wrapper_type);
|
let wrapper_struct = cast_block_of_memory_to_tag(env.builder, wrapper_struct, wrapper_type);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue