Skip to content

Commit ddd8fee

Browse files
committed
Support single-element append on vec, str. Closes #44.
1 parent 40fccac commit ddd8fee

File tree

4 files changed

+90
-8
lines changed

4 files changed

+90
-8
lines changed

src/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ TEST_XFAILS_LLVM := $(TASK_XFAILS) \
427427
acyclic-unwind.rs \
428428
alt-pattern-simple.rs \
429429
alt-tag.rs \
430+
append-units.rs \
430431
argv.rs \
431432
autoderef-full-lval.rs \
432433
autoderef-objfn.rs \

src/boot/me/trans.ml

+53-8
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ let trans_visitor
8888
let zero = imm 0L in
8989
let imm_true = imm_of_ty 1L TY_u8 in
9090
let imm_false = imm_of_ty 0L TY_u8 in
91+
let zero_byte = imm_of_ty 0L TY_u8 in
9192
let nil_ptr = Il.Mem ((Il.Abs (Asm.IMM 0L)), Il.NilTy) in
9293
let wordptr_ty = Il.AddrTy (Il.ScalarTy word_sty) in
9394

@@ -4389,18 +4390,18 @@ let trans_visitor
43894390
(src_ty:Ast.ty)
43904391
: unit =
43914392
let elt_ty = seq_unit_ty dst_ty in
4392-
let trim_trailing_null = dst_ty = Ast.TY_str in
4393-
assert (simplified_ty src_ty = simplified_ty dst_ty);
4394-
match simplified_ty src_ty with
4395-
Ast.TY_str
4396-
| Ast.TY_vec _ ->
4393+
let trailing_null = simplified_ty dst_ty = Ast.TY_str in
4394+
match (simplified_ty dst_ty, simplified_ty src_ty) with
4395+
(Ast.TY_str, Ast.TY_str)
4396+
| (Ast.TY_vec _, Ast.TY_vec _)
4397+
when (simplified_ty dst_ty) = (simplified_ty src_ty) ->
43974398
let is_gc = if type_has_state src_ty then 1L else 0L in
43984399
let src_cell = need_cell src_oper in
43994400
let src_vec = deref src_cell in
44004401
let src_fill = get_element_ptr src_vec Abi.vec_elt_fill in
44014402
let dst_vec = deref dst_cell in
44024403
let dst_fill = get_element_ptr dst_vec Abi.vec_elt_fill in
4403-
if trim_trailing_null
4404+
if trailing_null
44044405
then sub_from dst_fill (imm 1L);
44054406
trans_upcall "upcall_vec_grow"
44064407
dst_cell
@@ -4457,9 +4458,53 @@ let trans_visitor
44574458
let v = next_vreg_cell word_sty in
44584459
mov v (Il.Cell src_fill);
44594460
add_to dst_fill (Il.Cell v);
4460-
| t ->
4461+
4462+
| (Ast.TY_str, e)
4463+
| (Ast.TY_vec _, e)
4464+
when e = simplified_ty elt_ty ->
4465+
4466+
let dst_is_gc = if type_has_state dst_ty then 1L else 0L in
4467+
let elt_sz = ty_sz_in_current_frame elt_ty in
4468+
trans_upcall "upcall_vec_grow"
4469+
dst_cell
4470+
[| Il.Cell dst_cell;
4471+
elt_sz;
4472+
imm dst_is_gc |];
4473+
4474+
(*
4475+
* By now, dst_cell points to a vec/str with room for us
4476+
* to add to.
4477+
*)
4478+
4479+
(* Reload dst vec, fill; might have changed. *)
4480+
let dst_vec = deref dst_cell in
4481+
let dst_fill = get_element_ptr dst_vec Abi.vec_elt_fill in
4482+
4483+
let eltp_rty = Il.AddrTy (referent_type word_bits elt_ty) in
4484+
let dptr = next_vreg_cell eltp_rty in
4485+
let dst_data =
4486+
get_element_ptr_dyn_in_current_frame
4487+
dst_vec Abi.vec_elt_data
4488+
in
4489+
lea dptr (fst (need_mem_cell dst_data));
4490+
add_to dptr (Il.Cell dst_fill);
4491+
if trailing_null
4492+
then sub_from dptr elt_sz;
4493+
trans_copy_ty
4494+
(get_ty_params_of_current_frame()) true
4495+
(deref dptr) elt_ty
4496+
(Il.Mem (force_to_mem src_oper)) elt_ty
4497+
None;
4498+
add_to dptr elt_sz;
4499+
if trailing_null
4500+
then mov (deref dptr) zero_byte;
4501+
add_to dst_fill elt_sz;
4502+
4503+
| _ ->
44614504
begin
4462-
bug () "unsupported vector-append type %a" Ast.sprintf_ty t
4505+
bug () "unsupported vector-append types %a += %a"
4506+
Ast.sprintf_ty dst_ty
4507+
Ast.sprintf_ty src_ty
44634508
end
44644509

44654510

src/boot/me/type.ml

+21
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,27 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
763763
| Ast.STMT_copy (dst, src) ->
764764
infer_lval (check_expr src) dst
765765

766+
| Ast.STMT_copy_binop (dst, Ast.BINOP_add, src) ->
767+
begin
768+
let src_ty = check_atom ~deref:true src in
769+
let dst_ty = check_lval dst in
770+
match fundamental_ty dst_ty, fundamental_ty src_ty with
771+
Ast.TY_vec elt1, Ast.TY_vec elt2
772+
| Ast.TY_vec elt1, elt2 ->
773+
if elt1 = elt2
774+
then ()
775+
else
776+
Common.err None
777+
"mismatched types in vec-append: %a += %a"
778+
Ast.sprintf_ty dst_ty
779+
Ast.sprintf_ty src_ty
780+
| Ast.TY_str, (Ast.TY_mach Common.TY_u8)
781+
| Ast.TY_str, Ast.TY_str -> ()
782+
| _ ->
783+
infer_lval src_ty dst;
784+
demand src_ty (check_binop Ast.BINOP_add src_ty)
785+
end
786+
766787
| Ast.STMT_copy_binop (dst, binop, src) ->
767788
let ty = check_atom ~deref:true src in
768789
infer_lval ty dst;

src/test/run-pass/append-units.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
fn main() {
2+
auto v = vec(1,2,3);
3+
v += 4;
4+
v += 5;
5+
check (v.(3) == 4);
6+
check (v.(4) == 5);
7+
8+
auto s = "hello";
9+
log s;
10+
s += 'z' as u8;
11+
s += 'y' as u8;
12+
log s;
13+
check (s.(5) == 'z' as u8);
14+
check (s.(6) == 'y' as u8);
15+
}

0 commit comments

Comments
 (0)