Str.startsWith, str.endsWith and friends

This commit is contained in:
Folkert 2023-02-10 20:18:20 +01:00
parent 8df8c19ae2
commit eb48f01f63
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C
8 changed files with 98 additions and 54 deletions

View File

@ -2436,7 +2436,7 @@ impl<
let base_offset = storage_manager.claim_stack_area(&dst, 24);
ASM::mov_reg64_mem64_offset32(buf, tmp_reg, ptr_reg, 0);
ASM::mov_base32_reg64(buf, base_offset + 0, tmp_reg);
ASM::mov_base32_reg64(buf, base_offset, tmp_reg);
ASM::mov_reg64_mem64_offset32(buf, tmp_reg, ptr_reg, 8);
ASM::mov_base32_reg64(buf, base_offset + 8, tmp_reg);

View File

@ -557,7 +557,6 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg, X86_64Assembler> for X86_64Syste
// This should have been recieved via an arg pointer.
// That means the value is already loaded onto the stack area we allocated before the call.
// Nothing to do.
dbg!(sym);
}
}
}

View File

@ -791,6 +791,34 @@ trait Backend<'a> {
arg_layouts,
ret_layout,
),
LowLevel::StrStartsWith => self.build_fn_call(
sym,
bitcode::STR_STARTS_WITH.to_string(),
args,
arg_layouts,
ret_layout,
),
LowLevel::StrStartsWithScalar => self.build_fn_call(
sym,
bitcode::STR_STARTS_WITH_SCALAR.to_string(),
args,
arg_layouts,
ret_layout,
),
LowLevel::StrEndsWith => self.build_fn_call(
sym,
bitcode::STR_ENDS_WITH.to_string(),
args,
arg_layouts,
ret_layout,
),
LowLevel::StrCountGraphemes => self.build_fn_call(
sym,
bitcode::STR_COUNT_GRAPEHEME_CLUSTERS.to_string(),
args,
arg_layouts,
ret_layout,
),
LowLevel::PtrCast => {
debug_assert_eq!(
1,

View File

@ -18,12 +18,16 @@ macro_rules! run_jit_function_raw {
let result = main();
assert_eq!(
$errors,
std::vec::Vec::new(),
"Encountered errors: {:?}",
$errors
);
if !$errors.is_empty() {
dbg!(&$errors);
assert_eq!(
$errors,
std::vec::Vec::new(),
"Encountered errors: {:?}",
$errors
);
}
$transform(result)
}

View File

@ -3296,12 +3296,13 @@ fn box_num() {
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))]
#[ignore = "triggers some UB somewhere in at least the llvm and dev backends"]
fn box_str() {
assert_evals_to!(
"Box.box \"short\"",
RocBox::new(RocStr::from("short")),
RocBox<RocStr>
)
);
}
#[test]

View File

@ -485,7 +485,7 @@ fn empty_str_is_empty() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_starts_with() {
assert_evals_to!(r#"Str.startsWith "hello world" "hell""#, true, bool);
assert_evals_to!(r#"Str.startsWith "hello world" """#, true, bool);
@ -495,7 +495,7 @@ fn str_starts_with() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_starts_with_scalar() {
assert_evals_to!(
&format!(r#"Str.startsWithScalar "foobar" {}"#, 'f' as u32),
@ -510,7 +510,7 @@ fn str_starts_with_scalar() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_ends_with() {
assert_evals_to!(r#"Str.endsWith "hello world" "world""#, true, bool);
assert_evals_to!(r#"Str.endsWith "nope" "hello world""#, false, bool);
@ -518,13 +518,13 @@ fn str_ends_with() {
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_count_graphemes_small_str() {
assert_evals_to!(r#"Str.countGraphemes "å🤔""#, 2, usize);
}
#[test]
#[cfg(any(feature = "gen-llvm"))]
#[cfg(any(feature = "gen-llvm", feature = "gen-dev"))]
fn str_count_graphemes_three_js() {
assert_evals_to!(r#"Str.countGraphemes "JJJ""#, 3, usize);
}

View File

@ -572,47 +572,59 @@ pub fn try_run_lib_function<T>(
}
}
// only used in tests
#[allow(unused)]
pub(crate) fn llvm_evals_to<T, U, F>(src: &str, expected: U, transform: F, ignore_problems: bool)
where
U: PartialEq + std::fmt::Debug,
F: FnOnce(T) -> U,
{
use bumpalo::Bump;
use inkwell::context::Context;
let arena = Bump::new();
let context = Context::create();
let config = crate::helpers::llvm::HelperConfig {
mode: LlvmBackendMode::GenTest,
add_debug_info: false,
ignore_problems,
opt_level: crate::helpers::llvm::OPT_LEVEL,
};
let (main_fn_name, errors, lib) = crate::helpers::llvm::helper(&arena, config, src, &context);
let result = crate::helpers::llvm::try_run_lib_function::<T>(main_fn_name, &lib);
match result {
Ok(raw) => {
// only if there are no exceptions thrown, check for errors
assert!(errors.is_empty(), "Encountered errors:\n{}", errors);
#[allow(clippy::redundant_closure_call)]
let given = transform(raw);
assert_eq!(&given, &expected, "LLVM test failed");
// on Windows, there are issues with the drop instances of some roc_std
#[cfg(windows)]
std::mem::forget(given);
}
Err((msg, tag)) => match tag {
CrashTag::Roc => panic!(r#"Roc failed with message: "{}""#, msg),
CrashTag::User => panic!(r#"User crash with message: "{}""#, msg),
},
}
}
#[allow(unused_macros)]
macro_rules! assert_llvm_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr, $ignore_problems:expr) => {
use bumpalo::Bump;
use inkwell::context::Context;
use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_mono::ir::CrashTag;
let arena = Bump::new();
let context = Context::create();
let config = $crate::helpers::llvm::HelperConfig {
mode: LlvmBackendMode::GenTest,
add_debug_info: false,
ignore_problems: $ignore_problems,
opt_level: $crate::helpers::llvm::OPT_LEVEL,
};
let (main_fn_name, errors, lib) =
$crate::helpers::llvm::helper(&arena, config, $src, &context);
let result = $crate::helpers::llvm::try_run_lib_function::<$ty>(main_fn_name, &lib);
match result {
Ok(raw) => {
// only if there are no exceptions thrown, check for errors
assert!(errors.is_empty(), "Encountered errors:\n{}", errors);
#[allow(clippy::redundant_closure_call)]
let given = $transform(raw);
assert_eq!(&given, &$expected, "LLVM test failed");
// on Windows, there are issues with the drop instances of some roc_std
#[cfg(windows)]
std::mem::forget(given);
}
Err((msg, tag)) => match tag {
CrashTag::Roc => panic!(r#"Roc failed with message: "{}""#, msg),
CrashTag::User => panic!(r#"User crash with message: "{}""#, msg),
},
}
crate::helpers::llvm::llvm_evals_to::<$ty, _, _>(
$src,
$expected,
$transform,
$ignore_problems,
);
};
($src:expr, $expected:expr, $ty:ty) => {

View File

@ -86,9 +86,9 @@ checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
[[package]]
name = "libc"
version = "0.2.119"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "log"