mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 16:51:53 +03:00
Passing without bounds checks
This commit is contained in:
parent
4231b340ee
commit
b8b20a376a
@ -1198,30 +1198,17 @@ fn fromUtf8(arg: RocList) FromUtf8Result {
|
||||
}
|
||||
|
||||
pub fn fromUtf8RangeC(arg: RocList, countAndStart: CountAndStart, output: *FromUtf8Result) callconv(.C) void {
|
||||
output.* = @call(.{ .modifier = always_inline }, fromUtf8Range, .{arg, countAndStart});
|
||||
output.* = @call(.{ .modifier = always_inline }, fromUtf8Range, .{ arg, countAndStart });
|
||||
}
|
||||
|
||||
fn fromUtf8Range(arg: RocList, countAndStart: CountAndStart) FromUtf8Result {
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes)[0..arg.length];
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes)[countAndStart.start..countAndStart.count];
|
||||
|
||||
if (unicode.utf8ValidateSlice(bytes)) {
|
||||
// the output will be correct. Now we need to take ownership of the input
|
||||
if (arg.len() <= SMALL_STR_MAX_LENGTH) {
|
||||
// turn the bytes into a small string
|
||||
const string = RocStr.init(@ptrCast([*]u8, arg.bytes), arg.len());
|
||||
// the output will be correct. Now we need to clone the input
|
||||
const string = RocStr.init(@ptrCast([*]const u8, bytes), countAndStart.count);
|
||||
|
||||
// then decrement the input list
|
||||
const data_bytes = arg.len();
|
||||
utils.decref(arg.bytes, data_bytes, RocStr.alignment);
|
||||
|
||||
return FromUtf8Result{ .is_ok = true, .string = string, .byte_index = 0, .problem_code = Utf8ByteProblem.InvalidStartByte };
|
||||
} else {
|
||||
const byte_list = arg.makeUnique(RocStr.alignment, @sizeOf(u8));
|
||||
|
||||
const string = RocStr{ .str_bytes = byte_list.bytes, .str_len = byte_list.length };
|
||||
|
||||
return FromUtf8Result{ .is_ok = true, .string = string, .byte_index = 0, .problem_code = Utf8ByteProblem.InvalidStartByte };
|
||||
}
|
||||
return FromUtf8Result{ .is_ok = true, .string = string, .byte_index = 0, .problem_code = Utf8ByteProblem.InvalidStartByte };
|
||||
} else {
|
||||
const temp = errorToProblem(@ptrCast([*]u8, arg.bytes), arg.length);
|
||||
|
||||
@ -1233,7 +1220,6 @@ fn fromUtf8Range(arg: RocList, countAndStart: CountAndStart) FromUtf8Result {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn errorToProblem(bytes: [*]u8, length: usize) struct { index: usize, problem: Utf8ByteProblem } {
|
||||
var index: usize = 0;
|
||||
|
||||
|
@ -1015,7 +1015,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||
StrStartsWith | StrEndsWith => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||
StrStartsWithCodePoint => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
StrFromUtf8 => arena.alloc_slice_copy(&[owned]),
|
||||
StrFromUtf8Range => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||
StrFromUtf8Range => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
StrToBytes => arena.alloc_slice_copy(&[owned]),
|
||||
StrFromInt | StrFromFloat => arena.alloc_slice_copy(&[irrelevant]),
|
||||
Hash => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
|
@ -842,3 +842,39 @@ fn str_from_utf8_range() {
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_from_utf8_range_slice() {
|
||||
assert_evals_to!(
|
||||
r#"
|
||||
bytes = Str.toBytes "hello"
|
||||
Str.fromUtf8Range bytes { start: 1, count: 4 }
|
||||
"#,
|
||||
RocStr::from("ello"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn str_from_utf8_range_slice_not_end() {
|
||||
assert_evals_to!(
|
||||
r#"
|
||||
bytes = Str.toBytes "hello"
|
||||
Str.fromUtf8Range bytes { start: 1, count: 3 }
|
||||
"#,
|
||||
RocStr::from("ell"),
|
||||
RocStr
|
||||
);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn str_from_utf8_range_slice() {
|
||||
// assert_evals_to!(
|
||||
// r#"
|
||||
// bytes = Str.toBytes "hello"
|
||||
// Str.fromUtf8Range bytes { start: 6, count: 5 }
|
||||
// "#,
|
||||
// RocStr::from("ello"),
|
||||
// RocStr
|
||||
// );
|
||||
// }
|
||||
|
Loading…
Reference in New Issue
Block a user