misc cleanup

This commit is contained in:
Brendan Hansknecht 2023-03-15 11:40:32 -07:00
parent 8d5a182f83
commit b8e42b05a2
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
2 changed files with 10 additions and 17 deletions

View file

@ -59,7 +59,8 @@ pub const RocStr = extern struct {
} }
// This requires that the list is non-null. // This requires that the list is non-null.
pub fn fromSubList(list: RocList, start: usize, count: usize, update_mode: UpdateMode) RocStr { // It also requires that start and count define a slice that does not go outside the bounds of the list.
pub fn fromSubListUnsafe(list: RocList, start: usize, count: usize, update_mode: UpdateMode) RocStr {
const start_byte = @ptrCast([*]u8, list.bytes) + start; const start_byte = @ptrCast([*]u8, list.bytes) + start;
if (list.isSeamlessSlice()) { if (list.isSeamlessSlice()) {
return RocStr{ return RocStr{
@ -173,20 +174,10 @@ pub const RocStr = extern struct {
// Now we have to look at the string contents // Now we have to look at the string contents
const self_bytes = self.asU8ptr(); const self_bytes = self.asU8ptr();
const other_bytes = other.asU8ptr(); const other_bytes = other.asU8ptr();
// TODO: we can make an optimization like memcmp does in glibc.
// It's faster to compare pointer-sized words rather than bytes, as far as possible // We can check the min shared alignment 1, 2, 4, or 8.
// The bytes are always pointer-size aligned due to the refcount // Then do a copy at that alignment before falling back on one byte at a time.
// const self_words = @ptrCast([*]const usize, @alignCast(@alignOf(usize), self_bytes)); // Currently we have to be unaligned because slices can be at any alignment.
// const other_words = @ptrCast([*]const usize, @alignCast(@alignOf(usize), other_bytes));
// var w: usize = 0;
// while (w < self_len / @sizeOf(usize)) : (w += 1) {
// if (self_words[w] != other_words[w]) {
// return false;
// }
// }
// Compare the leftover bytes
// var b = w * @sizeOf(usize);
var b: usize = 0; var b: usize = 0;
while (b < self_len) : (b += 1) { while (b < self_len) : (b += 1) {
if (self_bytes[b] != other_bytes[b]) { if (self_bytes[b] != other_bytes[b]) {
@ -864,7 +855,6 @@ pub fn strSplit(string: RocStr, delimiter: RocStr) callconv(.C) RocList {
return list; return list;
} }
const Init = fn (slice_bytes: [*]u8, len: usize, ref_ptr: usize) RocStr;
fn initFromSmallStr(slice_bytes: [*]u8, len: usize, _: usize) RocStr { fn initFromSmallStr(slice_bytes: [*]u8, len: usize, _: usize) RocStr {
return RocStr.init(slice_bytes, len); return RocStr.init(slice_bytes, len);
} }
@ -1919,7 +1909,7 @@ pub fn fromUtf8Range(arg: RocList, start: usize, count: usize, update_mode: Upda
if (isValidUnicode(bytes)) { if (isValidUnicode(bytes)) {
// Make a seamless slice of the input. // Make a seamless slice of the input.
const string = RocStr.fromSubList(arg, start, count, update_mode); const string = RocStr.fromSubListUnsafe(arg, start, count, update_mode);
return FromUtf8Result{ return FromUtf8Result{
.is_ok = true, .is_ok = true,
.string = string, .string = string,

View file

@ -60,6 +60,9 @@ impl FromWasm32Memory for RocStr {
let str_words: &[u32; 3] = unsafe { std::mem::transmute(&str_bytes) }; let str_words: &[u32; 3] = unsafe { std::mem::transmute(&str_bytes) };
let big_elem_ptr = str_words[Builtin::WRAPPER_PTR as usize] as usize; let big_elem_ptr = str_words[Builtin::WRAPPER_PTR as usize] as usize;
// If the str is a seamless slice, it's highest bit will be set to 1.
// We need to remove that bit or we will get an incorrect negative length.
// Since wasm length is 32bits, and with i32::MAX (0 followed by all 1s in 32 bit).
let big_length = str_words[Builtin::WRAPPER_LEN as usize] as usize & (i32::MAX as usize); let big_length = str_words[Builtin::WRAPPER_LEN as usize] as usize & (i32::MAX as usize);
let big_capacity = str_words[Builtin::WRAPPER_CAPACITY as usize] as usize; let big_capacity = str_words[Builtin::WRAPPER_CAPACITY as usize] as usize;