mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge branch 'main' of github.com:roc-lang/roc into glue-getters-rtfeldman
This commit is contained in:
commit
f1b1aa6a7b
72 changed files with 2496 additions and 1853 deletions
|
@ -183,6 +183,26 @@ pub(crate) fn list_reserve<'a, 'ctx, 'env>(
|
|||
)
|
||||
}
|
||||
|
||||
/// List.releaseExcessCapacity : List elem -> List elem
|
||||
pub(crate) fn list_release_excess_capacity<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
list: BasicValueEnum<'ctx>,
|
||||
element_layout: InLayout<'a>,
|
||||
update_mode: UpdateMode,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
call_list_bitcode_fn_1(
|
||||
env,
|
||||
list.into_struct_value(),
|
||||
&[
|
||||
env.alignment_intvalue(layout_interner, element_layout),
|
||||
layout_width(env, layout_interner, element_layout),
|
||||
pass_update_mode(env, update_mode),
|
||||
],
|
||||
bitcode::LIST_RELEASE_EXCESS_CAPACITY,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.appendUnsafe : List elem, elem -> List elem
|
||||
pub(crate) fn list_append_unsafe<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
|
|
|
@ -63,3 +63,19 @@ pub(crate) fn str_equal<'a, 'ctx, 'env>(
|
|||
bitcode::STR_EQUAL,
|
||||
)
|
||||
}
|
||||
|
||||
// Gets a pointer to just after the refcount for a list or seamless slice.
|
||||
// The value is just after the refcount so that normal lists and seamless slices can share code paths easily.
|
||||
pub(crate) fn str_refcount_ptr<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
value: BasicValueEnum<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
call_str_bitcode_fn(
|
||||
env,
|
||||
&[value],
|
||||
&[],
|
||||
BitcodeReturns::Basic,
|
||||
bitcode::STR_REFCOUNT_PTR,
|
||||
)
|
||||
.into_pointer_value()
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ use crate::llvm::{
|
|||
},
|
||||
build_list::{
|
||||
list_append_unsafe, list_concat, list_drop_at, list_get_unsafe, list_len, list_map,
|
||||
list_map2, list_map3, list_map4, list_prepend, list_replace_unsafe, list_reserve,
|
||||
list_sort_with, list_sublist, list_swap, list_symbol_to_c_abi, list_with_capacity,
|
||||
pass_update_mode,
|
||||
list_map2, list_map3, list_map4, list_prepend, list_release_excess_capacity,
|
||||
list_replace_unsafe, list_reserve, list_sort_with, list_sublist, list_swap,
|
||||
list_symbol_to_c_abi, list_with_capacity, pass_update_mode,
|
||||
},
|
||||
compare::{generic_eq, generic_neq},
|
||||
convert::{
|
||||
|
@ -559,6 +559,18 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
bitcode::STR_RESERVE,
|
||||
)
|
||||
}
|
||||
StrReleaseExcessCapacity => {
|
||||
// Str.releaseExcessCapacity: Str -> Str
|
||||
arguments!(string);
|
||||
|
||||
call_str_bitcode_fn(
|
||||
env,
|
||||
&[string],
|
||||
&[],
|
||||
BitcodeReturns::Str,
|
||||
bitcode::STR_RELEASE_EXCESS_CAPACITY,
|
||||
)
|
||||
}
|
||||
StrAppendScalar => {
|
||||
// Str.appendScalar : Str, U32 -> Str
|
||||
arguments!(string, capacity);
|
||||
|
@ -707,6 +719,15 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
|||
update_mode,
|
||||
)
|
||||
}
|
||||
ListReleaseExcessCapacity => {
|
||||
// List.releaseExcessCapacity: List elem -> List elem
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let element_layout = list_element_layout!(layout_interner, list_layout);
|
||||
|
||||
list_release_excess_capacity(env, layout_interner, list, element_layout, update_mode)
|
||||
}
|
||||
ListSwap => {
|
||||
// List.swap : List elem, Nat, Nat -> List elem
|
||||
debug_assert_eq!(args.len(), 3);
|
||||
|
|
|
@ -8,12 +8,13 @@ use crate::llvm::build::{
|
|||
use crate::llvm::build_list::{
|
||||
incrementing_elem_loop, list_capacity_or_ref_ptr, list_refcount_ptr, load_list,
|
||||
};
|
||||
use crate::llvm::build_str::str_refcount_ptr;
|
||||
use crate::llvm::convert::{basic_type_from_layout, zig_str_type, RocUnion};
|
||||
use bumpalo::collections::Vec;
|
||||
use inkwell::basic_block::BasicBlock;
|
||||
use inkwell::module::Linkage;
|
||||
use inkwell::types::{AnyTypeEnum, BasicMetadataTypeEnum, BasicType, BasicTypeEnum};
|
||||
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue};
|
||||
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue};
|
||||
use inkwell::{AddressSpace, IntPredicate};
|
||||
use roc_module::symbol::Interns;
|
||||
use roc_module::symbol::Symbol;
|
||||
|
@ -75,16 +76,6 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn from_list_wrapper(env: &Env<'_, 'ctx, '_>, list_wrapper: StructValue<'ctx>) -> Self {
|
||||
let data_ptr = env
|
||||
.builder
|
||||
.build_extract_value(list_wrapper, Builtin::WRAPPER_PTR, "read_list_ptr")
|
||||
.unwrap()
|
||||
.into_pointer_value();
|
||||
|
||||
Self::from_ptr_to_data(env, data_ptr)
|
||||
}
|
||||
|
||||
pub fn is_1<'a, 'env>(&self, env: &Env<'a, 'ctx, 'env>) -> IntValue<'ctx> {
|
||||
let current = self.get_refcount(env);
|
||||
let one = match env.target_info.ptr_width() {
|
||||
|
@ -815,9 +806,9 @@ fn modify_refcount_str_help<'a, 'ctx, 'env>(
|
|||
|
||||
let parent = fn_val;
|
||||
|
||||
let arg_val =
|
||||
let str_type = zig_str_type(env);
|
||||
let str_wrapper =
|
||||
if Layout::Builtin(Builtin::Str).is_passed_by_reference(layout_interner, env.target_info) {
|
||||
let str_type = zig_str_type(env);
|
||||
env.builder
|
||||
.new_build_load(str_type, arg_val.into_pointer_value(), "load_str_to_stack")
|
||||
} else {
|
||||
|
@ -825,7 +816,7 @@ fn modify_refcount_str_help<'a, 'ctx, 'env>(
|
|||
debug_assert!(arg_val.is_struct_value());
|
||||
arg_val
|
||||
};
|
||||
let str_wrapper = arg_val.into_struct_value();
|
||||
let str_wrapper = str_wrapper.into_struct_value();
|
||||
|
||||
let capacity = builder
|
||||
.build_extract_value(str_wrapper, Builtin::WRAPPER_CAPACITY, "read_str_capacity")
|
||||
|
@ -848,7 +839,7 @@ fn modify_refcount_str_help<'a, 'ctx, 'env>(
|
|||
builder.build_conditional_branch(is_big_and_non_empty, modification_block, cont_block);
|
||||
builder.position_at_end(modification_block);
|
||||
|
||||
let refcount_ptr = PointerToRefcount::from_list_wrapper(env, str_wrapper);
|
||||
let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, str_refcount_ptr(env, arg_val));
|
||||
let call_mode = mode_to_call_mode(fn_val, mode);
|
||||
refcount_ptr.modify(call_mode, layout, env, layout_interner);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue