Implement Wasm string equality

This commit is contained in:
Brian Carroll 2021-12-14 10:45:47 +00:00
parent e1a04c2661
commit 86d8e2789e
3 changed files with 42 additions and 35 deletions

View File

@ -1,7 +1,7 @@
use bumpalo::{self, collections::Vec};
use code_builder::Align;
use roc_builtins::bitcode::IntWidth;
use roc_builtins::bitcode::{self, IntWidth};
use roc_collections::all::MutMap;
use roc_module::low_level::LowLevel;
use roc_module::symbol::{Interns, Symbol};
@ -958,29 +958,34 @@ impl<'a> WasmBackend<'a> {
BuiltinCall(name) => {
self.call_zig_builtin(name, param_types, ret_type);
}
GeneratedHelper => {
SpecializedEq | SpecializedNotEq => {
let layout = self.symbol_layouts[&arguments[0]];
let ident_ids = self
.interns
.all_ident_ids
.get_mut(&self.env.module_id)
.unwrap();
let (replacement_expr, maybe_new_proc_info) = self
.helper_proc_gen
.replace_generic_equals(ident_ids, &layout, arguments);
// If this is the first call to a new helper proc, register its symbol data
maybe_new_proc_info.map(|info| self.register_helper_proc(info));
self.build_expr(&return_sym, replacement_expr, &layout, storage);
if lowlevel == LowLevel::NotEq {
self.code_builder.i32_eqz();
if layout == Layout::Builtin(Builtin::Str) {
self.call_zig_builtin(bitcode::STR_EQUAL, param_types, ret_type);
} else {
debug_assert!(lowlevel == LowLevel::Eq);
let ident_ids = self
.interns
.all_ident_ids
.get_mut(&self.env.module_id)
.unwrap();
let (replacement_expr, maybe_new_proc_info) = self
.helper_proc_gen
.replace_generic_equals(ident_ids, &layout, arguments);
// If this is the first call to a new helper proc, register its symbol data
maybe_new_proc_info.map(|info| self.register_helper_proc(info));
self.build_expr(&return_sym, replacement_expr, &layout, storage);
}
if matches!(build_result, SpecializedNotEq) {
self.code_builder.i32_eqz();
}
}
SpecializedHash => {
todo!("Specialized hash functions")
}
NotImplemented => {
todo!("Low level operation {:?}", lowlevel)

View File

@ -10,7 +10,9 @@ use crate::wasm_module::{Align, CodeBuilder, ValueType::*};
pub enum LowlevelBuildResult {
Done,
BuiltinCall(&'static str),
GeneratedHelper,
SpecializedEq,
SpecializedNotEq,
SpecializedHash,
NotImplemented,
}
@ -564,7 +566,7 @@ pub fn decode_low_level<'a>(
}
Int128 => compare_bytes(code_builder),
Float128 => return NotImplemented,
DataStructure => return GeneratedHelper,
DataStructure => return SpecializedEq,
}
}
}
@ -580,7 +582,7 @@ pub fn decode_low_level<'a>(
},
StoredValue::StackMemory { format, .. } => {
if matches!(format, DataStructure) {
return GeneratedHelper;
return SpecializedNotEq;
} else {
decode_low_level(code_builder, storage, LowLevel::Eq, args, ret_layout);
code_builder.i32_eqz();
@ -590,7 +592,7 @@ pub fn decode_low_level<'a>(
And => code_builder.i32_and(),
Or => code_builder.i32_or(),
Not => code_builder.i32_eqz(),
Hash => return NotImplemented, // TODO: generated helpers
Hash => return SpecializedHash,
ExpectTrue => return NotImplemented,
RefCountGetPtr => {
code_builder.i32_const(4);

View File

@ -665,17 +665,17 @@ fn str_starts_with_false_small_str() {
// );
// }
// #[test]
// fn str_equality() {
// assert_evals_to!(r#""a" == "a""#, true, bool);
// assert_evals_to!(
// r#""loremipsumdolarsitamet" == "loremipsumdolarsitamet""#,
// true,
// bool
// );
// assert_evals_to!(r#""a" != "b""#, true, bool);
// assert_evals_to!(r#""a" == "b""#, false, bool);
// }
#[test]
fn str_equality() {
assert_evals_to!(r#""a" == "a""#, true, bool);
assert_evals_to!(
r#""loremipsumdolarsitamet" == "loremipsumdolarsitamet""#,
true,
bool
);
assert_evals_to!(r#""a" != "b""#, true, bool);
assert_evals_to!(r#""a" == "b""#, false, bool);
}
// #[test]
// fn nested_recursive_literal() {