diff --git a/crates/compiler/builtins/bitcode/src/main.zig b/crates/compiler/builtins/bitcode/src/main.zig index a258feb266..9070a36be3 100644 --- a/crates/compiler/builtins/bitcode/src/main.zig +++ b/crates/compiler/builtins/bitcode/src/main.zig @@ -192,17 +192,17 @@ comptime { exportStrFn(str.strJoinWithC, "joinWith"); exportStrFn(str.strNumberOfBytes, "number_of_bytes"); exportStrFn(str.strEqual, "equal"); - exportStrFn(str.substringUnsafe, "substring_unsafe"); - exportStrFn(str.getUnsafe, "get_unsafe"); - exportStrFn(str.reserve, "reserve"); + exportStrFn(str.substringUnsafeC, "substring_unsafe"); + exportStrFn(str.getUnsafeC, "get_unsafe"); + exportStrFn(str.reserveC, "reserve"); exportStrFn(str.strToUtf8C, "to_utf8"); exportStrFn(str.fromUtf8RangeC, "from_utf8_range"); - exportStrFn(str.repeat, "repeat"); + exportStrFn(str.repeatC, "repeat"); exportStrFn(str.strTrim, "trim"); exportStrFn(str.strTrimStart, "trim_start"); exportStrFn(str.strTrimEnd, "trim_end"); exportStrFn(str.strCloneTo, "clone_to"); - exportStrFn(str.withCapacity, "with_capacity"); + exportStrFn(str.withCapacityC, "with_capacity"); exportStrFn(str.strAllocationPtr, "allocation_ptr"); exportStrFn(str.strReleaseExcessCapacity, "release_excess_capacity"); diff --git a/crates/compiler/builtins/bitcode/src/str.zig b/crates/compiler/builtins/bitcode/src/str.zig index ca46dce32b..31c5d0b48d 100644 --- a/crates/compiler/builtins/bitcode/src/str.zig +++ b/crates/compiler/builtins/bitcode/src/str.zig @@ -1146,10 +1146,14 @@ pub fn getCapacity(string: RocStr) callconv(.C) usize { return string.getCapacity(); } -pub fn substringUnsafe(string: RocStr, start_u64: u64, length_u64: u64) callconv(.C) RocStr { +pub fn substringUnsafeC(string: RocStr, start_u64: u64, length_u64: u64) callconv(.C) RocStr { const start: usize = @intCast(start_u64); const length: usize = @intCast(length_u64); + return substringUnsafe(string, start, length); +} + +fn substringUnsafe(string: RocStr, start: usize, length: usize) RocStr { if (string.isSmallStr()) { if (start == 0) { var output = string; @@ -1181,7 +1185,7 @@ pub fn substringUnsafe(string: RocStr, start_u64: u64, length_u64: u64) callconv return RocStr.empty(); } -pub fn getUnsafe(string: RocStr, index: u64) callconv(.C) u8 { +pub fn getUnsafeC(string: RocStr, index: u64) callconv(.C) u8 { return string.getUnchecked(@intCast(index)); } @@ -1245,7 +1249,7 @@ pub fn startsWith(string: RocStr, prefix: RocStr) callconv(.C) bool { } // Str.repeat -pub fn repeat(string: RocStr, count_u64: u64) callconv(.C) RocStr { +pub fn repeatC(string: RocStr, count_u64: u64) callconv(.C) RocStr { const count: usize = @intCast(count_u64); const bytes_len = string.len(); const bytes_ptr = string.asU8ptr(); @@ -1514,17 +1518,24 @@ const CountAndStart = extern struct { pub fn fromUtf8RangeC( list: RocList, - start: u64, - count: u64, + start_u64: u64, + count_u64: u64, update_mode: UpdateMode, ) callconv(.C) FromUtf8Result { - return fromUtf8Range(list, start, count, update_mode); + return fromUtf8Range(list, @intCast(start_u64), @intCast(count_u64), update_mode); } -pub fn fromUtf8Range(arg: RocList, start_u64: u64, count_u64: u64, update_mode: UpdateMode) FromUtf8Result { - const start: usize = @intCast(start_u64); - const count: usize = @intCast(count_u64); +test "fromUtf8RangeC(\"hello\", 1, 3)" { + const original_bytes = "hello"; + const list = RocList.fromSlice(u8, original_bytes[0..]); + const result = fromUtf8RangeC(list, 1, 3, UpdateMode.Immutable); + try expectEqual(result.is_ok, true); + + result.string.decref(); +} + +pub fn fromUtf8Range(arg: RocList, start: usize, count: usize, update_mode: UpdateMode) FromUtf8Result { if (arg.len() == 0 or count == 0) { arg.decref(RocStr.alignment); return FromUtf8Result{ @@ -2374,9 +2385,12 @@ test "capacity: big string" { try expect(data.getCapacity() >= data_bytes.len); } -pub fn reserve(string: RocStr, spare_u64: u64) callconv(.C) RocStr { +pub fn reserveC(string: RocStr, spare_u64: u64) callconv(.C) RocStr { + return reserve(string, @intCast(spare_u64)); +} + +fn reserve(string: RocStr, spare: usize) RocStr { const old_length = string.len(); - const spare: usize = @intCast(spare_u64); if (string.getCapacity() >= old_length + spare) { return string; @@ -2387,11 +2401,12 @@ pub fn reserve(string: RocStr, spare_u64: u64) callconv(.C) RocStr { } } -pub fn withCapacity(capacity: u64) callconv(.C) RocStr { +pub fn withCapacityC(capacity: u64) callconv(.C) RocStr { var str = RocStr.allocate(@intCast(capacity)); str.setLen(0); return str; } + pub fn strCloneTo( string: RocStr, ptr: [*]u8, diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 3180caca46..43f746894f 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -232,8 +232,8 @@ impl<'a> LowLevelCall<'a> { output: *FromUtf8Result i32 arg: RocList i32 - start i32 - count i32 + start i64 + count i64 update_mode: UpdateMode i32 */ diff --git a/crates/compiler/test_gen/src/gen_str.rs b/crates/compiler/test_gen/src/gen_str.rs index 66f863ad25..80245fe4b9 100644 --- a/crates/compiler/test_gen/src/gen_str.rs +++ b/crates/compiler/test_gen/src/gen_str.rs @@ -965,7 +965,7 @@ fn str_from_utf8_range_order_does_not_matter() { bytes = Str.toUtf8 "hello" when Str.fromUtf8Range bytes { start: 1, count: 3 } is Ok utf8String -> utf8String - _ -> "" + Err _ -> "Str.fromUtf8Range returned Err instead of Ok!" "# ), RocStr::from("ell"),