From c6ca5a6b7a5845ebf11ed06b73e87164b18ce6ca Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Wed, 8 Jan 2025 12:15:30 +0000 Subject: [PATCH] Fix store_function_docstring for native subrs (Bug#74966) Since native subrs can have either etc/DOC indexes or vector indexes, we use the sign bit of the 'doc' field to distinguish the two cases. * src/comp.c (native_function_doc, make_subr): Use one's complement of doc index for native subrs. * src/doc.c (store_function_docstring): Add assertion. * src/lisp.h (struct Lisp_Subr): Document 'doc' sign bit. (cherry picked from commit ac52993b996927031a6913927e1028de47be4312) --- src/comp.c | 8 ++++++-- src/doc.c | 5 ++++- src/lisp.h | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/comp.c b/src/comp.c index 70a9a64a714..b96fae4ae95 100644 --- a/src/comp.c +++ b/src/comp.c @@ -5488,7 +5488,10 @@ native_function_doc (Lisp_Object function) if (!VECTORP (cu->data_fdoc_v)) xsignal2 (Qnative_lisp_file_inconsistent, cu->file, build_string ("missing documentation vector")); - return AREF (cu->data_fdoc_v, XSUBR (function)->doc); + EMACS_INT doc = XSUBR (function)->doc; + if (doc < 0) + return AREF (cu->data_fdoc_v, -doc - 1); + return make_fixnum (doc); } static Lisp_Object @@ -5529,7 +5532,8 @@ make_subr (Lisp_Object symbol_name, Lisp_Object minarg, Lisp_Object maxarg, x->s.symbol_name = xstrdup (SSDATA (symbol_name)); x->s.intspec.native = intspec; x->s.command_modes = command_modes; - x->s.doc = XFIXNUM (doc_idx); + x->s.doc = -XFIXNUM (doc_idx) - 1; + eassert (x->s.doc < 0); #ifdef HAVE_NATIVE_COMP x->s.native_comp_u = comp_u; x->s.native_c_name = xstrdup (SSDATA (c_name)); diff --git a/src/doc.c b/src/doc.c index 88be9121dab..04afe50d3dd 100644 --- a/src/doc.c +++ b/src/doc.c @@ -479,7 +479,10 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset) fun = XCDR (fun); /* Lisp_Subrs have a slot for it. */ if (SUBRP (fun)) - XSUBR (fun)->doc = offset; + { + XSUBR (fun)->doc = offset; + eassert (XSUBR (fun)->doc >= 0); + } else if (CLOSUREP (fun)) { /* This bytecode object must have a slot for the docstring, since diff --git a/src/lisp.h b/src/lisp.h index 4217dd9e347..4c09afc77e2 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2228,6 +2228,9 @@ struct Lisp_Subr Lisp_Object native; } intspec; Lisp_Object command_modes; + /* positive values: offset into etc/DOC. Negative values: one's + complement of index into the native comp unit's function + documentation vector. */ EMACS_INT doc; #ifdef HAVE_NATIVE_COMP Lisp_Object native_comp_u; -- 2.39.5