mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
FFI: Hold a weak reference to the procedure passed to `procedure->pointer'.
* libguile/foreign.c (scm_procedure_to_pointer): Keep a weak reference to PROC. * test-suite/tests/foreign.test ("procedure->pointer")["procedure is retained"]: New test.
This commit is contained in:
parent
4855c63441
commit
59a0273338
2 changed files with 20 additions and 2 deletions
|
@ -1152,7 +1152,8 @@ SCM_DEFINE (scm_procedure_to_pointer, "procedure->pointer", 3, 0, 0,
|
|||
if (closure == executable)
|
||||
{
|
||||
pointer = scm_from_pointer (executable, ffi_closure_free);
|
||||
register_weak_reference (pointer, cif_pointer);
|
||||
register_weak_reference (pointer,
|
||||
scm_list_2 (proc, cif_pointer));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1166,7 +1167,8 @@ SCM_DEFINE (scm_procedure_to_pointer, "procedure->pointer", 3, 0, 0,
|
|||
pointer = scm_from_pointer (executable, NULL);
|
||||
friend = scm_from_pointer (closure, ffi_closure_free);
|
||||
|
||||
register_weak_reference (pointer, scm_list_2 (cif_pointer, friend));
|
||||
register_weak_reference (pointer,
|
||||
scm_list_3 (proc, cif_pointer, friend));
|
||||
}
|
||||
|
||||
return pointer;
|
||||
|
|
|
@ -272,6 +272,22 @@
|
|||
(proc* (pointer->procedure void pointer '())))
|
||||
(proc*)
|
||||
called?)
|
||||
(throw 'unresolved)))
|
||||
|
||||
(pass-if "procedure is retained"
|
||||
;; The lambda passed to `procedure->pointer' must remain live.
|
||||
(if (defined? 'procedure->pointer)
|
||||
(let* ((ptr (procedure->pointer int
|
||||
(lambda (x) (+ x 7))
|
||||
(list int)))
|
||||
(procs (unfold (cut >= <> 10000)
|
||||
(lambda (i)
|
||||
(pointer->procedure int ptr (list int)))
|
||||
1+
|
||||
0)))
|
||||
(gc) (gc) (gc)
|
||||
(every (cut = <> 9)
|
||||
(map (lambda (f) (f 2)) procs)))
|
||||
(throw 'unresolved))))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue