unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Helmut Eller <eller.helmut@gmail.com>
To: "Gerd Möllmann" <gerd.moellmann@gmail.com>
Cc: Eli Zaretskii <eliz@gnu.org>,  emacs-devel@gnu.org
Subject: Re: Collecting markers with MPS
Date: Wed, 24 Apr 2024 21:03:20 +0200	[thread overview]
Message-ID: <87edauinwn.fsf@gmail.com> (raw)
In-Reply-To: <m2y193i0wf.fsf@pro2.fritz.box> ("Gerd Möllmann"'s message of "Wed, 24 Apr 2024 11:08:00 +0200")

[-- Attachment #1: Type: text/plain, Size: 375 bytes --]

On Wed, Apr 24 2024, Gerd Möllmann wrote:

> Makes sense to me, but I must say that I have 0 experience with that
> using MPS. It might require some experimentation how to about
> implementing such weak references, but that could be fun.

I implemented such weak references in the patch below.  Do I use the
IGC_OBJ_WEAK tag roughly how you intended it?

Helmut


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Experimental-weak-ref-objects.patch --]
[-- Type: text/x-diff, Size: 9677 bytes --]

From 4b0d85a06e6cec4a8c77f271e25cd87abaa52fdc Mon Sep 17 00:00:00 2001
From: Helmut Eller <eller.helmut@gmail.com>
Date: Wed, 24 Apr 2024 20:54:16 +0200
Subject: [PATCH] Experimental weak-ref objects

---
 src/data.c            |   5 +-
 src/igc.c             | 158 ++++++++++++++++++++++++++++++++++++++++--
 src/igc.h             |  16 +++++
 src/lisp.h            |   1 +
 src/pdumper.c         |   2 +
 src/print.c           |  10 +++
 test/src/igc-tests.el |  16 +++++
 7 files changed, 200 insertions(+), 8 deletions(-)
 create mode 100644 test/src/igc-tests.el

diff --git a/src/data.c b/src/data.c
index d52b73b8681..49b33727d75 100644
--- a/src/data.c
+++ b/src/data.c
@@ -296,7 +296,10 @@ DEFUN ("cl-type-of", Fcl_type_of, Scl_type_of, 1, 1, 0,
           return Qsqlite;
         case PVEC_SUB_CHAR_TABLE:
           return Qsub_char_table;
-        /* "Impossible" cases.  */
+	case PVEC_WEAK_REF:
+	  return Qweak_ref;
+
+	/* "Impossible" cases.  */
 	case PVEC_MISC_PTR:
         case PVEC_OTHER:
         case PVEC_FREE: ;
diff --git a/src/igc.c b/src/igc.c
index d0b3e8e3fa6..e64e0621c77 100644
--- a/src/igc.c
+++ b/src/igc.c
@@ -63,6 +63,12 @@
 # warning "HAVE_TEXT_CONVERSION not supported"
 #endif
 
+struct Lisp_Weak_Ref
+{
+  union vectorlike_header header;
+  Lisp_Object ref;
+} GCALIGNED_STRUCT;
+
 /* Note: Emacs will call allocation functions whlle aborting. This leads
    to all sorts of interesting phenomena when an assertion fails inside
    a function called from MPS.
@@ -1024,9 +1030,92 @@ fix_face_cache (mps_ss_t ss, struct face_cache *c)
 }
 
 static mps_res_t
-fix_weak (mps_ss_t ss, mps_addr_t base)
+fix_weak_ref (mps_ss_t ss, struct Lisp_Weak_Ref *wref)
+{
+  MPS_SCAN_BEGIN (ss)
+  {
+    const mps_word_t tagged_word = *(mps_word_t *)&wref->ref;
+    const enum Lisp_Type tag = tagged_word & IGC_TAG_MASK;
+
+    switch (tag)
+      {
+      case Lisp_Int0:
+      case Lisp_Int1:
+	return MPS_RES_OK;
+
+      case Lisp_Type_Unused0:
+	emacs_abort ();
+
+      case Lisp_Symbol:
+	{
+	  ptrdiff_t off = tagged_word ^ Lisp_Symbol;
+	  mps_addr_t client = (mps_addr_t)((char *)lispsym + off);
+	  if (is_mps (client))
+	    {
+	      mps_addr_t base = client_to_base (client);
+	      if (MPS_FIX1 (ss, base))
+		{
+		  mps_res_t res = MPS_FIX2 (ss, &base);
+		  if (res != MPS_RES_OK)
+		    return res;
+		  if (base == NULL)
+		    {
+		      wref->ref = Qnil;
+		    }
+		  else
+		    {
+		      client = base_to_client (base);
+		      ptrdiff_t new_off = (char *)client - (char *)lispsym;
+		      wref->ref = (Lisp_Object)(new_off | tag);
+		    }
+		}
+	    }
+	}
+	break;
+
+      default:
+	{
+	  const mps_addr_t client = (mps_addr_t)(tagged_word ^ tag);
+	  if (is_mps (client))
+	    {
+	      mps_addr_t base = client_to_base (client);
+	      if (MPS_FIX1 (ss, base))
+		{
+		  const mps_res_t res = MPS_FIX2 (ss, &base);
+		  if (res != MPS_RES_OK)
+		    return res;
+		  if (base == NULL)
+		    {
+		      wref->ref = Qnil;
+		    }
+		  else
+		    {
+		      const mps_addr_t client2 = base_to_client (base);
+		      wref->ref = (Lisp_Object)((mps_word_t)client2 | tag);
+		    }
+		}
+	    }
+	}
+      }
+  }
+  MPS_SCAN_END (ss);
+  return MPS_RES_OK;
+}
+
+static mps_res_t
+fix_weak (mps_ss_t ss, struct igc_header* base)
 {
-  MPS_SCAN_BEGIN (ss) { igc_assert (!"fix_weak"); }
+  MPS_SCAN_BEGIN (ss) {
+    const mps_addr_t client = base_to_client(base);
+    switch (base->pvec_type)
+      {
+      case PVEC_WEAK_REF:
+	IGC_FIX_CALL_FN (ss, struct Lisp_Weak_Ref, client, fix_weak_ref);
+	break;
+      default:
+	igc_assert (!"fix_weak");
+      }
+  }
   MPS_SCAN_END (ss);
   return MPS_RES_OK;
 }
@@ -1139,7 +1228,7 @@ dflt_scanx (mps_ss_t ss, mps_addr_t base_start, mps_addr_t base_limit,
 	    break;
 
 	  case IGC_OBJ_WEAK:
-	    IGC_FIX_CALL_FN (ss, mps_word_t, client, fix_weak);
+	    IGC_FIX_CALL_FN (ss, struct igc_header, base, fix_weak);
 	    break;
 	  }
       }
@@ -1633,6 +1722,9 @@ fix_vector (mps_ss_t ss, struct Lisp_Vector *v)
 #endif
 	IGC_FIX_CALL_FN (ss, struct Lisp_Vector, v, fix_vectorlike);
 	break;
+
+      case PVEC_WEAK_REF:
+	emacs_abort ();
       }
   }
   MPS_SCAN_END (ss);
@@ -2231,6 +2323,7 @@ finalize_vector (mps_addr_t v)
     case PVEC_XWIDGET_VIEW:
     case PVEC_TERMINAL:
     case PVEC_MARKER:
+    case PVEC_WEAK_REF:
       igc_assert (!"not implemented");
       break;
     }
@@ -2321,6 +2414,7 @@ maybe_finalize (mps_addr_t client, enum pvec_type tag)
 #ifdef IN_MY_FORK
     case PVEC_PACKAGE:
 #endif
+    case PVEC_WEAK_REF:
       break;
     }
 }
@@ -2387,9 +2481,11 @@ thread_ap (enum igc_obj_type type)
     case IGC_OBJ_PAD:
     case IGC_OBJ_FWD:
     case IGC_OBJ_LAST:
-    case IGC_OBJ_WEAK:
       emacs_abort ();
 
+    case IGC_OBJ_WEAK:
+      return t->d.weak_weak_ap;
+
     case IGC_OBJ_CONS:
     case IGC_OBJ_SYMBOL:
     case IGC_OBJ_INTERVAL:
@@ -2425,6 +2521,14 @@ igc_collect (void)
   mps_arena_release (gc->arena);
 }
 
+DEFUN ("igc--collect", Figc__collect, Sigc__collect, 0, 0, 0, doc
+       : /* */)
+(void)
+{
+  igc_collect ();
+  return Qnil;
+}
+
 static unsigned
 obj_hash (void)
 {
@@ -2665,11 +2769,46 @@ igc_make_face_cache (void)
   return c;
 }
 
-struct Lisp_Buffer_Local_Value *
-igc_alloc_blv (void)
+DEFUN ("igc-make-weak-ref", Figc_make_weak_ref, Sigc_make_weak_ref, 1, 1, 0,
+       doc
+       : /* todo */)
+(Lisp_Object target)
+{
+  const enum pvec_type type = PVEC_WEAK_REF;
+  struct Lisp_Weak_Ref *wref = alloc (sizeof *wref, IGC_OBJ_WEAK, type);
+  int nwords_lisp = VECSIZE(struct Lisp_Weak_Ref);
+  XSETPVECTYPESIZE (wref, type, nwords_lisp, 0);
+  maybe_finalize (wref, type);
+  wref->ref = target;
+  Lisp_Object obj = make_lisp_ptr (wref, Lisp_Vectorlike);
+  return obj;
+}
+
+static void
+CHECK_WEAK_REF_P (Lisp_Object x)
+{
+  CHECK_TYPE (WEAK_REF_P (x), Qweak_ref_p, x);
+}
+
+Lisp_Object
+igc_weak_ref_deref (struct Lisp_Weak_Ref *wref)
+{
+  return wref->ref;
+}
+
+DEFUN ("igc-weak-ref-deref", Figc_weak_reaf_deref, Sigc_weak_ref_deref, 1, 1,
+       0, doc
+       : /* todo */)
+(Lisp_Object obj)
+{
+  CHECK_WEAK_REF_P (obj);
+  return igc_weak_ref_deref (XWEAK_REF (obj));
+}
+
+struct Lisp_Buffer_Local_Value *igc_alloc_blv (void)
 {
   struct Lisp_Buffer_Local_Value *blv
-    = alloc (sizeof *blv, IGC_OBJ_BLV, PVEC_FREE);
+      = alloc (sizeof *blv, IGC_OBJ_BLV, PVEC_FREE);
   return blv;
 }
 
@@ -2871,7 +3010,12 @@ syms_of_igc (void)
 {
   defsubr (&Sigc_info);
   defsubr (&Sigc_roots);
+  defsubr (&Sigc_make_weak_ref);
+  defsubr (&Sigc_weak_ref_deref);
+  defsubr (&Sigc__collect);
   DEFSYM (Qambig, "ambig");
   DEFSYM (Qexact, "exact");
+  DEFSYM (Qweak_ref_p, "weak-ref-p");
+  DEFSYM (Qweak_ref, "weak-ref");
   Fprovide (intern_c_string ("mps"), Qnil);
 }
diff --git a/src/igc.h b/src/igc.h
index 0183b8da71f..e29e8f7cecc 100644
--- a/src/igc.h
+++ b/src/igc.h
@@ -93,6 +93,22 @@ #define EMACS_IGC_H
 void igc_root_create_exact (Lisp_Object *start, Lisp_Object *end);
 void igc_root_create_exact_ptr (void *var_addr);
 
+struct Lisp_Weak_Ref;
+Lisp_Object igc_weak_ref_deref (struct Lisp_Weak_Ref *);
+
+INLINE bool
+WEAK_REF_P (Lisp_Object x)
+{
+  return PSEUDOVECTORP (x, PVEC_WEAK_REF);
+}
+
+INLINE struct Lisp_Weak_Ref *
+XWEAK_REF (Lisp_Object a)
+{
+  eassert (WEAK_REF_P (a));
+  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Weak_Ref);
+}
+
 # define eassert_not_mps() eassert (false)
 #else
 # define igc_break() (void) 0
diff --git a/src/lisp.h b/src/lisp.h
index ce1516e9673..32b28921c44 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1047,6 +1047,7 @@ DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
   PVEC_TS_NODE,
   PVEC_TS_COMPILED_QUERY,
   PVEC_SQLITE,
+  PVEC_WEAK_REF,
 
   /* These should be last, for internal_equal and sxhash_obj.  */
   PVEC_COMPILED,
diff --git a/src/pdumper.c b/src/pdumper.c
index 8b179247db0..cca773a41bf 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -3170,6 +3170,8 @@ dump_vectorlike (struct dump_context *ctx,
     case PVEC_TS_NODE:
     case PVEC_TS_COMPILED_QUERY:
       break;
+    case PVEC_WEAK_REF:
+      emacs_abort();
     }
   char msg[60];
   snprintf (msg, sizeof msg, "pseudovector type %d", (int) ptype);
diff --git a/src/print.c b/src/print.c
index 81b6439fd7b..a2bd8ef0b19 100644
--- a/src/print.c
+++ b/src/print.c
@@ -33,6 +33,7 @@ Copyright (C) 1985-2024 Free Software Foundation, Inc.
 #include "blockinput.h"
 #include "xwidget.h"
 #include "dynlib.h"
+#include "igc.h"
 
 #include <c-ctype.h>
 #include <float.h>
@@ -2089,6 +2090,15 @@ print_vectorlike_unreadable (Lisp_Object obj, Lisp_Object printcharfun,
 	return;
       }
 
+    case PVEC_WEAK_REF:
+      {
+	Lisp_Object target = igc_weak_ref_deref (XWEAK_REF(obj));
+	print_c_string ("#<weak-ref ", printcharfun);
+	print_object (target, printcharfun, escapeflag);
+	print_c_string (">", printcharfun);
+	return;
+      }
+
     /* Types handled earlier.  */
     case PVEC_NORMAL_VECTOR:
     case PVEC_RECORD:
diff --git a/test/src/igc-tests.el b/test/src/igc-tests.el
new file mode 100644
index 00000000000..02caf6661f5
--- /dev/null
+++ b/test/src/igc-tests.el
@@ -0,0 +1,16 @@
+;;; igc-tests.el --- Tests for igc.c                -*- lexical-binding: t -*-
+
+(require 'ert)
+
+(defvar igc-test-v0 (igc-make-weak-ref (list 1 2)))
+(defvar igc-test-v1 (igc-make-weak-ref (make-symbol "foo")))
+
+(ert-deftest igc-test-weak-refs ()
+  (igc--collect)
+  (garbage-collect)
+  (should (equal (igc-weak-ref-deref igc-test-v0) nil))
+  (should (equal (igc-weak-ref-deref igc-test-v1) nil))
+  (let ((wref (igc-make-weak-ref (list 3 4))))
+    (should (equal (igc-weak-ref-deref wref) '(3 4)))))
+
+(provide 'igc-tests)
-- 
2.39.2


  reply	other threads:[~2024-04-24 19:03 UTC|newest]

Thread overview: 149+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-20  9:34 STatus of MPS branch Gerd Möllmann
2024-04-20 14:56 ` Michael Albinus
2024-04-20 15:08   ` Gerd Möllmann
2024-04-20 15:32     ` Michael Albinus
2024-04-20 17:37       ` Gerd Möllmann
2024-04-21  7:39         ` Michael Albinus
2024-04-21  7:56           ` Gerd Möllmann
2024-04-21  8:00             ` Gerd Möllmann
2024-04-21  8:04               ` Michael Albinus
2024-04-21  8:08                 ` Gerd Möllmann
2024-04-21  8:18                   ` Michael Albinus
2024-04-21  8:28                     ` Gerd Möllmann
2024-04-21  8:17           ` Gerd Möllmann
2024-04-21  9:43             ` Michael Albinus
2024-04-21 10:07               ` Gerd Möllmann
2024-04-21 10:58                 ` Tramp tests in MPS branch (was: STatus of MPS branch) Michael Albinus
2024-04-21 12:44                   ` Tramp tests in MPS branch Gerd Möllmann
2024-04-21  9:29           ` STatus of " Eli Zaretskii
2024-04-21  4:38 ` Gerd Möllmann
2024-04-21  5:31   ` Eli Zaretskii
2024-04-21  5:39     ` Gerd Möllmann
2024-04-21  9:04       ` Eli Zaretskii
2024-04-21  9:17         ` Gerd Möllmann
2024-04-21  6:15 ` Gerd Möllmann
2024-04-21  9:09   ` Eglot tests on MPS branch (was: STatus of MPS branch) Eli Zaretskii
2024-04-21  9:53     ` João Távora
2024-04-21 10:13       ` Eglot tests on MPS branch Gerd Möllmann
2024-04-21 11:01         ` João Távora
2024-04-21 10:55       ` Eglot tests on MPS branch (was: STatus of MPS branch) Eli Zaretskii
2024-04-21  7:49 ` STatus of MPS branch Gerd Möllmann
2024-04-21  8:45   ` Gerd Möllmann
2024-04-21  9:08     ` Andrea Corallo
2024-04-21  9:33     ` Native compilation on " Eli Zaretskii
2024-04-21 10:17       ` Gerd Möllmann
2024-04-21 13:07         ` Andrea Corallo
2024-04-22  7:15           ` Gerd Möllmann
2024-04-22 22:02             ` Andrea Corallo
2024-04-23  3:11               ` Gerd Möllmann
2024-04-23 16:09               ` Gerd Möllmann
2024-04-23 19:43                 ` Andrea Corallo
2024-04-24 12:49                   ` Gerd Möllmann
2024-04-24 18:14                     ` Andrea Corallo
2024-04-24 18:28                       ` Gerd Möllmann
2024-04-24 20:54                         ` Andrea Corallo
2024-04-25  4:33                           ` Gerd Möllmann
2024-04-25  5:50                             ` Andrea Corallo
2024-04-25  7:18                               ` Gerd Möllmann
2024-04-25  8:06                                 ` Andrea Corallo
2024-04-25  8:15                                   ` Gerd Möllmann
2024-04-25  8:57                                     ` Gerd Möllmann
2024-04-25  9:42                                     ` Andrea Corallo
2024-04-25 11:33                                       ` Gerd Möllmann
2024-04-25  5:24                           ` Eli Zaretskii
2024-04-25  5:48                             ` Andrea Corallo
2024-04-25 15:20                               ` Eli Zaretskii
2024-04-26 10:15                                 ` Gerd Möllmann
2024-04-21  8:58   ` STatus of " Andrea Corallo
2024-04-21  9:19     ` Gerd Möllmann
2024-04-21  9:30   ` Native compilation on MPS branch (was: STatus of MPS branch) Eli Zaretskii
2024-04-21 14:39 ` STatus of MPS branch Helmut Eller
2024-04-21 15:37   ` Gerd Möllmann
2024-04-21 15:52     ` Eli Zaretskii
2024-04-21 20:24     ` Helmut Eller
2024-04-22  4:58       ` Gerd Möllmann
2024-04-22  5:28       ` Gerd Möllmann
2024-04-22  6:15         ` MPS signals and Emacs (was: STatus of MPS branch) Eli Zaretskii
2024-04-22  6:44           ` MPS signals and Emacs Paul Eggert
2024-04-22  7:19             ` Gerd Möllmann
2024-04-22  7:40               ` Paul Eggert
2024-04-22  7:49                 ` Gerd Möllmann
2024-04-22  8:09                   ` Eli Zaretskii
2024-04-22  8:27                     ` Gerd Möllmann
2024-04-22  8:55                       ` Eli Zaretskii
2024-04-22  9:02                         ` Mattias Engdegård
2024-04-22  9:02                         ` Gerd Möllmann
2024-04-22  9:18                           ` Eli Zaretskii
2024-04-22  9:29                             ` Gerd Möllmann
2024-04-22  9:41                               ` Eli Zaretskii
2024-04-22 10:22                                 ` Gerd Möllmann
2024-04-22 10:46                                   ` Eli Zaretskii
2024-04-22 11:00                                     ` Gerd Möllmann
2024-04-22 12:01                                       ` Eli Zaretskii
2024-04-22 12:16                                         ` Gerd Möllmann
2024-04-22 10:54                                   ` Eli Zaretskii
2024-04-22 11:05                                     ` Gerd Möllmann
2024-04-22 19:41                   ` Paul Eggert
2024-04-22 20:55                     ` Gerd Möllmann
2024-04-22 22:12                       ` Paul Eggert
2024-04-23  3:15                         ` Gerd Möllmann
     [not found]                       ` <87le54g1h2.fsf@dick>
2024-04-23  5:51                         ` Gerd Möllmann
2024-04-23  6:35                           ` Helmut Eller
2024-04-23  6:45                             ` Gerd Möllmann
2024-04-23  6:53                               ` Helmut Eller
2024-04-23 14:29                                 ` Gerd Möllmann
     [not found]                                   ` <87sezbsmsd.fsf@dick>
2024-04-24  5:03                                     ` Gerd Möllmann
2024-04-22  7:46               ` Eli Zaretskii
2024-04-22  7:55                 ` Gerd Möllmann
2024-04-22 14:10             ` Helmut Eller
2024-04-22 14:42               ` Eli Zaretskii
2024-04-22 22:06                 ` Paul Eggert
2024-04-23  7:04                   ` Eli Zaretskii
2024-04-22  5:36       ` STatus of MPS branch Gerd Möllmann
2024-04-22  5:50         ` Gerd Möllmann
2024-04-22 15:09           ` Helmut Eller
2024-04-22 17:02             ` Gerd Möllmann
2024-04-24  7:26 ` Collecting markers with MPS (was: STatus of MPS branch) Helmut Eller
2024-04-24  7:44   ` Eli Zaretskii
2024-04-24  8:56     ` Collecting markers with MPS Helmut Eller
2024-04-24  9:17       ` Gerd Möllmann
2024-04-24 10:22       ` Eli Zaretskii
2024-04-24 10:27         ` Gerd Möllmann
2024-04-24 10:58           ` Gerd Möllmann
2024-04-24 13:32             ` Eli Zaretskii
2024-04-24 13:51               ` Gerd Möllmann
2024-04-24 15:03         ` Helmut Eller
2024-04-24 15:54           ` Eli Zaretskii
2024-04-24 16:21             ` Helmut Eller
2024-04-24 16:26               ` Eli Zaretskii
2024-04-24 16:50                 ` Gerd Möllmann
2024-04-24 19:18                 ` Helmut Eller
2024-04-24 19:55                   ` Gerd Möllmann
2024-04-25  7:38                   ` Mattias Engdegård
2024-04-24  9:08     ` Gerd Möllmann
2024-04-24 19:03       ` Helmut Eller [this message]
2024-04-24 20:02         ` Gerd Möllmann
2024-04-24 20:13           ` Helmut Eller
2024-04-24 20:42             ` Gerd Möllmann
2024-04-25  9:44       ` Helmut Eller
2024-04-25 11:44         ` Gerd Möllmann
2024-04-25 16:04 ` basic questions on MPS Andrea Corallo
2024-04-25 17:51   ` Helmut Eller
2024-04-25 18:48     ` Eli Zaretskii
2024-04-25 18:53     ` Gerd Möllmann
2024-04-25 19:26     ` Vibhav Pant
2024-04-26  6:36       ` Helmut Eller
2024-04-26  7:25         ` Gerd Möllmann
2024-04-26 15:07         ` vibhavp
2024-04-26  6:42       ` Gerd Möllmann
2024-04-27  0:20     ` Richard Stallman
2024-04-27  8:41       ` Helmut Eller
2024-04-28 22:44         ` Richard Stallman
2024-04-29  4:27           ` Helmut Eller
2024-04-29 22:40             ` Richard Stallman
2024-04-25 18:41   ` Eli Zaretskii
2024-04-25 18:53     ` Andrea Corallo
2024-04-25 18:56       ` Gerd Möllmann
2024-04-25 19:29         ` Andrea Corallo
2024-04-25 19:03       ` Eli Zaretskii
2024-04-25 19:09         ` Andrea Corallo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87edauinwn.fsf@gmail.com \
    --to=eller.helmut@gmail.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=gerd.moellmann@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).