mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
inc/dec string slices
This commit is contained in:
parent
62dac6bdf8
commit
736b7c6a83
1 changed files with 52 additions and 62 deletions
|
@ -777,6 +777,13 @@ fn refcount_str<'a>(
|
||||||
let layout_isize = root.layout_isize;
|
let layout_isize = root.layout_isize;
|
||||||
let field_layouts = arena.alloc([Layout::OPAQUE_PTR, layout_isize, layout_isize]);
|
let field_layouts = arena.alloc([Layout::OPAQUE_PTR, layout_isize, layout_isize]);
|
||||||
|
|
||||||
|
let is_increment = matches!(ctx.op, HelperOp::Inc);
|
||||||
|
|
||||||
|
let (modify_rc_ptr, modify_data_ptr) = match is_increment {
|
||||||
|
true => (LowLevel::RefCountIncRcPtr, LowLevel::RefCountIncDataPtr),
|
||||||
|
false => (LowLevel::RefCountDecRcPtr, LowLevel::RefCountDecDataPtr),
|
||||||
|
};
|
||||||
|
|
||||||
// Get the last word as a signed int
|
// Get the last word as a signed int
|
||||||
let last_word = root.create_symbol(ident_ids, "last_word");
|
let last_word = root.create_symbol(ident_ids, "last_word");
|
||||||
let last_word_expr = Expr::StructAtIndex {
|
let last_word_expr = Expr::StructAtIndex {
|
||||||
|
@ -819,6 +826,11 @@ fn refcount_str<'a>(
|
||||||
};
|
};
|
||||||
let length_stmt = |next| Stmt::Let(length, length_expr, layout_isize, next);
|
let length_stmt = |next| Stmt::Let(length, length_expr, layout_isize, next);
|
||||||
|
|
||||||
|
let alignment = root.create_symbol(ident_ids, "alignment");
|
||||||
|
let alignment_int = root.target_info.ptr_width() as u32;
|
||||||
|
let alignment_expr = Expr::Literal(Literal::Int((alignment_int as u128).to_ne_bytes()));
|
||||||
|
let alignment_stmt = |next| Stmt::Let(alignment, alignment_expr, layout_isize, next);
|
||||||
|
|
||||||
// let is_slice = lowlevel NumLt length zero
|
// let is_slice = lowlevel NumLt length zero
|
||||||
let is_slice = root.create_symbol(ident_ids, "is_slice");
|
let is_slice = root.create_symbol(ident_ids, "is_slice");
|
||||||
let is_slice_stmt =
|
let is_slice_stmt =
|
||||||
|
@ -828,39 +840,24 @@ fn refcount_str<'a>(
|
||||||
// Branch on seamless slice vs "real" string
|
// Branch on seamless slice vs "real" string
|
||||||
//
|
//
|
||||||
|
|
||||||
let jp_chars = JoinPointId(root.create_symbol(ident_ids, "jp_chars"));
|
let second_argument = match is_increment {
|
||||||
let chars = root.create_symbol(ident_ids, "chars");
|
true => Symbol::ARG_2,
|
||||||
let param_elems = Param {
|
false => alignment,
|
||||||
symbol: chars,
|
|
||||||
ownership: Ownership::Owned,
|
|
||||||
layout: Layout::OPAQUE_PTR,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// one = 1
|
// when the string is a slice, the capacity field is a pointer to the refcount
|
||||||
let one = root.create_symbol(ident_ids, "one");
|
let unit = root.create_symbol(ident_ids, "unit");
|
||||||
let one_expr = Expr::Literal(Literal::Int(1i128.to_ne_bytes()));
|
let slice_branch = let_lowlevel(
|
||||||
let one_stmt = |next| Stmt::Let(one, one_expr, layout_isize, next);
|
arena,
|
||||||
|
Layout::UNIT,
|
||||||
// slice_elems = lowlevel NumShiftLeftBy length one
|
unit,
|
||||||
let slice_chars = root.create_symbol(ident_ids, "slice_chars");
|
modify_rc_ptr,
|
||||||
let slice_chars_stmt = |next| {
|
&[last_word, second_argument],
|
||||||
let_lowlevel(
|
arena.alloc(
|
||||||
arena,
|
|
||||||
layout_isize,
|
|
||||||
slice_chars,
|
|
||||||
NumShiftLeftBy,
|
|
||||||
&[length, one],
|
|
||||||
next,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let slice_branch = one_stmt(arena.alloc(
|
|
||||||
//
|
|
||||||
slice_chars_stmt(arena.alloc(
|
|
||||||
//
|
//
|
||||||
Stmt::Jump(jp_chars, arena.alloc([slice_chars])),
|
Stmt::Ret(unit),
|
||||||
)),
|
),
|
||||||
));
|
);
|
||||||
|
|
||||||
// Characters pointer for a real string
|
// Characters pointer for a real string
|
||||||
let string_chars = root.create_symbol(ident_ids, "string_chars");
|
let string_chars = root.create_symbol(ident_ids, "string_chars");
|
||||||
|
@ -871,11 +868,23 @@ fn refcount_str<'a>(
|
||||||
};
|
};
|
||||||
let string_chars_stmt = |next| Stmt::Let(string_chars, string_chars_expr, layout_isize, next);
|
let string_chars_stmt = |next| Stmt::Let(string_chars, string_chars_expr, layout_isize, next);
|
||||||
|
|
||||||
|
let modify_rc_stmt = let_lowlevel(
|
||||||
|
arena,
|
||||||
|
Layout::UNIT,
|
||||||
|
unit,
|
||||||
|
modify_data_ptr,
|
||||||
|
&[string_chars, second_argument],
|
||||||
|
arena.alloc(
|
||||||
|
//
|
||||||
|
Stmt::Ret(unit),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
let string_branch = arena.alloc(
|
let string_branch = arena.alloc(
|
||||||
//
|
//
|
||||||
string_chars_stmt(arena.alloc(
|
string_chars_stmt(arena.alloc(
|
||||||
//
|
//
|
||||||
Stmt::Jump(jp_chars, arena.alloc([string_chars])),
|
modify_rc_stmt,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -884,49 +893,30 @@ fn refcount_str<'a>(
|
||||||
is_slice,
|
is_slice,
|
||||||
Layout::UNIT,
|
Layout::UNIT,
|
||||||
slice_branch,
|
slice_branch,
|
||||||
root.arena.alloc(string_branch),
|
string_branch,
|
||||||
);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Modify Refcount
|
|
||||||
//
|
|
||||||
|
|
||||||
let alignment = root.target_info.ptr_width() as u32;
|
|
||||||
let ret_stmt = rc_return_stmt(root, ident_ids, ctx);
|
|
||||||
let modify_rc_stmt = modify_refcount(
|
|
||||||
root,
|
|
||||||
ident_ids,
|
|
||||||
ctx,
|
|
||||||
chars,
|
|
||||||
alignment,
|
|
||||||
arena.alloc(ret_stmt),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// JoinPoint for slice vs list
|
// JoinPoint for slice vs list
|
||||||
//
|
//
|
||||||
|
|
||||||
let joinpoint_elems = Stmt::Join {
|
let modify_stmt = length_stmt(arena.alloc(
|
||||||
id: jp_chars,
|
//
|
||||||
parameters: arena.alloc([param_elems]),
|
is_slice_stmt(arena.alloc(
|
||||||
body: arena.alloc(modify_rc_stmt),
|
|
||||||
remainder: arena.alloc(
|
|
||||||
//
|
//
|
||||||
length_stmt(arena.alloc(
|
if_slice,
|
||||||
//
|
)),
|
||||||
is_slice_stmt(arena.alloc(
|
));
|
||||||
//
|
|
||||||
if_slice,
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
let if_big_stmt = Stmt::if_then_else(
|
let if_big_stmt = Stmt::if_then_else(
|
||||||
root.arena,
|
root.arena,
|
||||||
is_big_str,
|
is_big_str,
|
||||||
Layout::UNIT,
|
Layout::UNIT,
|
||||||
joinpoint_elems,
|
if is_increment {
|
||||||
|
modify_stmt
|
||||||
|
} else {
|
||||||
|
alignment_stmt(arena.alloc(modify_stmt))
|
||||||
|
},
|
||||||
root.arena.alloc(rc_return_stmt(root, ident_ids, ctx)),
|
root.arena.alloc(rc_return_stmt(root, ident_ids, ctx)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue