}
}
+void
+mark_maybe_objects (Lisp_Object *array, ptrdiff_t nelts)
+{
+ for (Lisp_Object *lim = array + nelts; array < lim; array++)
+ mark_maybe_object (*array);
+}
+
/* Return true if P might point to Lisp data that can be garbage
collected, and false otherwise (i.e., false if it is easy to see
that P cannot point to Lisp data that can be garbage collected).
break;
case SPECPDL_UNWIND:
+ case SPECPDL_UNWIND_ARRAY:
case SPECPDL_UNWIND_PTR:
case SPECPDL_UNWIND_INT:
case SPECPDL_UNWIND_EXCURSION:
grow_specpdl ();
}
+void
+record_unwind_protect_array (Lisp_Object *array, ptrdiff_t nelts)
+{
+ specpdl_ptr->unwind_array.kind = SPECPDL_UNWIND_ARRAY;
+ specpdl_ptr->unwind_array.array = array;
+ specpdl_ptr->unwind_array.nelts = nelts;
+ grow_specpdl ();
+}
+
void
record_unwind_protect_ptr (void (*function) (void *), void *arg)
{
case SPECPDL_UNWIND:
this_binding->unwind.func (this_binding->unwind.arg);
break;
+ case SPECPDL_UNWIND_ARRAY:
+ xfree (this_binding->unwind_array.array);
+ break;
case SPECPDL_UNWIND_PTR:
this_binding->unwind_ptr.func (this_binding->unwind_ptr.arg);
break;
save_excursion_restore (marker, window);
}
break;
+ case SPECPDL_UNWIND_ARRAY:
case SPECPDL_UNWIND_PTR:
case SPECPDL_UNWIND_INT:
case SPECPDL_UNWIND_VOID:
break;
case SPECPDL_UNWIND:
+ case SPECPDL_UNWIND_ARRAY:
case SPECPDL_UNWIND_PTR:
case SPECPDL_UNWIND_INT:
case SPECPDL_UNWIND_EXCURSION:
mark_object (specpdl_arg (pdl));
break;
+ case SPECPDL_UNWIND_ARRAY:
+ mark_maybe_objects (pdl->unwind_array.array, pdl->unwind_array.nelts);
+ break;
+
case SPECPDL_UNWIND_EXCURSION:
mark_object (pdl->unwind_excursion.marker);
mark_object (pdl->unwind_excursion.window);
enum specbind_tag {
SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object. */
+ SPECPDL_UNWIND_ARRAY, /* Likewise, on an array that needs freeing.
+ Its elements are potential Lisp_Objects. */
SPECPDL_UNWIND_PTR, /* Likewise, on void *. */
SPECPDL_UNWIND_INT, /* Likewise, on int. */
SPECPDL_UNWIND_EXCURSION, /* Likewise, on an execursion. */
void (*func) (Lisp_Object);
Lisp_Object arg;
} unwind;
+ struct {
+ ENUM_BF (specbind_tag) kind : CHAR_BIT;
+ void (*func) (Lisp_Object);
+ Lisp_Object *array;
+ ptrdiff_t nelts;
+ } unwind_array;
struct {
ENUM_BF (specbind_tag) kind : CHAR_BIT;
void (*func) (void *);
#endif
extern void alloc_unexec_pre (void);
extern void alloc_unexec_post (void);
+extern void mark_maybe_objects (Lisp_Object *, ptrdiff_t);
extern void mark_stack (char *, char *);
extern void flush_stack_call_func (void (*func) (void *arg), void *arg);
extern const char *pending_malloc_warning;
extern struct handler *push_handler_nosignal (Lisp_Object, enum handlertype);
extern void specbind (Lisp_Object, Lisp_Object);
extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
+extern void record_unwind_protect_array (Lisp_Object *, ptrdiff_t);
extern void record_unwind_protect_ptr (void (*) (void *), void *);
extern void record_unwind_protect_int (void (*) (int), int);
extern void record_unwind_protect_void (void (*) (void));
(buf) = AVAIL_ALLOCA (alloca_nbytes); \
else \
{ \
- Lisp_Object arg_; \
(buf) = xmalloc (alloca_nbytes); \
- arg_ = make_save_memory (buf, nelt); \
+ record_unwind_protect_array (buf, nelt); \
sa_must_free = true; \
- record_unwind_protect (free_save_value, arg_); \
} \
} while (false)