@@ -453,6 +453,11 @@ let trans_visitor
453
453
Il. Mem (fp_imm out_mem_disp, args_rty)
454
454
in
455
455
456
+ let fp_to_args (fp :Il.cell ) (args_rty :Il.referent_ty ): Il.cell =
457
+ let (reg, _) = force_to_reg (Il. Cell fp) in
458
+ Il. Mem (based_imm reg out_mem_disp, args_rty)
459
+ in
460
+
456
461
let get_ty_param (ty_params :Il.cell ) (param_idx :int ) : Il.cell =
457
462
get_element_ptr ty_params param_idx
458
463
in
@@ -753,6 +758,28 @@ let trans_visitor
753
758
Il. Mem (mem, (pointee_type ptr))
754
759
in
755
760
761
+ (*
762
+ * Within a for-each block, calculate the fp of an enclosing for-each block
763
+ * or the enclosing function by chasing static links.
764
+ *)
765
+ let get_nth_outer_frame_ptr (diff :int ) : Il.cell =
766
+ (* All for-each block frames have the same args. *)
767
+ let block_args_rty = current_fn_args_rty None in
768
+ let current_fp = Il. Reg (abi.Abi. abi_fp_reg, Il. AddrTy Il. OpaqueTy ) in
769
+ let rec out (n :int ) (fp :Il.cell ) : Il.cell =
770
+ if n == 0
771
+ then fp
772
+ else
773
+ let args = fp_to_args fp block_args_rty in
774
+ let iter_args = get_element_ptr args Abi. calltup_elt_iterator_args in
775
+ let outer_fp =
776
+ get_element_ptr iter_args Abi. iterator_args_elt_outer_frame_ptr
777
+ in
778
+ out (n - 1 ) outer_fp
779
+ in
780
+ out diff current_fp
781
+ in
782
+
756
783
let cell_of_block_slot
757
784
(slot_id :node_id )
758
785
: Il.cell =
@@ -820,28 +847,13 @@ let trans_visitor
820
847
in
821
848
let diff = stmt_depth - slot_depth in
822
849
let _ = annotate " get outer frame pointer" in
823
- let fp =
824
- get_iter_outer_frame_ptr_for_current_frame ()
850
+ let fp = get_nth_outer_frame_ptr diff in
851
+ let _ = annotate " calculate size" in
852
+ let p =
853
+ based_sz (get_ty_params_of_current_frame() )
854
+ (fst (force_to_reg (Il. Cell fp))) off
825
855
in
826
- if diff > 1
827
- then
828
- bug () " unsupported nested for each loop" ;
829
- for i = 2 to diff do
830
- (* FIXME (issue #79): access outer
831
- * caller-block fps, given nearest
832
- * caller-block fp.
833
- *)
834
- let _ =
835
- annotate " step to outer-outer frame"
836
- in
837
- mov fp (Il. Cell fp)
838
- done ;
839
- let _ = annotate " calculate size" in
840
- let p =
841
- based_sz (get_ty_params_of_current_frame() )
842
- (fst (force_to_reg (Il. Cell fp))) off
843
- in
844
- Il. Mem (p, referent_type)
856
+ Il. Mem (p, referent_type)
845
857
else
846
858
Il. Mem (fp_off_sz off, referent_type)
847
859
end
0 commit comments