@@ -121,23 +121,29 @@ let ret_accu = Obj.repr (ref ())
121121
122122type accu_val = { mutable acc_atm : atom ; acc_arg : t list }
123123
124- external set_tag : Obj .t -> int -> unit = " coq_obj_set_tag"
125-
126- let mk_accu (a : atom ) : t =
127- let rec accumulate data x =
128- if Obj. repr x == ret_accu then Obj. repr data
129- else
130- let data = { data with acc_arg = x :: data .acc_arg } in
131- let ans = Obj. repr (accumulate data) in
132- let () = set_tag ans accumulate_tag in
133- ans
134- in
135- let acc = { acc_atm = a; acc_arg = [] } in
136- let ans = Obj. repr (accumulate acc) in
137- (* * FIXME: use another representation for accumulators, this causes naked
138- pointers. *)
139- let () = set_tag ans accumulate_tag in
140- (Obj. obj ans : t )
124+ (* * Returns a pointer to the code of a partial application of [accumulate], yet also recognized as an unscannable block *)
125+ external get_proxy_accu : (accu_val -> t -> t ) -> Obj .t = " coq_proxy_accu"
126+
127+ [@@@ warning " -69" ]
128+ type accu_clos = { clos_addr : Obj .t ; clos_arity : int ; clos_env : Obj .t }
129+
130+ let proxy_accu = ref None
131+
132+ let mk_accu data =
133+ let ans = { clos_addr = Option. get ! proxy_accu; clos_arity = 2 ; clos_env = Obj. repr data } in
134+ (* [ans] is indistinguishable from [accumulate data] *)
135+ (Obj. magic ans : t )
136+
137+ let accumulate data x =
138+ if Obj. repr x == ret_accu then (Obj. magic data : t )
139+ else mk_accu { data with acc_arg = x :: data .acc_arg }
140+
141+ let () =
142+ proxy_accu := Some (get_proxy_accu accumulate)
143+
144+ let mk_accu a : t =
145+ let data = { acc_atm = a; acc_arg = [] } in
146+ mk_accu data
141147
142148let get_accu (k : accumulator ) =
143149 (Obj. magic k : Obj.t -> accu_val ) ret_accu
0 commit comments