summaryrefslogtreecommitdiff
path: root/src/eval.c
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2022-03-05 11:12:54 +0100
committerAndrew G Cohen <cohen@andy.bu.edu>2022-04-04 07:42:12 +0800
commite091bee8db9926716a3e7778275901696896cbdf (patch)
treedd1d1867f6fd7c24b24af6ce5af9de278b1638d9 /src/eval.c
parent9fab134ee8b4ed439a8944e0d7058b1898c9bc0b (diff)
downloademacs-e091bee8db9926716a3e7778275901696896cbdf.tar.gz
Add optional GC marking function to specpdl unwind_ptr record
Add a new `record_unwind_protect_ptr_mark` function for use with C data structures that use the specpdl for clean-up but also contain possibly unique references to Lisp objects. * src/eval.c (record_unwind_protect_ptr_mark): New. (record_unwind_protect_module, set_unwind_protect_ptr): Set the mark function to NULL. (mark_specpdl): Call the mark function if present. * src/lisp.h (unwind_ptr): Add a mark function pointer to the SPECPDL_UNWIND_PTR case.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/eval.c b/src/eval.c
index a4449b18f9b..7269582333c 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3496,6 +3496,20 @@ record_unwind_protect_ptr (void (*function) (void *), void *arg)
specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
specpdl_ptr->unwind_ptr.func = function;
specpdl_ptr->unwind_ptr.arg = arg;
+ specpdl_ptr->unwind_ptr.mark = NULL;
+ grow_specpdl ();
+}
+
+/* Like `record_unwind_protect_ptr', but also specifies a function
+ for GC-marking Lisp objects only reachable through ARG. */
+void
+record_unwind_protect_ptr_mark (void (*function) (void *), void *arg,
+ void (*mark) (void *))
+{
+ specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
+ specpdl_ptr->unwind_ptr.func = function;
+ specpdl_ptr->unwind_ptr.arg = arg;
+ specpdl_ptr->unwind_ptr.mark = mark;
grow_specpdl ();
}
@@ -3539,6 +3553,7 @@ record_unwind_protect_module (enum specbind_tag kind, void *ptr)
specpdl_ptr->kind = kind;
specpdl_ptr->unwind_ptr.func = NULL;
specpdl_ptr->unwind_ptr.arg = ptr;
+ specpdl_ptr->unwind_ptr.mark = NULL;
grow_specpdl ();
}
@@ -3667,6 +3682,7 @@ set_unwind_protect_ptr (specpdl_ref count, void (*func) (void *), void *arg)
p->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
p->unwind_ptr.func = func;
p->unwind_ptr.arg = arg;
+ p->unwind_ptr.mark = NULL;
}
/* Pop and execute entries from the unwind-protect stack until the
@@ -4100,6 +4116,10 @@ mark_specpdl (union specbinding *first, union specbinding *ptr)
break;
case SPECPDL_UNWIND_PTR:
+ if (pdl->unwind_ptr.mark)
+ pdl->unwind_ptr.mark (pdl->unwind_ptr.arg);
+ break;
+
case SPECPDL_UNWIND_INT:
case SPECPDL_UNWIND_INTMAX:
case SPECPDL_UNWIND_VOID: