3
3
*)
4
4
5
5
open Common ;;
6
+ open Semant ;;
6
7
open Transutil ;;
7
8
8
9
let log cx = Session. log " trans"
@@ -549,6 +550,37 @@ let trans_crate
549
550
end
550
551
in
551
552
553
+ (* Dereferences the box referred to by ptr, whose type is ty. Looks
554
+ straight through all mutable and constrained-type boxes, and loads
555
+ pointers per dctrl. Returns the dereferenced value and its type. *)
556
+ let rec deref_ty
557
+ (llbuilder :Llvm.llbuilder ) (dctrl :deref_ctrl )
558
+ (ptr :Llvm.llvalue ) (ty :Ast.ty )
559
+ : (Llvm.llvalue * Ast.ty) =
560
+ match (ty, dctrl) with
561
+
562
+ | (Ast. TY_mutable ty, _)
563
+ | (Ast. TY_constrained (ty , _ ), _ ) ->
564
+ deref_ty llbuilder dctrl ptr ty
565
+
566
+ | (Ast. TY_box ty', DEREF_one_box )
567
+ | (Ast. TY_box ty' , DEREF_all_boxes) ->
568
+ let content =
569
+ Llvm. build_load
570
+ (get_element_ptr llbuilder ptr (Abi. box_rc_field_body))
571
+ (anon_llid " deref" ) llbuilder
572
+ in
573
+ let inner_dctrl =
574
+ if dctrl = DEREF_one_box
575
+ then DEREF_none
576
+ else DEREF_all_boxes
577
+ in
578
+ (* Possibly deref recursively. *)
579
+ deref_ty llbuilder inner_dctrl content ty'
580
+
581
+ | _ -> (ptr, ty)
582
+ in
583
+
552
584
let (llitems:(node_id, Llvm.llvalue) Hashtbl. t ) = Hashtbl. create 0 in
553
585
(* Maps a fn's or block's id to an LLVM metadata node (subprogram or
554
586
lexical block) representing it. *)
@@ -724,36 +756,61 @@ let trans_crate
724
756
725
757
(* Translates an lval by reference into the appropriate pointer
726
758
* value. *)
727
- let trans_lval (lval :Ast.lval ) : Llvm.llvalue =
759
+ let rec trans_lval (lval :Ast.lval ) : ( Llvm.llvalue * Ast.ty) =
728
760
iflog (fun _ -> log sem_cx " trans_lval: %a" Ast. sprintf_lval lval);
729
761
match lval with
730
762
Ast. LVAL_base { id = base_id } ->
731
763
set_debug_loc base_id;
732
- let id =
733
- Hashtbl. find sem_cx.Semant. ctxt_lval_to_referent base_id
734
- in
735
- let referent = Hashtbl. find sem_cx.Semant. ctxt_all_defns id in
764
+ let referent = lval_to_referent sem_cx base_id in
736
765
begin
737
- match referent with
738
- Semant. DEFN_slot _ -> Hashtbl. find slot_to_llvalue id
739
- | Semant. DEFN_item _ -> Hashtbl. find llitems id
766
+ match resolve_lval_id sem_cx base_id with
767
+ Semant. DEFN_slot slot ->
768
+ (Hashtbl. find slot_to_llvalue referent, slot_ty slot)
769
+ | Semant. DEFN_item _ ->
770
+ (Hashtbl. find llitems referent, lval_ty sem_cx lval)
740
771
| _ ->
741
- Common. unimpl (Some id )
772
+ Common. unimpl (Some referent )
742
773
" LLVM base-referent translation of: %a"
743
774
Ast. sprintf_lval lval
744
775
end
745
- | Ast. LVAL_ext _ ->
746
- Common. unimpl (Some (Semant. lval_base_id lval))
747
- " LLVM lval translation of: %a"
748
- Ast. sprintf_lval lval
776
+ | Ast. LVAL_ext (base , component ) ->
777
+ let (llbase, base_ty) = trans_lval base in
778
+ let base_ty = strip_mutable_or_constrained_ty base_ty in
779
+ (*
780
+ * All lval components aside from explicit-deref just
781
+ * auto-deref through all boxes to find their indexable
782
+ * referent.
783
+ *)
784
+ let (llbase, base_ty) =
785
+ if component = Ast. COMP_deref
786
+ then (llbase, base_ty)
787
+ else deref_ty llbuilder DEREF_all_boxes llbase base_ty
788
+ in
789
+ match (base_ty, component) with
790
+ (Ast. TY_rec entries ,
791
+ Ast. COMP_named (Ast. COMP_ident id )) ->
792
+ let i = arr_idx (Array. map fst entries) id in
793
+ (get_element_ptr llbuilder llbase i, snd entries.(i))
794
+
795
+ | (Ast. TY_tup entries,
796
+ Ast. COMP_named (Ast. COMP_idx i)) ->
797
+ (get_element_ptr llbuilder llbase i, entries.(i))
798
+
799
+ | (Ast. TY_box _ , Ast. COMP_deref) ->
800
+ deref_ty llbuilder DEREF_one_box llbase base_ty
801
+
802
+ | _ -> (Common. unimpl (Some (Semant. lval_base_id lval))
803
+ " LLVM lval translation of: %a"
804
+ Ast. sprintf_lval lval)
749
805
in
750
806
751
807
let trans_atom (atom :Ast.atom ) : Llvm.llvalue =
752
808
iflog (fun _ -> log sem_cx " trans_atom: %a" Ast. sprintf_atom atom);
753
809
match atom with
754
810
Ast. ATOM_literal { node = lit } -> trans_literal lit
755
811
| Ast. ATOM_lval lval ->
756
- Llvm. build_load (trans_lval lval) (anon_llid " tmp" ) llbuilder
812
+ Llvm. build_load (fst (trans_lval lval)) (anon_llid " tmp" )
813
+ llbuilder
757
814
in
758
815
759
816
let build_binop (op :Ast.binop ) (lllhs :Llvm.llvalue ) (llrhs :Llvm.llvalue )
@@ -867,7 +924,7 @@ let trans_crate
867
924
match head.node with
868
925
Ast. STMT_init_tup (dest , elems ) ->
869
926
let zero = const_i32 0 in
870
- let lldest = trans_lval dest in
927
+ let ( lldest, _) = trans_lval dest in
871
928
let trans_tup_elem idx (_ , atom ) =
872
929
let indices = [| zero; const_i32 idx |] in
873
930
let gep_id = anon_llid " init_tup_gep" in
@@ -881,12 +938,12 @@ let trans_crate
881
938
882
939
| Ast. STMT_copy (dest , src ) ->
883
940
let llsrc = trans_expr src in
884
- let lldest = trans_lval dest in
941
+ let ( lldest, _) = trans_lval dest in
885
942
ignore (Llvm. build_store llsrc lldest llbuilder);
886
943
trans_tail ()
887
944
888
945
| Ast. STMT_copy_binop (dest , op , src ) ->
889
- let lldest = trans_lval dest in
946
+ let ( lldest, _) = trans_lval dest in
890
947
let llsrc = trans_atom src in
891
948
(* FIXME: Handle vecs and strs. *)
892
949
let lldest_deref =
@@ -898,8 +955,8 @@ let trans_crate
898
955
899
956
| Ast. STMT_call (dest , fn , args ) ->
900
957
let llargs = Array. map trans_atom args in
901
- let lldest = trans_lval dest in
902
- let llfn = trans_lval fn in
958
+ let ( lldest, _) = trans_lval dest in
959
+ let ( llfn, _) = trans_lval fn in
903
960
let llallargs = Array. append [| lldest; lltask |] llargs in
904
961
let llrv = build_call llfn llallargs " " llbuilder in
905
962
Llvm. set_instruction_call_conv Llvm.CallConv. c llrv;
@@ -966,7 +1023,7 @@ let trans_crate
966
1023
trans_tail_with_builder llokbuilder
967
1024
968
1025
| Ast. STMT_init_str (dst , str ) ->
969
- let d = trans_lval dst in
1026
+ let (d, _) = trans_lval dst in
970
1027
let s = static_str str in
971
1028
let len =
972
1029
Llvm. const_int word_ty ((String. length str) + 1 )
0 commit comments