Skip to content

Commit d86a022

Browse files
committed
Merge branch 'sync/fix_memory_corruption' into 'master'
Refactor AnalysisContextStruct creation See merge request eng/libadalang/langkit!929
2 parents 70ed788 + f9fb9b4 commit d86a022

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

langkit/templates/ocaml_api/struct_types_ocaml.mako

+22-15
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ module AnalysisContextStruct : sig
270270
271271
val c_type : t typ
272272
273-
val allocate_analysis_context : unit -> t
273+
val allocate_analysis_context : ?keep:'a -> unit -> t
274274
val initialize_analysis_context :
275275
t -> string -> unit ptr -> unit ptr -> unit ptr -> bool -> int -> unit
276276
@@ -295,23 +295,30 @@ end = struct
295295
296296
let unwrap (value : t) : unit ptr = !@value
297297
298-
let context_decref =
299-
let f =
300-
foreign ~from:c_lib "${capi.get_name('context_decref')}"
301-
(ptr void @-> raisable void)
302-
in
303-
fun ctx -> f (unwrap ctx)
304-
305-
let wrap (c_value : unit ptr) : t =
306-
(* To deallocate cleanly the context, we need to call context_decref.
307-
Allocate a value and attach a finalizer to it *)
308-
allocate ~finalise:context_decref (ptr void) c_value
298+
(* The read part is not required as the only function returning a c_type is
299+
allocate_analysis_context which is manually written to take an object
300+
to keep alive as argument *)
301+
let c_type = view (ptr void) ~read:(fun _ -> assert false) ~write:unwrap
309302
310-
let c_type = view (ptr void) ~read:wrap ~write:unwrap
303+
let context_decref =
304+
foreign ~from:c_lib "${capi.get_name('context_decref')}"
305+
(c_type @-> raisable void)
311306
312-
let allocate_analysis_context =
307+
let c_allocate_analysis_context =
313308
foreign ~from:c_lib "${capi.get_name('allocate_analysis_context')}"
314-
( void @-> raisable c_type )
309+
( void @-> raisable (ptr void) )
310+
311+
let allocate_analysis_context ?keep () =
312+
(* To deallocate cleanly the context, we need to call context_decref.
313+
Allocate a value and attach a finalizer to it. Use the keep option
314+
to keep an object alive while the analysis context is. *)
315+
let ref_keep = ref keep in
316+
let finalise arg =
317+
ref_keep := None;
318+
context_decref arg
319+
in
320+
let c_value = c_allocate_analysis_context () in
321+
allocate ~finalise (ptr void) c_value
315322
316323
let initialize_analysis_context =
317324
foreign ~from:c_lib "${capi.get_name('initialize_analysis_context')}"

0 commit comments

Comments
 (0)